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