diff options
Diffstat (limited to 'scripts/newbitmaps/lib')
-rw-r--r-- | scripts/newbitmaps/lib/__init__.py | 6 | ||||
-rwxr-xr-x | scripts/newbitmaps/lib/bmpblock.py | 104 | ||||
-rwxr-xr-x | scripts/newbitmaps/lib/pixcontrol.py | 102 | ||||
-rwxr-xr-x | scripts/newbitmaps/lib/pixdisplay.py | 62 |
4 files changed, 274 insertions, 0 deletions
diff --git a/scripts/newbitmaps/lib/__init__.py b/scripts/newbitmaps/lib/__init__.py new file mode 100644 index 00000000..8fa877aa --- /dev/null +++ b/scripts/newbitmaps/lib/__init__.py @@ -0,0 +1,6 @@ +# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import bmpblock +import pixcontrol +import pixdisplay diff --git a/scripts/newbitmaps/lib/bmpblock.py b/scripts/newbitmaps/lib/bmpblock.py new file mode 100755 index 00000000..eacf72fa --- /dev/null +++ b/scripts/newbitmaps/lib/bmpblock.py @@ -0,0 +1,104 @@ +#!/usr/bin/python -tt +# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""A BmpBlock class""" + +import os +import types +import yaml + +class BmpBlock(object): + """A wrapper for the config.yaml file. + It has a few special attributes to specify which part we're focusing on. + """ + + def __init__(self, filename=None): + self.yaml = None + self.filename = None + self.current_screen = None + self.filename = filename # always set, so we can reload + if filename: + self.LoadFile(filename) + + def LoadFile(self, filename): + """Load the specified yaml file and verify that it's a valid BmpBlock""" + print "Loading", filename + with open(filename, 'rb') as f: + stuff = yaml.safe_load(f) + # FIXME: This is pretty lame. We should be able to find images using a + # default directory path instead of using chdir. + if os.path.dirname(filename): + os.chdir(os.path.dirname(filename)) + if self.IsValidSyntax(stuff): + self.yaml = stuff + self.current_screen = sorted(self.yaml["screens"].keys())[0] + + def Reload(self): + tmp = self.current_screen + self.LoadFile(self.filename) + if tmp in self.yaml["screens"]: + self.current_screen = tmp + + def IsValidSyntax(self, thing): + """Raise an error if the specified dict is not a valid BmpBlock structure""" + + assert isinstance(thing, dict) + assert thing["bmpblock"] == 1.0 + + seen_images = {} + seen_screens = {} + + images = thing["images"] + assert isinstance(images, dict) + assert len(images) > 0 + # image values should all be filenames (ie, strings) + for val in images.values(): + assert val and isinstance(val, types.StringTypes) + + screens = thing["screens"] + assert isinstance(screens, dict) + assert screens + # screen values should all be lists of 3-tuples + for scrname, imglist in screens.items(): + assert len(imglist) <= 8 + for img in imglist: + assert 3 == len(img) + # must have defined all referenced bitmaps + x,y,i = img + assert i in images + seen_images[i] = True + + localizations = thing["localizations"] + assert hasattr(localizations, '__iter__') + assert localizations + # localizations should all be lists with the same number of screens + len0 = len(localizations[0]) + assert len0 + for elt in localizations: + assert len0 == len(elt) + # we must have defined all referenced screens + for scr in elt: + assert scr in screens + seen_screens[scr] = True + + for unused_img in [x for x in images if x not in seen_images]: + print " Unused image:", unused_img + for unused_scr in [x for x in screens if x not in seen_screens]: + print " Unused screen:", unused_scr + + return True + + def RegisterScreenDisplayObject(self, displayer): + """Register an object with a .Redisplay() function to display updates.""" + self.displayer = displayer + + + def Redisplay(self): + """Redisplay contents.""" + if self.displayer: + if self.current_screen: + sc = self.yaml['screens'][self.current_screen] + slist = [(x,y,self.yaml['images'][z]) for x,y,z in sc] + self.displayer.DisplayScreen(self.current_screen, slist) diff --git a/scripts/newbitmaps/lib/pixcontrol.py b/scripts/newbitmaps/lib/pixcontrol.py new file mode 100755 index 00000000..1f46558e --- /dev/null +++ b/scripts/newbitmaps/lib/pixcontrol.py @@ -0,0 +1,102 @@ +#!/usr/bin/python -tt +# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Edit buttons for bmpblock object""" + +import wx + +class Frame(wx.Frame): + + def __init__(self, bmpblock=None, title=None): + wx.Frame.__init__(self, None, wx.ID_ANY, title, size=(200,400)) + menuFile = wx.Menu() + m_about = menuFile.Append(wx.ID_ANY, "About...\tCtrl+A") + menuFile.AppendSeparator() + m_reload = menuFile.Append(wx.ID_ANY, "Reload\tCtrl+R") + m_quit = menuFile.Append(wx.ID_ANY, "Quit\tCtrl+Q") + menuBar = wx.MenuBar() + menuBar.Append(menuFile, "&File") + self.SetMenuBar(menuBar) + self.CreateStatusBar() + self.Bind(wx.EVT_MENU, self.OnAbout, m_about) + self.Bind(wx.EVT_MENU, self.OnReload, m_reload) + self.Bind(wx.EVT_MENU, self.OnQuit, m_quit) + self.Bind(wx.EVT_CLOSE, self.OnQuit) + + acctbl = wx.AcceleratorTable([ + (wx.ACCEL_CTRL, ord('A'), m_about.GetId()), + (wx.ACCEL_CTRL, ord('R'), m_reload.GetId()), + (wx.ACCEL_CTRL, ord('Q'), m_quit.GetId()) + ]) + + self.SetAcceleratorTable(acctbl) + + # create UI components + panel = wx.Panel(self) + button_reload = wx.Button(panel, label="Reload File") + self.screenlist = wx.ListBox(panel, wx.ID_ANY) + + # connect events + self.Bind(wx.EVT_BUTTON, self.OnReload, button_reload) + self.Bind(wx.EVT_LISTBOX, self.OnSelected, self.screenlist) + self.Bind(wx.EVT_IDLE, self.OnIdle) + + # place the componenents + sizer = wx.BoxSizer(wx.VERTICAL) + sizer.Add(button_reload) + sizer.Add(wx.StaticText(panel, wx.ID_ANY, "Screens")) + sizer.Add(self.screenlist, 1, wx.EXPAND) + + panel.SetSizer(sizer) + panel.Fit() + + # now, what are we looking at? + self.bmpblock = bmpblock + self.UpdateControls() + self.do_update = True + self.screenlist.SetFocus() + + def OnAbout(self, event): + """Display basic information about this application.""" + msg = ("Yes, all this does right now is display the screens from the config" + " file. You still have to edit, save, and reload in order to see any" + " changes. Learning python and wxpython is my 20% project (actually" + " it's more like 5%). Feel free to improve things.\n\t-- bill") + wx.MessageBox(msg, "About", wx.OK | wx.ICON_INFORMATION, self) + + def OnQuit(self, event): + """Close all application windows and quit.""" + wx.GetApp().ExitMainLoop() + + def OnReload(self, event): + """Tell the model object to refresh the view that the user sees. + FIXME: The model itself should know to do this without being told. + """ + self.bmpblock.Reload() + self.do_update = True; + self.UpdateControls() + + def OnSelected(self, event): + """User may have picked one of the pulldowns.""" + if event.IsSelection(): + self.bmpblock.current_screen = event.GetString() + self.do_update = True + event.Skip() + + def UpdateControls(self): + """Reload all the buttons with the current model information.""" + screens = self.bmpblock.yaml["screens"] + self.screenlist.Clear() + self.screenlist.AppendItems(sorted(screens.keys())) + current = self.bmpblock.current_screen + self.screenlist.SetStringSelection(current) + self.SetStatusText(self.bmpblock.filename) + + def OnIdle(self, event=None): + """What to do, what to do...""" + if self.do_update: + # FIXME: The model should know when to do this itself, right? + self.bmpblock.Redisplay() + self.do_update = False diff --git a/scripts/newbitmaps/lib/pixdisplay.py b/scripts/newbitmaps/lib/pixdisplay.py new file mode 100755 index 00000000..0d40580b --- /dev/null +++ b/scripts/newbitmaps/lib/pixdisplay.py @@ -0,0 +1,62 @@ +#!/usr/bin/python -tt +# Copyright (c) 2011 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Display for bmpblock object.""" +import wx + +class MyPanel(wx.Panel): + + def __init__(self, parent): + wx.Panel.__init__(self, parent, wx.ID_ANY) + self.Bind(wx.EVT_PAINT, self.OnPaint) + self.parent = parent + self.imglist = () + + def OnPaint(self, evt=None): + if (evt): + dc = wx.PaintDC(self) + else: + dc = wx.ClientDC(self) + + done_first = False + # The first image in the sequence may be used by the BIOS to set the + # display resolution. Regardless, it should match the desired or default + # resolution so that any previous screens get cleared. + for x, y, filename in self.imglist: + img = wx.Image(filename, wx.BITMAP_TYPE_ANY) + if (not done_first): + size = img.GetSize() + self.SetMinSize(size) + self.SetSize(size) + self.Fit() + w,h = self.parent.GetBestSize() + self.parent.SetDimensions(-1, -1, w, h, wx.SIZE_AUTO) + done_first = True + bmp = img.ConvertToBitmap() + dc.DrawBitmap(bmp, x, y) + + +class Frame(wx.Frame): + + def __init__(self, bmpblock=None, title=None): + wx.Frame.__init__(self, None, wx.ID_ANY, title=title) + self.CreateStatusBar() + self.SetStatusText(title) + self.Bind(wx.EVT_CLOSE, self.OnQuit) + + self.bmpblock = bmpblock + if self.bmpblock: + self.bmpblock.RegisterScreenDisplayObject(self) + + self.p = MyPanel(self) + + + def OnQuit(self, event): + wx.GetApp().ExitMainLoop() + + def DisplayScreen(self, name, imglist): + self.SetStatusText(name) + self.p.imglist = imglist + self.p.OnPaint() |