[patch]: FtlkListResource select callbacks
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. 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
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
On Wed, Apr 30, 2008 at 10:52:37PM +0200, Johannes Hofmann 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.
It's not so much complicated as cumbersome: the logic is pretty straightforward, but using the Hash requires extra scaffolding. I was reluctant to add stuff to Item because that class serves double duty for both FltkListResource and FltkOptionMenuResource and so it's ugly for Item to contain stuff that is specific to one of the resource classes. Of course the resource classes could derive their own Item classes, but that adds scaffolding too. IIRC I experimented with that when I first did FltkOptionMenuResource (before going for a simpler suggestion of yours, I think) and the templating made it particularly messy. Let me think about it a little while I fix the bugs. I think the bug fixes will be orthogonal to the issue of how we store the selection information so it shouldn't impact implementing your suggestions if that's the way to go. Regards, Jeremy Henty
participants (2)
-
Johannes.Hofmann@gmx.de
-
onepoint@starurchin.org