Enlightenment CVS committal

Author  : pfritz
Project : e17
Module  : libs/ewl

Dir     : e17/libs/ewl/src/lib


Modified Files:
        ewl_combo.c ewl_combo.h 


Log Message:
the combo can now have submenus, this works the similar to tree2

===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_combo.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -3 -r1.46 -r1.47
--- ewl_combo.c 6 Feb 2007 13:42:16 -0000       1.46
+++ ewl_combo.c 15 Mar 2007 06:04:17 -0000      1.47
@@ -3,12 +3,17 @@
 #include "ewl_combo.h"
 #include "ewl_button.h"
 #include "ewl_cell.h"
-#include "ewl_popup.h"
+#include "ewl_context_menu.h"
+#include "ewl_menu.h"
 #include "ewl_debug.h"
 #include "ewl_macros.h"
 #include "ewl_private.h"
 
 static void ewl_combo_cb_selected_change(Ewl_MVC *mvc);
+Ewl_Widget *ewl_combo_submenu_new(Ewl_Combo *c, Ewl_Model *model, 
+                                       void *mvc_data);
+static void ewl_combo_popup_fill(Ewl_Combo *combo, Ewl_Container *c, 
+                       Ewl_Model *model, void *mvc_data);
 
 /**
  * @return Returns a pointer to a new combo on success, NULL on failure.
@@ -42,8 +47,6 @@
 int
 ewl_combo_init(Ewl_Combo *combo)
 {
-       Ewl_Widget *o;
-
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR_RET("combo", combo, FALSE);
 
@@ -68,7 +71,7 @@
        /*
         * setup the popup
         */
-       combo->popup = ewl_popup_new();
+       combo->popup = ewl_context_menu_new();
        ewl_popup_follow_set(EWL_POPUP(combo->popup), EWL_WIDGET(combo));
        ewl_popup_type_set(EWL_POPUP(combo->popup), 
                                EWL_POPUP_TYPE_MENU_VERTICAL);
@@ -81,20 +84,8 @@
                                        EWL_FLAG_FILL_HFILL);
        ewl_object_alignment_set(EWL_OBJECT(combo->popup),
                                EWL_FLAG_ALIGN_LEFT | EWL_FLAG_ALIGN_TOP);
-       ewl_callback_append(combo->popup, EWL_CALLBACK_MOUSE_DOWN,
-                                       ewl_combo_cb_popup_mouse_down, combo);
-       
-       /*
-        * setup the popbox
-        */
-       o = ewl_vbox_new();
-       ewl_container_child_append(EWL_CONTAINER(combo->popup), o);
-       ewl_container_redirect_set(EWL_CONTAINER(combo->popup), 
EWL_CONTAINER(o));
-       ewl_widget_show(o);
-
-       ewl_object_fill_policy_set(EWL_OBJECT(combo), 
-                               EWL_FLAG_FILL_HFILL | EWL_FLAG_FILL_VSHRINK);
-
+       ewl_callback_append(combo->popup, EWL_CALLBACK_HIDE,
+                                       ewl_combo_cb_popup_hide, combo);
 
        DRETURN_INT(TRUE, DLEVEL_STABLE);
 }
@@ -158,7 +149,6 @@
        Ewl_Model *model;
        Ewl_View *view;
        void *mvc_data;
-       int i;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("data", data);
@@ -186,24 +176,8 @@
                DRETURN(DLEVEL_STABLE);
 
        ewl_container_reset(EWL_CONTAINER(combo->popup));
-       for (i = 0; i < model->count(mvc_data); i++)
-       {
-               Ewl_Widget *cell;
-               Ewl_Widget *item;
-
-               cell = ewl_cell_new();
-               ewl_object_fill_policy_set(EWL_OBJECT(cell), 
-                                               EWL_FLAG_FILL_HFILL);
-               ewl_container_child_append(EWL_CONTAINER(combo->popup), cell);
-               ewl_callback_append(cell, EWL_CALLBACK_CLICKED,
-                                       ewl_combo_cb_item_clicked, combo);
-               ewl_widget_show(cell);
-
-               item = view->construct();
-               view->assign(item, model->fetch(mvc_data, i, 0));
-               ewl_container_child_append(EWL_CONTAINER(cell), item);
-               ewl_widget_show(item);
-       }
+       ewl_combo_popup_fill(combo, EWL_CONTAINER(combo->popup), model, 
+                               mvc_data);
 
        ewl_mvc_dirty_set(EWL_MVC(combo), FALSE);
 
@@ -219,63 +193,27 @@
  * @brief Callback for when the button to close the combo is clicked
  */
 void
-ewl_combo_cb_popup_mouse_down(Ewl_Widget *w, 
+ewl_combo_cb_popup_hide(Ewl_Widget *w, 
                                void *ev __UNUSED__, void *data)
 {
-       DENTER_FUNCTION(DLEVEL_STABLE);
-       DCHECK_PARAM_PTR("data", data);
-
-       if (w == ewl_embed_focused_widget_get(EWL_EMBED(w))) {
-               Ewl_Combo *combo;
-               
-               combo = EWL_COMBO(data);
-               ewl_widget_hide(combo->popup);
-               ewl_widget_state_set(combo->button, "collapsed", 
-                                       EWL_STATE_PERSISTENT);
-       }
-
-       DLEAVE_FUNCTION(DLEVEL_STABLE);
-}
-
-/**
- * @internal
- * @param w: UNUSED
- * @param ev: UNUSED
- * @param data: The combo widget
- * @return Returns no value
- * @brief Callback for when a combo item is clicked
- */
-void
-ewl_combo_cb_item_clicked(Ewl_Widget *w __UNUSED__, void *ev __UNUSED__, 
-                                                               void *data)
-{
-       int i;
        Ewl_Combo *combo;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("data", data);
 
-       combo = data;
-
-       i = ewl_container_child_index_get(EWL_CONTAINER(combo->popup), w);
-       ewl_mvc_selected_set(EWL_MVC(combo), NULL, 
-                               ewl_mvc_data_get(EWL_MVC(combo)), i, -1);
-
-       ewl_widget_hide(combo->popup);
-       ewl_widget_state_set(combo->button, "collapsed",
-                                       EWL_STATE_PERSISTENT);
+       combo = EWL_COMBO(data);
+       ewl_widget_state_set(combo->button, "collapsed", EWL_STATE_PERSISTENT);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+
 static void
 ewl_combo_cb_selected_change(Ewl_MVC *mvc)
 {
        Ewl_View *view;
-       Ewl_Model *model;
        Ewl_Combo *combo;
        Ewl_Widget *item = NULL;
-       void *mvc_data;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("mvc", mvc);
@@ -283,10 +221,8 @@
 
        combo = EWL_COMBO(mvc);
        view = ewl_mvc_view_get(mvc);
-       model = ewl_mvc_model_get(mvc);
-       mvc_data = ewl_mvc_data_get(mvc);
 
-       if (!mvc_data)
+       if (!ewl_mvc_data_get(mvc))
                DRETURN(DLEVEL_STABLE);
 
        /*
@@ -307,19 +243,289 @@
        if (ewl_mvc_selected_count_get(mvc))
        {
                Ewl_Selection_Idx *idx;
+               Ewl_Model *model;
+               void *mvc_data;
 
                idx = ewl_mvc_selected_get(mvc);
+               model = idx->sel.model;
+               mvc_data = idx->sel.data;
+
                item = view->construct();
                view->assign(item, model->fetch(mvc_data, idx->row, 0));
        }
-       else if (view->header_fetch)
-               item = view->header_fetch(mvc_data, -1);
+       else if (view->header_fetch) 
+               item = view->header_fetch(ewl_mvc_model_get(mvc), -1);
 
        if (item)
        {
                ewl_container_child_prepend(EWL_CONTAINER(combo->header), item);
                ewl_widget_show(item);
        }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @internal
+ * @param w: UNUSED
+ * @param ev: The event data
+ * @param data: The combo box
+ * @return Returns no value
+ * @brief Callback for when the button to expand the combo is pressed
+ */
+Ewl_Widget *
+ewl_combo_submenu_new(Ewl_Combo *combo, Ewl_Model *model, void *mvc_data)
+{
+       Ewl_Widget *menu;
+       Ewl_View *view;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("combo", combo, NULL);
+
+       view = ewl_mvc_view_get(EWL_MVC(combo));
+
+       menu = ewl_menu_new();
+       ewl_widget_appearance_set(EWL_MENU(menu)->popup, EWL_COMBO_TYPE
+                                               "/"EWL_POPUP_TYPE);
+
+       /* nothing to do if we have no model/view or data */
+       if (!model || !view)
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+
+       ewl_combo_popup_fill(combo, EWL_CONTAINER(menu), model, mvc_data);
+
+       ewl_button_label_set(EWL_BUTTON(menu), NULL);
+       ewl_button_image_set(EWL_BUTTON(menu), NULL, NULL);
+       ewl_object_fill_policy_set(EWL_OBJECT(menu), EWL_FLAG_FILL_HFILL);
+       ewl_container_redirect_set(EWL_CONTAINER(menu), 
+                       EWL_CONTAINER(EWL_BUTTON(menu)->body));
+
+       DRETURN_PTR(menu, DLEVEL_STABLE);
+}
+
+/**
+ * @internal
+ * @param combo: The combo
+ * @param c: The container to fill
+ * @param model: The model to fill the container
+ * @param mvc_data: The data to fill the container
+ * @return Returns no value
+ * @brief fill the given container with the items
+ */
+static void
+ewl_combo_popup_fill(Ewl_Combo *combo, Ewl_Container *c, Ewl_Model *model, 
void *mvc_data)
+{
+       Ewl_View *view;
+       int count;
+       int i;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("combo", combo);
+
+       view = ewl_mvc_view_get(EWL_MVC(combo));
+
+       /* XXX put checks to make sure all the needed module and view
+        * function callbacks are setup */
+       count = model->count(mvc_data);
+       for (i = 0; i < count; i++)
+       {
+               Ewl_Widget *o, *item;
+
+               if (model->expansion.is && model->expansion.is(mvc_data, i))
+               {
+                       Ewl_Model *em;
+                       void *data;
+
+                       em = model->expansion.model(mvc_data, i);
+                       data = model->expansion.data(mvc_data, i);
+                       o = ewl_combo_submenu_new(combo, em, data);
+               }
+               else
+               {
+                       o = ewl_combo_cell_new();
+                       ewl_combo_cell_combo_set(EWL_COMBO_CELL(o), combo);
+                       ewl_combo_cell_model_set(EWL_COMBO_CELL(o), model);
+                       ewl_combo_cell_data_set(EWL_COMBO_CELL(o), mvc_data);
+               }
+               ewl_container_child_append(c, o);
+               ewl_widget_show(o);
+
+               item = view->construct();
+               view->assign(item, model->fetch(mvc_data, i, 0));
+               ewl_container_child_append(EWL_CONTAINER(o), item);
+               ewl_widget_show(item);
+       }
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @return Returns a pointer to a new combo cell  on success, NULL on failure.
+ * @brief Create a new combo cell
+ */
+Ewl_Widget *
+ewl_combo_cell_new(void)
+{
+       Ewl_Combo_Cell *cell;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       cell = NEW(Ewl_Combo_Cell, 1);
+       if (!cell)
+               DRETURN_PTR(NULL, DLEVEL_STABLE);
+
+       if (!ewl_combo_cell_init(cell)) 
+       {
+               ewl_widget_destroy(EWL_WIDGET(cell));
+               cell = NULL;
+       }
+
+       DRETURN_PTR(EWL_WIDGET(cell), DLEVEL_STABLE);
+}
+
+/**
+ * @param combo: The Ewl_Combo_Cell to initialize
+ * @return Returns TRUE on success or FALSE on failure
+ * @brief Initializes a combo cell to default values 
+ */
+int
+ewl_combo_cell_init(Ewl_Combo_Cell *cell)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("cell", cell, FALSE);
+
+       if (!ewl_cell_init(EWL_CELL(cell)))
+               DRETURN_INT(FALSE, DLEVEL_STABLE);
+
+       ewl_widget_inherit(EWL_WIDGET(cell), EWL_COMBO_CELL_TYPE);
+       ewl_object_fill_policy_set(EWL_OBJECT(cell), EWL_FLAG_FILL_HFILL);
+       ewl_callback_append(EWL_WIDGET(cell), EWL_CALLBACK_CLICKED, 
+                               ewl_combo_cell_cb_clicked, NULL);
+
+       DRETURN_INT(TRUE, DLEVEL_STABLE);
+}
+
+/**
+ * @param cell: The Ewl_Combo_Cell to use
+ * @param combo: the parent combo widget
+ * @return Returns no value
+ */
+void
+ewl_combo_cell_combo_set(Ewl_Combo_Cell *cell, Ewl_Combo *combo)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("cell", cell);
+       DCHECK_TYPE("cell", cell, EWL_COMBO_CELL_TYPE);
+       DCHECK_PARAM_PTR("combo", combo);
+       DCHECK_TYPE("combo", combo, EWL_COMBO_TYPE);
+
+       cell->combo = combo;
+       
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @param cell: The Ewl_Combo to use
+ * @return Returns the parent combo of the cell
+ */
+Ewl_Combo *
+ewl_combo_cell_combo_get(Ewl_Combo_Cell *cell)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("cell", cell, NULL);
+       DCHECK_TYPE_RET("cell", cell, EWL_COMBO_TYPE, NULL);
+
+       DRETURN_PTR(cell->combo, DLEVEL_STABLE);
+}
+
+/**
+ * @param cell: The Ewl_Combo_Cell to use
+ * @param model: the model for the cell
+ * @return Returns no value
+ */
+void
+ewl_combo_cell_model_set(Ewl_Combo_Cell *cell, Ewl_Model *model)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("cell", cell);
+       DCHECK_TYPE("cell", cell, EWL_COMBO_CELL_TYPE);
+       DCHECK_PARAM_PTR("model", model);
+
+       cell->model = model;
+       
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @param cell: The Ewl_Combo to use
+ * @return Returns the model of the cell
+ */
+Ewl_Model *
+ewl_combo_cell_model_get(Ewl_Combo_Cell *cell)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("cell", cell, NULL);
+       DCHECK_TYPE_RET("cell", cell, EWL_COMBO_CELL_TYPE, NULL);
+
+       DRETURN_PTR(cell->model, DLEVEL_STABLE);
+}
+
+/**
+ * @param cell: The Ewl_Combo_Cell to use
+ * @param mvc_data: the data for the cell
+ * @return Returns no value
+ */
+void
+ewl_combo_cell_data_set(Ewl_Combo_Cell *cell, void *mvc_data)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("cell", cell);
+       DCHECK_TYPE("cell", cell, EWL_COMBO_CELL_TYPE);
+
+       cell->mvc_data = mvc_data;
+       
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @param cell: The Ewl_Combo to use
+ * @return Returns the model of the cell
+ */
+void *
+ewl_combo_cell_data_get(Ewl_Combo_Cell *cell)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("cell", cell, NULL);
+       DCHECK_TYPE_RET("cell", cell, EWL_COMBO_CELL_TYPE, NULL);
+
+       DRETURN_PTR(cell->mvc_data, DLEVEL_STABLE);
+}
+/**
+ * @internal
+ * @param w: UNUSED
+ * @param ev: UNUSED
+ * @param data: The combo widget
+ * @return Returns no value
+ * @brief Callback for when a combo item is clicked
+ */
+void
+ewl_combo_cell_cb_clicked(Ewl_Widget *w, void *ev __UNUSED__, 
+                                                       void *data __UNUSED__)
+{
+       Ewl_Combo *combo;
+       Ewl_Model *model;
+       void *mvc_data;
+       int i;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("w", w);
+
+       i = ewl_container_child_index_get(EWL_CONTAINER(w->parent), w);
+
+       combo = ewl_combo_cell_combo_get(EWL_COMBO_CELL(w));
+       model = ewl_combo_cell_model_get(EWL_COMBO_CELL(w));
+       mvc_data = ewl_combo_cell_data_get(EWL_COMBO_CELL(w));
+       
+       ewl_mvc_selected_set(EWL_MVC(combo), model, mvc_data, i, -1);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_combo.h,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -3 -r1.25 -r1.26
--- ewl_combo.h 4 Mar 2007 00:52:01 -0000       1.25
+++ ewl_combo.h 15 Mar 2007 06:04:17 -0000      1.26
@@ -3,6 +3,7 @@
 #define EWL_COMBO_H
 
 #include "ewl_mvc.h"
+#include "ewl_cell.h"
 
 /**
  * @addtogroup Ewl_Combo Ewl_Combo: A Simple Combo Box
@@ -68,11 +69,62 @@
  * Internally used callbacks, override at your own risk.
  */
 void ewl_combo_cb_decrement_clicked(Ewl_Widget *w, void *ev, void *data);
-void ewl_combo_cb_popup_mouse_down(Ewl_Widget *w, void *ev, void *data);
-void ewl_combo_cb_item_clicked(Ewl_Widget *w, void *ev, void *data);
+void ewl_combo_cb_popup_hide(Ewl_Widget *w, void *ev, void *data);
+
+/*
+ * Ewl_Combo_Cell
+ */
+
+/**
+ * @def EWL_COMBO_CELL
+ * The type name for the Ewl_Combo_Cell widget
+ */
+#define EWL_COMBO_CELL_TYPE "combo_cell"
+
+/**
+ * @def EWL_COMBO_CELL_IS(w)
+ * Returns TRUE if the widget is an Ewl_Combo_Cell, FALSE otherwise
+ */
+#define EWL_COMBO_CELL_IS(w) (ewl_widget_type_is(EWL_WIDGET(w), 
EWL_COMBO_CELL_TYPE))
+
+/**
+ * Typedef for the Ewl_Combo_Cell struct
+ */
+typedef struct Ewl_Combo_Cell Ewl_Combo_Cell;
+
+/**
+ * @def EWL_COMBO_CELL(c)
+ * Typecasts a pointer to an Ewl_Combo_Cell pointer
+ */
+#define EWL_COMBO_CELL(c) ((Ewl_Combo_Cell *)c)
+
+/**
+ * @brief Inherits from Ewl_Cell and is used internally for the combo box
+ */
+struct Ewl_Combo_Cell
+{
+       Ewl_Cell cell;          /**< Inherit from the cell */
+       Ewl_Combo *combo;       /**< The parent combo */
+       Ewl_Model *model;       /**< The model that was used to build the 
+                                       content of the cell */
+       void *mvc_data;         /**< The mvc data that was used to build the
+                                       content of the cell */
+};
+
+Ewl_Widget     *ewl_combo_cell_new(void);
+int             ewl_combo_cell_init(Ewl_Combo_Cell *c);
+void            ewl_combo_cell_combo_set(Ewl_Combo_Cell *c, Ewl_Combo *combo);
+Ewl_Combo      *ewl_combo_cell_combo_get(Ewl_Combo_Cell *c);
+
+void            ewl_combo_cell_model_set(Ewl_Combo_Cell *c, Ewl_Model *model);
+Ewl_Model      *ewl_combo_cell_model_get(Ewl_Combo_Cell *c);
+
+void            ewl_combo_cell_data_set(Ewl_Combo_Cell *c, void *mvc_data);
+void           *ewl_combo_cell_data_get(Ewl_Combo_Cell *c);
 
 /**
  * @}
  */
+void ewl_combo_cell_cb_clicked(Ewl_Widget *w, void *ev, void *data);
 
 #endif



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to