Proper structure for complicated layout

Hi all,

I’m back in the saddle on a back-burner project, and item 1 is refactoring a 450-line object that does too much.

I want a window - Panel, probably - that is structured (well, can’t get preformatted to format correctly, so image a smaller vertical widget panel on the right and a larger image panel on the left)


---------------------------------------------------------
|   Bitmap  800x600               |  Buttons      |
|   that can be drawn upon           |  and             |
|                                                     |  Dropdowns |
---------------------------------------------------------

This was all one panel in the original code. I think it should be two separate Panels, both inside a Panel? And, I am unsure as to whether the drawing methods for the bitmap should belong to the Panel that owns the bitmap OR to the bitmap itself.

In other words, is the best approach

Option 1:

class MyStaticBitmap(wx.StaticBitmap):
   # drawing methods go here

class MyImagePanel(wx.Panel):
  
  def __init__(self):
      image = MyStaticBitmap(self, image_from_file)

  #respond to mouse events by calling MyStaticBitmap methods

OR

Option 2:

class MyImagePanel(wx.Panel):
  def __init__(self):
    image = wx.StaticBitmap(self,image_from_file)

  # drawing methods go here
  # mouse events call drawing methods

All advice appreciated.

Both will work.

When I’ve gone with option 1, I’ve often regretted it, because I would end up with half the business logic in MyImagePanel and the other half in MyStaticBitmap, and it would be pretty arbitrary what goes where. Better to have the business logic concentrated in one class. So that’s an argument for option 2.

However: If you have a clear concept for how responsibilities are divided between MyImagePanel and MyStaticBitmap, then option 1 may work well. For example, you may decide that the code in MyStaticBitmap handles drawing and only drawing.

If you do go with option 1, then avoid defining event handlers in MyStaticBitmap. Instead, do self.image.Bind(wx.EVT_FOO, self.OnFoo) in the panel. Because then your OnFoo event handler will have an easier time cooperating with the rest of your business logic in the panel. When the event handler then needs to do something with the bitmap, have it call methods in MyStaticBitmap to handle the low-level bitmap stuff, so that you don’t end up with low-level bitmap code in the panel, either.

1 Like

Another point to consider is the potential for the reuse of the ‘MyStaticBitmap’ class in other applications. The probability that it can also be used elsewhere would be increased if you limit that class to drawing functionality and keep the application specific code in the panel.

1 Like