ThumbnailCtrl is more of a image browser demo application than a widget,
in that it reads files from a directory, selects which files to display,
deletes files, displays the source directory path in a text ctrl, etc.
This makes it unlikely that it could be used in any other application,
for example, to provide thumbnails of files with different file types
than the ones hard-coded in the class.
ThumbnailCtrl delegates most of its operations to ScrolledThumbnail
which actually implements a scrolled window of thumbnails, a Thumb class,
which contains information about a thumbnail, and an ImageHandler class,
which manipulates images. There was poor isolation of functionality
between these classes, violating object-oriented design, with one class
making changes to the internal data of another class. Additionally, there
was substantial non-functional code, as well as code which did not
function correctly.
This refactoring maintains the functionality and interfaces of
ThumbnailCtrl, except for those which were unused. Existing uses of
the thumbnailctrl package should work without modification. A new package,
scrolledthumbnail, contains the functionality for a scrolled window
containing thumbnails, an extendable Thumb class, and image manipulation
classes. The scrolledthumbnail package can be used in other applications,
independent of the ThumbnailCtrl class, and without the functional
restrictions of that application.
Detailed changes:
ThumbnailCtrl.py (demo program):
- Always import from wx.lib.agw
- Optional code to use PIL instead of native image handling
- Add setting for thumbnail width and height
- Increase size of demo window
thumbnailctrl.py:
- Move Thumb, ScrolledThumbnail, ImageHandler to scrolledthumbnail.py
- Remove EVT_THUMBNAILS_CAPTION_CHANGED (unused)
- Add EVT_THUMBNAILS_CHAR to respond to keystrokes
- Remove image processing code
- Add scrolling dialog for delete files
- Move directory processing from ScrolledThumbnail
- Move file delete processing from ScrolledThumbnail
- List all files to be deleted in scrolling dialog
- Remove unused or unimplemented methods and options
scrolledthumbnail.py:
- Move Thumb, ScrolledThumbnail, ImageHander classes from thumbnailctrl.py
- Add documentation for ScrolledThumbnail widget
- Add example program which does not use ThumbnailCtrl
- New EVT_THUMBNAILS_CHAR event for key press
- Remove unused options and dead code
- Add Rotate() to PILImageHandler and NativeImageHandler
- Throw event EVT_THUMBNAILS_CHAR for keystroke on thumbnail
- Fix failure to rotate images correctly
- Redisplay window when thumb size changed
- Simplify logic
- Remove popup dialog when rotating images
Specyfing a horizontal alignment in a wxHORIZONTAL layed out BoxSizer
is pointless, and doing so throws an exception:
wx._core.wxAssertionError: C++ assertion "!(flags & wxALIGN_RIGHT)"
failed at ./src/common/sizer.cpp(2133) in DoInsert():
Horizontal alignment flags are ignored in horizontal sizers
Without the change, SetColumnWidth(**col**, LIST_AUTOSIZE_CONTENT_OR_HEADER) would throw this:
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/wx/lib/agw/hypertreelist.py", line 4645, in SetColumnWidth
width2, dummy, dummy = dc.GetMultiLineTextExtent(self._header_win.GetColumnText(column))
ValueError: not enough values to unpack (expected 3, got 2)
I ended up using the function called when LIST_AUTOSIZE_CONTENT_OR_HEADER, but reducing the number of **dummy** variables. To be consistent, I did the same for LIST_AUTOSIZE_USEHEADER.
- defined more properties for wx.lib.intctrl.IntCtrl: Limited, LongAllowed, Min, Max, NoneAllowed;
- defined more properties for wx.lib.agw.floatspin.FloatSpin: DefaultValue, Digits, Font, Format, Increment, Min, Max;
- added SetMin-SetMax to wx.lib.agw.floatspin.FloatSpin.
Hint window border color can be set now with AUI_DOCKART_HINT_WINDOW_BORDER_COLOUR
Optimizations:
Optimized venetian blind loop and removed unnecessary wxPoint to tuple in Paint method wx.Rect