Page MenuHomePhabricator

EO: Item and Item_List API's
Open, HighPublic

Description

Subtask for T5301.

The original idea for item-based widgets was to rely on MVVM internally, and then expose simpler APIs externally in order to manipulate items easily.
Unfortunately work on T5354, T5355, T5333 and future/promise is still under way, leaving us with too many unanswered questions.

Toolbar/ctxpopup/menu/multibuttonentry all are item-based widgets that are in desperate need of a clean EO API.
I believe that we don't need to worry about performance at the API level (never a crazy large number of items in those widgets), and that we need to provide as simple an API as possible. Also, we should avoid creating non-widget objects as items, as those require special handling for focus, accessibility, etc...

So here is my proposal for a simple pair of item+item list interfaces. Basically an item is created by an item list (eg. toolbar) with a text and an icon. Then the user can modify it all they want (add event callbacks, etc...).

Icons are given by name so that DBUS menus can implement this interface, and in theory this should be good enough as icons should come from the theme and its extensions.

efl_ui_item.eo

interface Efl.Ui.Item
{
   /* Note: All methods prefixed with item_ as they might have conflicting names
    * with base classes, such as Efl.Text. */

   [[An individual widget item for an @Efl.Ui.Item_List.

     Each item is a real widget, but all item classes have in common the
     following properties:
      - a text
      - an icon
     Items can be selected or activated. Items are real widgets, so any widget
     operation can be applied to these items.

     The item list provides extra functionality (get item index, move it,
     iterate, etc...).

     @since 1.21
   ]]
   methods {
      @property item_list {
         [[The parent item list.]]
         get {}
         values {
            list: Efl.Ui.Item_List; [[The parent list.]]
         }
      }
      @property item_text {
         [[The base text for this item.

           If the real object implements @Efl.Text, this should be the same as
           @Efl.Text.text.
         ]]
         get {}
         set {}
         values {
            text: string @nullable; [[Human readable text.]]
         }
      }
      @property item_icon {
         [[The base icon name for this item.

           This is a standard icon name, as used in $Efl.Ui.Image.
         ]]
         get {}
         set {}
         values {
            icon: string @nullable; [[An icon name.]]
         }
      }

   }
   events {
      selected; [[This item was selected.]]
      unselected; [[This item was unselected.]]
   }
}

efl_ui_item_list.eo

interface Efl.Ui.Item_List
{
   [[A flat list of widget items.

     To remove an item, simply delete it.

     @since 1.21
   ]]
   eo_prefix: efl_ui_item;
   methods {
      item_append {
         [[Create and add a new item to the end of this list.

           After creation, it is common to install event callbacks on the item
           object returned.
         ]]
         params {
            text: string; [[A visible text.]]
            icon: string; [[Standard name of an icon.]]
         }
         return: Efl.Ui.Item; [[Returns a new item.]]
      }
      item_prepend {
         [[Create and add a new item to the beginning of this list.

           After creation, it is common to install event callbacks on the item
           object returned.
         ]]
         params {
            text: string; [[A visible text.]]
            icon: string; [[Standard name of an icon.]]
         }
         return: Efl.Ui.Item; [[Returns a new item.]]
      }
      item_insert {
         [[Create and insert an item at a given position.

           After creation, it is common to install event callbacks on the item
           object returned.
         ]]
         params {
            text: string; [[A visible text.]]
            icon: string; [[Standard name of an icon.]]
            index: int(-1); [[The position index in this list. If -1, append.]]
         }
         return: Efl.Ui.Item; [[Returns a new item.]]
      }
      @property item_index {
         [[An item's index.]]
         get {
            [[Get an existing item's index. If not found, returns -1.]]
         }
         set {
            [[Move an item at a given index. Use -1 to push to the end.]]
         }
         keys {
            item: Efl.Ui.Item; [[An item to inspect.]]
         }
         values {
            index: int(-1); [[The item's index.]]
         }
      }
      /* item_at + item_count could be replaced with an accessor */
      @property item_at {
         [[Get the item at a given index.]]
         get {}
         keys {
            index: uint; [[The index must be valid, otherwise $null is
                           returned.]]
         }
         values {
            item: Efl.Ui.Item @nullable; [[The item widget.]]
         }
      }
      @property item_count {
         [[Get the number of items in this list.]]
         get {}
         values {
            count: uint(0); [[The number of items.]]
         }
      }
      item_iterate {
         [[Start iterating on the items in this list.]]
         return: iterator<Efl.Ui.Item> @owned;
      }
   }
   events {
      item,added: Efl.Ui.Item; [[A new item was just added.]]
      item,removed: Efl.Ui.Item; [[An item will be removed.]]
   }
}

See also T6236, T5327

jpeg added a comment.Nov 13 2017, 3:03 AM

Problem #1:
An item (text+icon) can take multiple different forms during its lifetime. For instance in a toolbar with "More" menu, items can be either icon+label or a submenu item. Those are 2 different edje groups.

jpeg added a comment.Nov 13 2017, 3:03 AM

Problem #2:
What about separators?

@felipealmeida @cedric @raster
Using real widgets as handles for the items can be problematic in quite a few cases (toolbar main button and menu item look different, dbus menu, etc...).
Using model, how could we easily create items and register event callbacks on them?

Any thoughts on a solution that can be implemented QUICKLY? (and obviously without shooting ourselves in the foot for future maintenance and extension).

jpeg reassigned this task from jpeg to cedric.Jan 18 2018, 12:34 AM

This depends on @cedric's work on the model. Come on.

zmike edited projects, added Restricted Project; removed efl.Jun 11 2018, 6:51 AM
segfaultxavi edited projects, added efl: widgets; removed Restricted Project.Jun 11 2018, 7:31 AM
zmike added a subscriber: zmike.

A #Goal ticket should not be set to a milestone.