Hi Jeremy, On Wed, Apr 30, 2008 at 09:33:36PM +0100, Jeremy Henty wrote:
This is a first cut at making FltkListResource work properly.
The resource maintains a hash of its items' selected status, the MultiBrowser widget gets a callback that updates the hash and isSelected() looks up the hash for the answer. It's the same technique I used for FltkOptionMenuResource , where the FLTK widgets are linked to their resources by user_data() and callback arguments.
I added equals() and hashValue() methods to Items so they could be hash keys, and implemented an object::Object wrapper class for boolean values to be the hash values. The wrapper class is inside FltkListResource , though it could easily move to lout::object IMHO.
It seems a bit complicated to me. Wouldn't it be easier to just add a member "selected" to Item that stores whether the item is currently selected or not? May well be that I'm missing something though. Cheers, Johannes
The patch also enables the ListResource widget in test/dw-ui-test .
Unfortunately it's still a little buggy. Specifying multiple selected items initially doesn't work right: they are all selected in the resource but only one is selected on the FLTK widget. Things also go out of sync when you select a group item: any previously selected item is unselected in the widget but not in the resource. I'll look into these further.
Comments are welcome!
Regards,
Jeremy Henty
diff -pru -- 00_pre/dw/fltkui.cc 01_post/dw/fltkui.cc --- 00_pre/dw/fltkui.cc 2008-04-26 21:42:58.000000000 +0100 +++ 01_post/dw/fltkui.cc 2008-04-30 20:37:40.000000000 +0100 @@ -858,6 +858,22 @@ template <class I> FltkSelectionResource }
template <class I> +bool FltkSelectionResource<I>::Item::equals (Object *other) +{ + return ((void *) this) == ((void *) other); +} + +template <class I> +int FltkSelectionResource<I>::Item::hashValue () +{ +#if SIZEOF_VOID_P == 4 + return (int)this; +#else + return ((int*) this)[0] ^ ((int*) this)[1]; +#endif +} + +template <class I> ::fltk::Item *FltkSelectionResource<I>::Item::createNewWidget () { ::fltk::Item *item = new ::fltk::Item (name); @@ -1107,7 +1123,8 @@ bool FltkOptionMenuResource::isSelected FltkListResource::FltkListResource (FltkPlatform *platform, core::ui::ListResource::SelectionMode selectionMode): - FltkSelectionResource <dw::core::ui::ListResource> (platform) + FltkSelectionResource <dw::core::ui::ListResource> (platform), + itemsSelected(false,false) { init (platform); } @@ -1119,10 +1136,34 @@ FltkListResource::~FltkListResource ()
::fltk::Menu *FltkListResource::createNewMenu (core::Allocation *allocation) { - return + ::fltk::Menu *menu = new ::fltk::MultiBrowser (allocation->x, allocation->y, allocation->width, allocation->ascent + allocation->descent); + menu->callback(widgetCallback,this); + menu->when(::fltk::WHEN_CHANGED); + return menu; +} + +void FltkListResource::widgetCallback (::fltk::Widget *widget, void *data) +{ + ::fltk::Widget *fltkItem = ((::fltk::Menu *) widget)->item (); + Item *item = (Item *) (fltkItem->user_data ()); + if (!item) return; + Selection *selected = Selection::fromBool(fltkItem->selected ()); + ((FltkListResource *) data)->itemsSelected.put (item, selected); +} + +void FltkListResource::addItem (const char *str, bool enabled, bool selected) +{ + FltkSelectionResource<dw::core::ui::ListResource>::addItem + (str,enabled,selected); + Item *item = items->get (items->size()-1); + Selection *is_selected = Selection::fromBool (selected); + itemsSelected.put(item,is_selected); + + // blindly copied from FltkOptionMenuResource, is it necessary? + queueResize (true); }
void FltkListResource::sizeRequest (core::Requisition *requisition) @@ -1135,8 +1176,15 @@ void FltkListResource::sizeRequest (core
bool FltkListResource::isSelected (int index) { - /** todo Not implemented. */ - return true; + return itemsSelected.get(items->get(index))->getValue(); +} + +FltkListResource::Selection FltkListResource::Selection::SELECTED(true); +FltkListResource::Selection FltkListResource::Selection::UNSELECTED(false); + +FltkListResource::Selection *FltkListResource::Selection::fromBool(bool value) +{ + return value ? &SELECTED : &UNSELECTED; }
} // namespace ui diff -pru -- 00_pre/dw/fltkui.hh 01_post/dw/fltkui.hh --- 00_pre/dw/fltkui.hh 2008-04-26 21:42:58.000000000 +0100 +++ 01_post/dw/fltkui.hh 2008-04-30 20:37:40.000000000 +0100 @@ -458,6 +458,9 @@ protected: bool selected = false); ~Item ();
+ bool equals (Object *other); + int hashValue (); + ::fltk::Item *createNewWidget (); ::fltk::ItemGroup *createNewGroupWidget (); }; @@ -526,11 +529,31 @@ class FltkListResource: protected: ::fltk::Menu *createNewMenu (core::Allocation *allocation);
+private: + + class Selection : public Object { + + private: + bool value; + + public: + Selection(bool value) { this->value = value; } + inline int getValue() { return value; } + + static Selection SELECTED, UNSELECTED; + static Selection *fromBool (bool value); + }; + + static void widgetCallback (::fltk::Widget *widget, void *data); + container::typed::HashTable <Item, Selection> itemsSelected; + public: FltkListResource (FltkPlatform *platform, core::ui::ListResource::SelectionMode selectionMode); ~FltkListResource ();
+ void addItem (const char *str, bool enabled, bool selected); + void sizeRequest (core::Requisition *requisition); bool isSelected (int index); }; diff -pru -- 00_pre/test/dw_ui_test.cc 01_post/test/dw_ui_test.cc --- 00_pre/test/dw_ui_test.cc 2008-04-26 21:42:59.000000000 +0100 +++ 01_post/test/dw_ui_test.cc 2008-04-30 20:37:40.000000000 +0100 @@ -192,7 +192,7 @@ int main(int argc, char **argv) checklabel->addText (strdup (" check"), cellStyle); checklabel->flush ();
- for(int i = 0; i < 1; i++) { + for(int i = 0; i < 2; i++) { table->addRow (cellStyle);
Embed *sel = new Embed (selres[i]);
_______________________________________________ Dillo-dev mailing list Dillo-dev@dillo.org http://lists.auriga.wearlab.de/cgi-bin/mailman/listinfo/dillo-dev