Enlightenment CVS committal

Author  : pfritz
Project : e17
Module  : libs/ewl

Dir     : e17/libs/ewl/src/lib


Modified Files:
        ewl_combo.c ewl_combo.h ewl_context_menu.c ewl_context_menu.h 


Log Message:
- make it possible to set a custom container to hold the widget of the context 
menu
- use this and make it possible to have scrollable combo

Note: there are some minor tweaks need, the problem is kwon, but not the 
solution atm

===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_combo.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -3 -r1.49 -r1.50
--- ewl_combo.c 16 Mar 2007 23:18:50 -0000      1.49
+++ ewl_combo.c 17 Mar 2007 08:55:37 -0000      1.50
@@ -4,6 +4,7 @@
 #include "ewl_button.h"
 #include "ewl_cell.h"
 #include "ewl_context_menu.h"
+#include "ewl_scrollpane.h"
 #include "ewl_menu.h"
 #include "ewl_debug.h"
 #include "ewl_macros.h"
@@ -81,7 +82,8 @@
        ewl_widget_appearance_set(combo->popup, EWL_COMBO_TYPE
                                                "/"EWL_POPUP_TYPE);
        ewl_object_fill_policy_set(EWL_OBJECT(combo->popup),
-                                       EWL_FLAG_FILL_HFILL);
+                                       EWL_FLAG_FILL_HFILL 
+                                       | EWL_FLAG_FILL_NONE);
        ewl_object_alignment_set(EWL_OBJECT(combo->popup),
                                EWL_FLAG_ALIGN_LEFT | EWL_FLAG_ALIGN_TOP);
        ewl_callback_append(combo->popup, EWL_CALLBACK_HIDE,
@@ -107,7 +109,7 @@
        DCHECK_PARAM_PTR("combo", combo);
        DCHECK_TYPE("combo", combo, EWL_COMBO_TYPE);
 
-       if (combo->editable == editable)
+       if (combo->editable == !!editable)
                DRETURN(DLEVEL_STABLE);
 
        combo->editable = !!editable;
@@ -134,6 +136,70 @@
 }
 
 /**
+ * @param combo: The Ewl_Combo to use
+ * @param editable: Set if the combo is scrollable or not
+ * @return Returns no value
+ *
+ * On true, this functions set the combo to use a scrollpane to view the
+ * widget inside of it. The maximal size of it is set by a theme
+ * defined value.
+ */
+void
+ewl_combo_scrollable_set(Ewl_Combo *combo, unsigned int scrollable)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("combo", combo);
+       DCHECK_TYPE("combo", combo, EWL_COMBO_TYPE);
+
+       if (combo->scrollable == !!scrollable)
+               DRETURN(DLEVEL_STABLE);
+
+       combo->scrollable = !!scrollable;
+
+       if (scrollable) {
+               Ewl_Widget *scroll;
+               int max_h;
+
+               max_h = ewl_theme_data_int_get(EWL_WIDGET(combo), 
+                                               "/combo/popup/height");
+               /* set it to sane values if it isn't defined in the theme */
+               if (max_h <= 0)
+                       max_h = 100;
+
+               /* setup the new scrollpane container */
+               scroll = ewl_scrollpane_new();
+               ewl_object_fill_policy_set(EWL_OBJECT(scroll), 
+                                               EWL_FLAG_FILL_HFILL
+                                               | EWL_FLAG_FILL_SHRINK);
+               ewl_object_maximum_h_set(EWL_OBJECT(scroll), max_h);
+               ewl_widget_show(scroll);
+
+               ewl_context_menu_container_set(EWL_CONTEXT_MENU(combo->popup),
+                                                       EWL_CONTAINER(scroll));
+       }
+       else
+               ewl_context_menu_container_set(EWL_CONTEXT_MENU(combo->popup),
+                                               NULL);
+
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @param combo: The Ewl_Combo to use
+ * @return Returns the scrollable status of the combo
+ * @brief Retrieves the scrollable status of the combo
+ */
+unsigned int
+ewl_combo_scrollable_get(Ewl_Combo *combo)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("combo", combo, FALSE);
+       DCHECK_TYPE_RET("combo", combo, EWL_COMBO_TYPE, FALSE);
+
+       DRETURN_INT(combo->scrollable, DLEVEL_STABLE);
+}
+/**
  * @internal
  * @param w: UNUSED
  * @param ev: The event data
@@ -287,6 +353,7 @@
        menu = ewl_menu_new();
        ewl_widget_appearance_set(EWL_MENU(menu)->popup, EWL_COMBO_TYPE
                                                "/"EWL_POPUP_TYPE);
+       ewl_widget_appearance_set(menu, EWL_COMBO_TYPE"_menu");
 
        /* nothing to do if we have no model/view or data */
        if (!model || !view)
@@ -397,6 +464,7 @@
                DRETURN_INT(FALSE, DLEVEL_STABLE);
 
        ewl_widget_inherit(EWL_WIDGET(cell), EWL_COMBO_CELL_TYPE);
+       ewl_widget_appearance_set(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);
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_combo.h,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -3 -r1.26 -r1.27
--- ewl_combo.h 15 Mar 2007 06:04:17 -0000      1.26
+++ ewl_combo.h 17 Mar 2007 08:55:38 -0000      1.27
@@ -56,6 +56,7 @@
        Ewl_Widget *button;     /**< expand/contract button */
        Ewl_Widget *header;     /**< The combo header widget */
        unsigned char editable:1; /**< Is the combo editable */
+       unsigned char scrollable:1; /**< Is the combo scrollable */
 };
 
 Ewl_Widget     *ewl_combo_new(void);
@@ -64,6 +65,10 @@
 void            ewl_combo_editable_set(Ewl_Combo *combo, 
                                                unsigned int editable);
 unsigned int    ewl_combo_editable_get(Ewl_Combo *combo);
+void            ewl_combo_scrollable_set(Ewl_Combo *combo, 
+                                               unsigned int scrollable);
+unsigned int    ewl_combo_scrollable_get(Ewl_Combo *combo);
+
 
 /*
  * Internally used callbacks, override at your own risk.
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_context_menu.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -3 -r1.5 -r1.6
--- ewl_context_menu.c  8 Mar 2007 00:31:21 -0000       1.5
+++ ewl_context_menu.c  17 Mar 2007 08:55:38 -0000      1.6
@@ -51,7 +51,6 @@
 ewl_context_menu_init(Ewl_Context_Menu *cm)
 {
        Ewl_Widget *w;
-       Ewl_Widget *box;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR_RET("cm", cm, FALSE);
@@ -68,15 +67,7 @@
                                 EWL_FLAG_ALIGN_LEFT | EWL_FLAG_ALIGN_TOP);
        ewl_popup_type_set(EWL_POPUP(cm), EWL_POPUP_TYPE_MOUSE);
 
-       box = ewl_vbox_new();
-       ewl_container_child_append(EWL_CONTAINER(cm), box);
-       ewl_widget_show(box);
-
-       /* redirect the context menu to the inner box */
-       ewl_container_redirect_set(EWL_CONTAINER(cm), EWL_CONTAINER(box));
-       ewl_widget_internal_set(box, TRUE);
-       ewl_container_add_notify_set(EWL_CONTAINER(box), 
-                                       ewl_context_menu_cb_child_add);
+       ewl_context_menu_container_set(cm, NULL);
 
        /* add the callbacks */
        ewl_callback_append(w, EWL_CALLBACK_MOUSE_DOWN, 
@@ -155,6 +146,76 @@
 }
 
 /**
+ * @param cm: the context menu to set the container
+ * @param c: the container to use inside of the context menu, if @a c is
+ *             NULL then this function will use a vbox instead
+ * @brief set a custom container for the context menu
+ *
+ * This function give you the ability to set a custom container as 
+ * the internal used container of the context menu. It is not necessary to
+ * use this function, because the context menu uses a vbox as default,
+ * if you do not add an own one. If you override a previous added container,
+ * this container will be destroyed, but the children will be moved into
+ * the new container.
+ */
+void 
+ewl_context_menu_container_set(Ewl_Context_Menu *cm, Ewl_Container *c)
+{
+       Ewl_Container *old_c = NULL;
+       Ewl_Container *red;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("cm", cm);
+       DCHECK_TYPE("cm", cm, EWL_CONTEXT_MENU_TYPE);
+       
+       /* if there is not a container specified we will create a vbox as
+        * default */
+       if (!c)
+               c = EWL_CONTAINER(ewl_vbox_new());
+
+       /* remove the old container */
+       if (cm->container) {
+               old_c = EWL_CONTAINER(cm->container);
+               ewl_container_redirect_set(EWL_CONTAINER(cm), NULL);
+               ewl_container_child_remove(EWL_CONTAINER(cm),
+                                                       EWL_WIDGET(old_c));
+               cm->container = NULL;
+       }
+       
+       /* now we can append the new container */
+       ewl_container_child_append(EWL_CONTAINER(cm), EWL_WIDGET(c));
+       ewl_widget_show(EWL_WIDGET(c));
+
+       /* redirect the context menu to the new container */
+       ewl_container_redirect_set(EWL_CONTAINER(cm), c);
+       ewl_widget_internal_set(EWL_WIDGET(c), TRUE);
+       /* add the callbacks to the last container in the redirect list */
+       red = ewl_container_end_redirect_get(c);
+       if (!red)
+               red = c;
+       ewl_container_add_notify_set(red, ewl_context_menu_cb_child_add);
+       ewl_container_remove_notify_set(red, ewl_context_menu_cb_child_remove);
+
+       /* if we already had a container we have to move the existing widgets
+        * in to the new one.
+        * Note: We leave internal widgets out because they are part of the 
+        * container and not of the context menu */
+       if (old_c) {
+               Ewl_Widget *child;
+
+               ewl_container_child_iterate_begin(old_c);
+               while ((child = ewl_container_child_next(old_c))) 
+                       ewl_container_child_append(c, child);
+               /* and now destroy the old container */
+               ewl_widget_destroy(EWL_WIDGET(old_c));
+       }
+
+       cm->container = EWL_WIDGET(c);
+
+       DRETURN(DLEVEL_STABLE);
+}
+
+/**
  * @internal
  * @param w: The widget to work with
  * @param ev_data: UNUSED
@@ -178,7 +239,8 @@
        if (ev->button != 3)
                DRETURN(DLEVEL_STABLE);
        
-       ewl_popup_mouse_position_set(EWL_POPUP(user_data), ev->base.x, 
ev->base.y);
+       ewl_popup_mouse_position_set(EWL_POPUP(user_data), ev->base.x, 
+                                                               ev->base.y);
        ewl_widget_show(EWL_WIDGET(user_data));
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
@@ -353,6 +415,8 @@
 void
 ewl_context_menu_cb_child_add(Ewl_Container *c, Ewl_Widget *w)
 {
+       Ewl_Widget *cm;
+
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("c", c);
        DCHECK_PARAM_PTR("w", w);
@@ -362,19 +426,50 @@
        if (ewl_widget_internal_is(w) || !ewl_widget_focusable_get(w))
                DRETURN(DLEVEL_STABLE);
 
+       cm = EWL_WIDGET(ewl_embed_widget_find(EWL_WIDGET(c)));
        if (EWL_MENU_IS(w)) {
-               Ewl_Widget *cm;
                
-               cm = ewl_widget_parent_get(EWL_WIDGET(c));
                EWL_MENU_ITEM(w)->inmenu = cm;
        }
        else
                ewl_callback_append(w, EWL_CALLBACK_CLICKED,
-                               ewl_context_menu_cb_child_clicked,
-                               ewl_widget_parent_get(EWL_WIDGET(c)));
+                               ewl_context_menu_cb_child_clicked, cm);
 
        ewl_callback_append(w, EWL_CALLBACK_MOUSE_IN, 
-                               ewl_context_menu_cb_child_mouse_in, c);
+                               ewl_context_menu_cb_child_mouse_in, NULL);
+       
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/**
+ * @internal
+ * @param c: The container to work with
+ * @param w: The widget to work with
+ * @return Returns no value
+ * @brief The child remove callback
+ */
+void
+ewl_context_menu_cb_child_remove(Ewl_Container *c, Ewl_Widget *w, 
+                                       int idx __UNUSED__)
+{
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("c", c);
+       DCHECK_PARAM_PTR("w", w);
+       DCHECK_TYPE("c", c, EWL_CONTAINER_TYPE);
+       DCHECK_TYPE("w", w, EWL_WIDGET_TYPE);
+
+       if (ewl_widget_internal_is(w) || !ewl_widget_focusable_get(w))
+               DRETURN(DLEVEL_STABLE);
+
+       if (EWL_MENU_IS(w)) {
+               EWL_MENU_ITEM(w)->inmenu = NULL;
+       }
+       else
+               ewl_callback_del(w, EWL_CALLBACK_CLICKED,
+                               ewl_context_menu_cb_child_clicked);
+
+       ewl_callback_del(w, EWL_CALLBACK_MOUSE_IN, 
+                               ewl_context_menu_cb_child_mouse_in);
        
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
===================================================================
RCS file: /cvs/e/e17/libs/ewl/src/lib/ewl_context_menu.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- ewl_context_menu.h  8 Mar 2007 00:31:21 -0000       1.3
+++ ewl_context_menu.h  17 Mar 2007 08:55:38 -0000      1.4
@@ -43,6 +43,7 @@
 {
        Ewl_Popup popup; /**< Inherit from Ewl_Popup */
        Ewl_Widget *open_menu; /**< a pointer to the current open submenu */
+       Ewl_Widget *container; /**< the container holding the children */
 };
 
 Ewl_Widget     *ewl_context_menu_new(void);
@@ -50,6 +51,9 @@
 void            ewl_context_menu_attach(Ewl_Context_Menu *cm, Ewl_Widget *w);
 void            ewl_context_menu_detach(Ewl_Context_Menu *cm, Ewl_Widget *w);
 
+void            ewl_context_menu_container_set(Ewl_Context_Menu *cm, 
+                                                       Ewl_Container *c);
+
 /*
  * Internal, override at your own risk
  */
@@ -63,6 +67,7 @@
 void ewl_context_menu_cb_attach_mouse_down(Ewl_Widget *w, void *ev_data, 
                                                        void *user_data);
 void ewl_context_menu_cb_child_add(Ewl_Container *c, Ewl_Widget *w);
+void ewl_context_menu_cb_child_remove(Ewl_Container *c, Ewl_Widget *w, int 
idx);
 void ewl_context_menu_cb_child_mouse_in(Ewl_Widget *w, void *ev_data, 
                                                        void *user_data);
 void ewl_context_menu_cb_child_clicked(Ewl_Widget *w, void *ev_data, 



-------------------------------------------------------------------------
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