r65 - 16 Jun 2006 - 16:21:56 - DavidSurovellYou are here: OSAF >  Projects Web  >  DevelopmentHome > WxPythonProject > WxListHeaderWork

wxListHeader Development:

Subproject Kiosk

Draft 1.7

David Surovell

Chandler GUI Frameworks Engineer, OSA Foundation

16 June 2006







Status

  • 16 June 2006
    • working on alpha3 acceptance
    • waiting for John Anderson to commit changes to fix many (but not all) item resize issues
      • resize via grid line drag doesn't work
    • planning to rename wxColumnHeader class to wxListHeader
  • 15 May 2006
    • ready for alpha2 acceptance
    • patched once during May Sprint Week:
      • reviewed by John and Robin
    • active patch in Bugzilla, reviewed once by John, may need second mini-review
    • FIXED bugs:
      • resize mouse handling is ugly
      • item size maintenance is poor
      • labels missing on initial render
    • still broken:
      • wxGTK: black bar appears above list header
      • wxMSW: gap between bottom of list header and grid cells
      • wxMSW: wxGrid bimaps rendered poorly
      • wxMSW: static implementation of FindLabelHeight is broken



  • 02 May 2006
    • ready for alpha2 code complete and test!
    • what's working:
      • tested for Mac, Windows; GTK status unknown
      • item rendering (after resize or clicking on list item)
        • selection highlighting
        • sort direction arrows
      • mouse click support:
        • single item selection
        • double-click support
        • (partial) divider-drag item resize
    • what's broken:
      • needed for Chandler
        • resize mouse handling is ugly:
          • wxCH click handler interferes with wxGrid click handler
          • list header width is often mismatched to cell content
          • doesn't resize headers until the next header click
        • item size maintenance is poor:
          • list header item sizes are often mismatched to cell content
        • labels missing on initial render
        • wxMSW: gap between bottom of list header and grid cells
    • nice to have for general wx support
      • rename class to wxChandlerListHeader
      • initial item sizing for vertically-oriented windows
      • multi-item selection
      • coordinated selection
        • row select leads to column deselect, and vice versa
      • non-standard item heights
        • without native rendering


Feature Highlights

  • v2.0:
    • all alignments, extents and origins are wxSize for full 2D math
    • add and delete multiple header items
    • scrolled view (display subset of items)
    • show/hide individual items
    • default labeling support
    • partial multi-item selection support
    • improved resizing
    • fixes for 2-3 unreported bugs
    • namespace agrees with standard wx and wxGrid nomenclature



  • v1.0:
    • rendering:
      • theme-compliant background
      • text, with justification and ellipses truncation
      • small bitmaps, with justification (optional)
      • sort direction arrows (optional)
    • button arrows (arrows in bitmap locations) (optional)
      • (limited) custom selection appearance (optional)
    • supports hit testing, resizing (several modes)
    • supports Unicode and ANSI builds


Acceptance and Verification

  • QA acceptance goals
    • Chandler:
      • "All" summary view function near same or better; renders natively when possible
      • Calendar list headers unchanged
    • wxPythonDemo:
      • ColumnHeader.py
      • GridSimple.py (from "grid - simple" demo)


Source Code Manifest

  • v2.0:
    • colheader.[cpp,h,i] - tested co-compliant with existing CalendarCanvas colheader
    • demo code - wxPython/demo/colheader.py
    • src/generic/grid.cpp - (14 atomic diffs from wxChandler trunk svn 10558)
      • 6 small blocks, 3 medium blocks
      • all code controlled by #if brackets



  • v1.0:
    • wxPython / wxWidgets versions are checked in under "internal/wx/"
      • class name: wxColumnHeader; filename: colheader
    • wxColumnHeader widget integrated into Chandler Calendar view
      • thanks to Alec Flett
    • wxPythonDemo addition demonstrates desired class functionality
      • please run the wxPythonDemo to see this widget in action!




Near-term Tasks

  1. fix bugs / implementation shortcomings (see below)
  2. fix best practices shortcomings
    • C++ justification flag values could/should use existing wx constants
    • list item management code should be converted to "list" (variable array) template variable
      • not allowed in wxWidget internal implementations
  3. switch over to HITheme APIs and HIThemeHeaderDrawInfo
    • unfortunately, Apple won't document the HITheme APIs - how lame!
    • I don't think this has been true since 10.3 came out -- ReidEllis - 23 Feb 2006
  4. wish list
    • expose support for label text measurement
    • per-item-assignable label insets
      • e.g., MacOS X Finder
    • support for item divider click and drag resizing
    • in-place text editing for cell data
    • supporting owner-drawn items
      • not needed for Chandler, but necessary for wxPython/wxWidget acceptance
      • how to mix-in with wxOwnerDrawn class (ownerdrw.h)
      • can wxListBoxItem be used as a (figurative) template?
  5. wxWidget submittance
    • respond to RDunn email from 13-April-05
    • what else to do?
  6. miscellaneous
    • MacOS: is there a better way to call DrawThemeButton( ... kThemeListHeaderButton ... ) w/o drawing sort arrows?
      • current implementation uses clipping hack to achieve this...
    • check out other open source implementations for implementation comparisons:
      • most MacOS X 2-D data UIs are DataBrowser-based: Finder, Thunderbird, Xcode, etc.


Known Issues

  1. wxGTK: black bar appears above list header
  2. wxMSW: gap between bottom of list header and grid cells
  3. wxMSW: wxGrid bimaps rendered poorly
  4. wxMSW: static implementation of FindLabelHeight is broken



  5. vertical orientation support is partial and buggy:
    • to reproduce problems, use:
      • wxWidgets grid sample
      • wxPythonDemo GridSimple
  6. fixed item height code is bloated and hacked
  7. doesn't track mouse-down or mouse-over events
    • although it does handle mouse-up events
  8. doesn't show depressed state on mousedown events
  9. not (de-)activated on application switch
  10. MacOS: implement CoreGraphics version using HIDrawThemeButton

  • Fixed
  1. MSW, generic: no selection UI
    • no native canonical expression or API hooks to speak of
    • styles under consideration:
      • implemented: frame border, under/over-line
      • not yet implemented: invertedBevel, grayOut, boldLabel, colourLabel, bullet
  2. MSW, generic: oversized wxBitmaps scale improperly
  3. "font-blindness": convert font refs to wxFont


Questions recently answered

  1. many platform-specific routines are in pairs (and with GTK, triples)
    • most of them can be (have been) collapsed into a single routine
  2. is an HIView-based implementation allowable in wxMac (Carbon) ?
    • No: HIView-based code has gone away in wxWidgets version


General Notes

The functional architecture is:

  • wxChandlerGridLabelWindow - public parent class:
    • lightweight adapter
    • shim between wxGrid - wxGrid[Row,Col]LabelWindow and wxColumnHeader
    • used in Chandler Summary View
  • wxColumnHeader - public parent class:
    • relatively platform-neutral
    • used in Chandler CalendarCanvas
  • wxColumnHeaderItem - private, platform-specific class:
    • performs most drawing and platform-specific UI management

A wxColumnHeader object is created from a array of item records. The object instantiates a list of Item objects from the input array and manages them as a typical dynamic array via indexed access: e.g., Insert, Delete, GetData, SetData, etc.

The demo / test routines have been written with the intent of serving as a rough template / starting point (Python or C++) for writing code that uses these classes. The MacOSX demo was derived from the Apple DTS sample code download "HICustomPushButton", version-current as of this date.

Platform Notes:

The wxControl has 2 platform-specific targets (MSW (Win32) and MacOS) and a platform-neutral generic implementation.

The MSW implementation is essentially a wrapper to the native Win32 common control. The Windows Explorer "Details" folder view uses the native control.

The MacOS implementation relies on Appearance Manager routines for rendering. There is no MacOS-native column header control, although the native DataBrowser widget (which uses nearly the same drawing techniques) can be observed in many UI contexts within MacOS X.

The generic implementation relies on wxNativeRenderer for generic rendering of the column header background "button". The generic appearance is also available within the Mac and MSW builds.


wxGrid Integration Notes

  • architectural design and integration is complete
    • no changes to wxGrid public APIs
  • private wxGrid class hierarchy rework completed:
    • wxGridCornerLabelWindow gets a minor wxRenderer update
      • not needed for Chandler
    • existing wxGrid label classes become subclasses of wxChandlerGridLabelWindow
      • wxGrid[Row,Col]LabelWindow
    • wxChandlerGridLabelWindow is a subclass of wxColumnHeader
    • wxColumnHeader is still used "as is" by Chandler CalendarCanvas
  • all new code paths controlled by #if brackets
    • using switch(es) preserves the current behavior
  • integration controlled by 2 one-line compile switches:
    • switching wxChandlerGridLabelWindow base class to wxColumnHeader from wxWindow
    • include/wx/generic/colheader.h, src/generic/grid.cpp





ColumnHeader API Manifest

NB: "( ... )" means "lots of arguments"

  • wxColumnHeader
    • creation, destruction
      • Create( ... )
      • Destroy()



    • manipulation
      • DeleteItem( itemIndex )
      • ResizeToFit()
      • RescaleToFit( sizeX )
      • ResizeDivision( itemIndex, originX )
      • SetSize( x, y, height, width, flags )
      • GetBestSize()
      • CalculateDefaultSize()
      • GetTotalUIExtent()
      • HitTest( wxPoint )
      • Draw(), Enable(), Show(), etc.



    • attributes
      • Get/Set-Enabled( bFlagValue )
      • Get/Set-SelectionColour( wxColour )
      • Get/Set-SelectionDrawStyle( styleEnum )
        • enums: underline, overline, frame, invertedBevel, grayOut, boldLabel, colourLabel, bullet
      • Get/Set-Attribute( attributeEnum, bFlagValue )
        • enums: useUnicode, genericRenderer, visibleSelection, multipleSelection, proportionalResizing



    • item management
      • AddItem( beforeIndex, text, justEnum, width, bSelected, bSortDirection )
      • AppendItem( text, justEnum, width, bSelected, bSortDirection )
        • for creating column header items and assigning attribute values



      • AddEmptyItems( beforeIndex, count )
      • SetItemCount( beforeIndex, count )
        • for resizing a list view
      • Get/Set-SelectedItem( itemIndex )
      • Get/Set-LabelText( itemIndex, string )
      • Get/Set-LabelAlignment( itemIndex, alignmentEnum )
      • Get/Set-Bitmap( itemIndex, wxBitmap, wxRect )
      • Get/Set-BitmapAlignment( itemIndex, alignmentEnum )
      • Get/Set-ButtonArrowStyle( itemIndex, styleEnum )
      • Get/Set-UIOrigin( itemIndex, amountXY )
      • Get/Set-UIExtent( itemIndex, amountXY )
      • Get/Set-ItemAttribute( itemIndex, itemAttributeEnum, bFlagValue )
        • enums: select, sortEnable, sortDirection, fixedWidth



Code Review Notes

  • v2.0 Notes (01 May 06)
    • review code and plan for near-term completion:
      • analysis of "grid.cpp" changes
      • management of "grid.cpp" changes
      • code review of "colheader" files and planned changes



    • symbols to look for:
      1. "__GRID_LABELS_ARE_COLHEADERS__"

        This symbol is #defined in "include/wx/generic/colheader.h". This is the internal compilation flag to emable the wxGrid support within the wxColumnHeader class.
      2. "__USE_CHANDLER_LIST_HEADERS__"

        This symbol is #defined at the top of "grid.cpp". All of the important changes are within #if brackets with this symbol value #defined. Most if not all of these blocks are critical for this feature to work.
      3. "__USE_NATIVE_LIST_HEADERS__"

        (no longer included for code review) This symbol is not currently #defined. Code in "grid.cpp" under #if control is a test of the wxRendererNative::Get().DrawHeaderButton( ... ) code made to execute for all platforms. Needless to say, the results were suboptimal. wink All of the code in OnPaint routines under this control can be ignored.



    • debugging tips:
      • in "colheader.cpp" at line 202 you'll find:

        #if 0 && defined(WXDEBUG) && WXDEBUG

        Change this to a "#if 1" and, if you're built a debug target and you click on a column header, the clicked columnheader contents will be dumped to stdout.



  • v1.0 Notes (10 Jan 05)

First off: Thank you for agreeing to review this small batch of code. Your time and effort is much appreciated.



The intent of this code review is to determine the validity of my current design and its conformace to wxWidgets and wxPython Best Practices. Additionally, the current design meets the needs of Chandler client code (calendars, summary views, etc.), but I believe that these requirements are clear and simple, and are documented elsewheres.




Things to look for and/or consider

This implementation is targeted for adoption by Chandler and the greater wx community via wxWidgets and wxPython.

  1. determine architectural variance from wxWidgets Best Practices
    • move all rendering code to wxRenderer
    • splitting single ".cpp" into separate files
    • others?
  2. is the wxPython demo code sufficient?
  3. related info
    • check the "Near-term Tasks" section above for more potential issues
    • consult this wiki page for more background info:



Code Review - Standalone Demo Files Manifest

The files included are in 4 groups: wxWidgets/wxPython version; MacOSX native demo; Win32 native demo; native control classes; docs. The files are as follows:

  • colheader.[cpp, h, i], colheader-generic.h - wxPython implementation (wxColumnHeader)
  • ColumnHeader.py - wxPythonDemo addition

  • WxCodeReviewNotes.txt - this document in plain-text format
  • HICustomDemoApp.cpp - MacOSX test main()
  • Win32ListHeaderDemo.cpp - Win32 test main()
  • BaseListHeader.[cpp, h] - platform-neutral base classes
  • MacListHeader.[cpp, h] - MacOSX Carbon implementation subclasses
  • WinListHeader.[cpp, h] - Win32 implementation subclasses


Excluded Files (from review)

  • HICustomListHeader.xcode - Xcode v1.5 IDE project file
  • Win32ListHeaderDemo.[sln,vcproj] - MSVC v7.x IDE project files
  • Win32ListHeaderDemo.[rc,exe.manifest] - Win32 demo resources
  • HICustomPushButton-orig.app - original MacOSX test application (no list header code)
  • HICustomPushButton-orig.cp - original MacOSX sample code
  • HICustomPushButton.r - MacOSX demo resources
  • English.lproj - MacOSX demo resources
  • JunkCodeSnips.cpp, Detritus.txt - scrap code

PageInfo
PageType DevDocPage
MaintainedBy DavidSurovell
PageStatus Work in progress -- this page is still being drafted?
Trash.CommentsWelcome2 Feel free to contribute comments?
Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r65 < r64 < r63 < r62 < r61 | More topic actions
 
Open Source Applications Foundation
Except where otherwise noted, this site and its content are licensed by OSAF under an Creative Commons License, Attribution Only 3.0.
See list of page contributors for attributions.