From: <enl...@li...> - 2006-02-08 12:49:44
|
Enlightenment CVS committal Author : codewarrior Project : e17 Module : proto Dir : e17/proto/etk/src/lib Modified Files: Etk.h Makefile.am etk_main.c etk_types.h etk_widget.c etk_widget.h etk_window.c Added Files: etk_spin_button.c etk_spin_button.h Log Message: - add skeleton for spin button widget (doesnt work yet!) - add xdnd drop support per widget - see test. =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/Etk.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -3 -r1.16 -r1.17 --- Etk.h 19 Jan 2006 13:56:10 -0000 1.16 +++ Etk.h 8 Feb 2006 12:49:38 -0000 1.17 @@ -57,5 +57,6 @@ #include "etk_filechooser_widget.h" #include "etk_notebook.h" #include "etk_progress_bar.h" +#include "etk_spin_button.h" #endif =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/Makefile.am,v retrieving revision 1.19 retrieving revision 1.20 diff -u -3 -r1.19 -r1.20 --- Makefile.am 19 Jan 2006 13:56:10 -0000 1.19 +++ Makefile.am 8 Feb 2006 12:49:38 -0000 1.20 @@ -40,7 +40,8 @@ etk_statusbar.h \ etk_filechooser_widget.h \ etk_notebook.h \ -etk_progress_bar.h +etk_progress_bar.h \ +etk_spin_button.h libetk_la_SOURCES = \ etk_main.c etk_utils.c \ @@ -68,6 +69,7 @@ etk_filechooser_widget.c \ etk_notebook.c \ etk_progress_bar.c \ +etk_spin_button.c \ $(ETKHEADERS) installed_headersdir = $(prefix)/include/etk =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_main.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -3 -r1.10 -r1.11 --- etk_main.c 15 Jan 2006 11:07:16 -0000 1.10 +++ etk_main.c 8 Feb 2006 12:49:38 -0000 1.11 @@ -1,7 +1,10 @@ /** @file etk_main.c */ #include "etk_main.h" #include <locale.h> +#include <string.h> +#include <stdlib.h> #include <Ecore.h> +#include <Ecore_X.h> #include <Ecore_Job.h> #include <Ecore_Evas.h> #include <Evas.h> @@ -12,6 +15,7 @@ #include "etk_toplevel_widget.h" #include "etk_utils.h" #include "etk_theme.h" +#include "etk_window.h" #include "config.h" /** @@ -23,10 +27,19 @@ static void _etk_main_size_request_recursive(Etk_Widget *widget); static void _etk_main_size_allocate_recursive(Etk_Widget *widget, Etk_Bool is_top_level); +#if HAVE_ECORE_X +static int _etk_xdnd_enter_handler(void *data, int type, void *event); +static int _etk_xdnd_position_handler(void *data, int type, void *event); +static int _etk_xdnd_drop_handler(void *data, int type, void *event); +static int _etk_xdnd_leave_handler(void *data, int type, void *event); +static int _etk_xdnd_selection_handler(void *data, int type, void *event); +#endif + static Evas_List *_etk_main_toplevel_widgets = NULL; static Etk_Bool _etk_main_running = ETK_FALSE; static Etk_Bool _etk_main_initialized = ETK_FALSE; static Ecore_Job *_etk_main_iterate_job = NULL; +static Etk_Widget *_etk_dnd_widget = NULL; /************************** * @@ -63,6 +76,15 @@ ETK_WARNING("Edje initialization failed!"); return ETK_FALSE; } + +#if HAVE_ECORE_X + if (!ecore_x_init(NULL)) + { + ETK_WARNING("Ecore_X initialzation failed!"); + return ETK_FALSE; + } +#endif + etk_theme_init(); /* Gettext */ @@ -70,6 +92,14 @@ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); +#if HAVE_ECORE_X + ecore_event_handler_add(ECORE_X_EVENT_XDND_ENTER, _etk_xdnd_enter_handler, NULL); + ecore_event_handler_add(ECORE_X_EVENT_XDND_POSITION, _etk_xdnd_position_handler, NULL); + ecore_event_handler_add(ECORE_X_EVENT_XDND_DROP, _etk_xdnd_drop_handler, NULL); + ecore_event_handler_add(ECORE_X_EVENT_XDND_LEAVE, _etk_xdnd_leave_handler, NULL); + ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY, _etk_xdnd_selection_handler, NULL); +#endif + _etk_main_initialized = ETK_TRUE; return ETK_TRUE; } @@ -214,4 +244,205 @@ } } + +#if HAVE_ECORE_X +#define E_INSIDE(x, y, xx, yy, ww, hh) (((x) < ((xx) + (ww))) && ((y) < ((yy) + (hh))) && ((x) >= (xx)) && ((y) >= (yy))) +static int _etk_xdnd_enter_handler(void *data, int type, void *event) +{ + Ecore_X_Event_Xdnd_Enter *ev; + int i; + + /* printf("enter\n"); */ + ev = event; + /* + for (i = 0; i < ev->num_types; i++) + printf("type: %s\n", ev->types[i]); + */ + return 1; +} + +/* Search the container recursively for the widget that accepts xdnd */ +static void _etk_xdnd_container_get_widgets_at(Etk_Container *cont, int x, int y, int offx, int offy, Evas_List **list) +{ + Evas_List *child; + + for(child = etk_container_children_get(cont); child; child = child->next) + { + Etk_Widget *widget; + + if(!(widget = ETK_WIDGET(child->data))) + continue; + + if(E_INSIDE(x, y, + widget->inner_geometry.x + offx, + widget->inner_geometry.y + offy, + widget->inner_geometry.w, + widget->inner_geometry.h)) + { + if(widget->accepts_xdnd) + { + *list = evas_list_append(*list, widget); + } + + if(ETK_IS_CONTAINER(widget)) + _etk_xdnd_container_get_widgets_at(ETK_CONTAINER(widget), x, y, offx, offy, list); + } + } +} + +static int _etk_xdnd_position_handler(void *data, int type, void *event) +{ + Ecore_X_Event_Xdnd_Position *ev; + Etk_Window *window; + Evas_List *l; + Evas_List *children = NULL; + Etk_Widget *widget; + ev = event; + + /* loop top level widgets (windows) */ + for(l = _etk_main_toplevel_widgets; l; l = l->next) + { + int x, y; + + if (!(window = ETK_WINDOW(l->data))) + continue; + + /* if this isnt the active window, dont waste time */ + if(ev->win != window->x_window) + continue; + + ecore_evas_geometry_get(window->ecore_evas, &x, &y, NULL, NULL); + + /* find the widget we want to drop on */ + _etk_xdnd_container_get_widgets_at(ETK_CONTAINER(window), ev->position.x, ev->position.y, x, y, &children); + } + + /* if we found a widget, emit signals */ + if(children != NULL) + { + Ecore_X_Rectangle rect; + widget = (evas_list_last(children))->data; + _etk_dnd_widget = widget; + /* TODO: filter types according to what widget wants */ + rect.x = widget->inner_geometry.x; + rect.y = widget->inner_geometry.y; + rect.width = widget->inner_geometry.w; + rect.height = widget->inner_geometry.h; + ecore_x_dnd_send_status(1, 1, rect, ECORE_X_DND_ACTION_PRIVATE); + } + + return 1; +} + +static int _etk_xdnd_drop_handler(void *data, int type, void *event) +{ + Ecore_X_Event_Xdnd_Drop *ev; + + /* printf("drop\n"); */ + ev = event; + + ecore_x_selection_xdnd_request(ev->win, "text/uri-list"); + return 1; +} + +static int _etk_xdnd_leave_handler(void *data, int type, void *event) +{ + /* printf("leave\n"); */ + return 1; +} + +static int _etk_xdnd_selection_handler(void *data, int type, void *event) +{ + Ecore_X_Event_Selection_Notify *ev; + Ecore_X_Selection_Data *sel; + Ecore_X_Selection_Data_Files *files; + Ecore_X_Selection_Data_Text *text; + Ecore_X_Selection_Data_Targets *targets; + int i; + + /* printf("selection\n"); */ + ev = event; + switch (ev->selection) + { + case ECORE_X_SELECTION_PRIMARY: + if (!strcmp(ev->target, ECORE_X_SELECTION_TARGET_TARGETS)) + { + /* printf("primary: %s\n", ev->target); */ + targets = ev->data; + /* + for (i = 0; i < targets->num_targets; i++) + printf("target: %s\n", targets->targets[i]); + */ + } + else + { + text = ev->data; + /* printf("primary: %s %s\n", ev->target, text->text); */ + } + break; + + case ECORE_X_SELECTION_SECONDARY: + sel = ev->data; + /* printf("secondary: %s %s\n", ev->target, sel->data); */ + break; + + case ECORE_X_SELECTION_XDND: + /* printf("xdnd: %s\n", ev->target); */ + + files = ev->data; + + if(!_etk_dnd_widget || files->num_files < 1) + break; + + /* free old data, should this be done here? */ + for (i = 0; i < _etk_dnd_widget->xdnd_files_num; i++) + { + if(_etk_dnd_widget->xdnd_files[i]) + free(_etk_dnd_widget->xdnd_files[i]); + } + + if(_etk_dnd_widget->xdnd_files) + free(_etk_dnd_widget->xdnd_files); + + _etk_dnd_widget->xdnd_files = calloc(files->num_files, sizeof(char*)); + + /* printf("num_files: %d\n", files->num_files); */ + + /* Fill in the drop data into the widget */ + _etk_dnd_widget->xdnd_files_num = files->num_files; + for (i = 0; i < files->num_files; i++) + { + /* printf("file: %s\n", files->files[i]); */ + _etk_dnd_widget->xdnd_files[i] = strdup(files->files[i]); + } + + /* emit the drop signal so the widget can react */ + etk_widget_drag_drop(_etk_dnd_widget); + + ecore_x_dnd_send_finished(); + break; + + case ECORE_X_SELECTION_CLIPBOARD: + if (!strcmp(ev->target, ECORE_X_SELECTION_TARGET_TARGETS)) + { + printf("clipboard: %s\n", ev->target); + targets = ev->data; + /* + for (i = 0; i < targets->num_targets; i++) + printf("target: %s\n", targets->targets[i]); + */ + } + else + { + text = ev->data; + /* printf("clipboard: %s %s\n", ev->target, text->text); */ + } + break; + } + + return 1; +} + +#endif + /** @} */ =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_types.h,v retrieving revision 1.22 retrieving revision 1.23 diff -u -3 -r1.22 -r1.23 --- etk_types.h 19 Jan 2006 23:09:24 -0000 1.22 +++ etk_types.h 8 Feb 2006 12:49:38 -0000 1.23 @@ -105,6 +105,7 @@ typedef struct _Etk_Notebook Etk_Notebook; typedef struct _Etk_Progress_Bar Etk_Progress_Bar; typedef enum _Etk_Progress_Bar_Orientation Etk_Progress_Bar_Orientation; +typedef struct _Etk_Spin_Button Etk_Spin_Button; /** * @enum Etk_Fill_Policy_Flags =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -3 -r1.18 -r1.19 --- etk_widget.c 15 Jan 2006 11:07:17 -0000 1.18 +++ etk_widget.c 8 Feb 2006 12:49:38 -0000 1.19 @@ -13,6 +13,7 @@ #include "etk_marshallers.h" #include "etk_signal.h" #include "etk_signal_callback.h" +#include "config.h" /** * @addtogroup Etk_Widget @@ -60,6 +61,7 @@ ETK_WIDGET_FOCUS_SIGNAL, ETK_WIDGET_UNFOCUS_SIGNAL, ETK_WIDGET_SCROLL_SIZE_CHANGED_SIGNAL, + ETK_WIDGET_DRAG_DROP_SIGNAL, ETK_WIDGET_NUM_SIGNALS }; @@ -90,6 +92,7 @@ static void _etk_widget_leave_handler(Etk_Widget *widget); static void _etk_widget_focus_handler(Etk_Widget *widget); static void _etk_widget_unfocus_handler(Etk_Widget *widget); +static void _etk_widget_drag_drop_handler(Etk_Widget *widget); static void _etk_widget_mouse_in_cb(void *data, Evas *evas, Evas_Object *object, void *event_info); static void _etk_widget_signal_mouse_in_cb(Etk_Object *object, Etk_Event_Mouse_In_Out *event, void *data); @@ -167,6 +170,7 @@ _etk_widget_signals[ETK_WIDGET_FOCUS_SIGNAL] = etk_signal_new("focus", widget_type, ETK_MEMBER_OFFSET(Etk_Widget, focus), etk_marshaller_VOID__VOID, NULL, NULL); _etk_widget_signals[ETK_WIDGET_UNFOCUS_SIGNAL] = etk_signal_new("unfocus", widget_type, ETK_MEMBER_OFFSET(Etk_Widget, unfocus), etk_marshaller_VOID__VOID, NULL, NULL); _etk_widget_signals[ETK_WIDGET_SCROLL_SIZE_CHANGED_SIGNAL] = etk_signal_new("scroll_size_changed", widget_type, -1, etk_marshaller_VOID__VOID, NULL, NULL); + _etk_widget_signals[ETK_WIDGET_DRAG_DROP_SIGNAL] = etk_signal_new("drag_drop", widget_type, ETK_MEMBER_OFFSET(Etk_Widget, drag_drop),etk_marshaller_VOID__VOID, NULL, NULL); etk_type_property_add(widget_type, "name", ETK_WIDGET_NAME_PROPERTY, ETK_PROPERTY_STRING, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_string(NULL)); etk_type_property_add(widget_type, "parent", ETK_WIDGET_PARENT_PROPERTY, ETK_PROPERTY_POINTER, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_pointer(NULL)); @@ -1395,6 +1399,19 @@ return widget->clip; } +#if HAVE_ECORE_X +/** + * @brief Sends the "drag_drop" signal + * @param widget a widget + */ +void etk_widget_drag_drop(Etk_Widget *widget) +{ + if (!widget) + return; + etk_signal_emit(_etk_widget_signals[ETK_WIDGET_DRAG_DROP_SIGNAL], ETK_OBJECT(widget), NULL); +} + +#endif /************************** * @@ -1429,7 +1446,8 @@ widget->leave = _etk_widget_leave_handler; widget->focus = _etk_widget_focus_handler; widget->unfocus = _etk_widget_unfocus_handler; - + widget->drag_drop = _etk_widget_drag_drop_handler; + widget->left_inset = 0; widget->right_inset = 0; widget->top_inset = 0; @@ -1460,7 +1478,12 @@ widget->need_redraw = ETK_FALSE; widget->need_theme_min_size_recalc = ETK_FALSE; widget->swallowed = ETK_FALSE; - +#if HAVE_ECORE_X + widget->accepts_xdnd = ETK_FALSE; + widget->xdnd_files = NULL; + widget->xdnd_files_num = 0; +#endif + etk_signal_connect_full(_etk_widget_signals[ETK_WIDGET_MOUSE_IN_SIGNAL], ETK_OBJECT(widget), ETK_CALLBACK(_etk_widget_signal_mouse_in_cb), NULL, ETK_FALSE, ETK_FALSE); etk_signal_connect_full(_etk_widget_signals[ETK_WIDGET_MOUSE_OUT_SIGNAL], ETK_OBJECT(widget), ETK_CALLBACK(_etk_widget_signal_mouse_out_cb), NULL, ETK_FALSE, ETK_FALSE); etk_signal_connect_full(_etk_widget_signals[ETK_WIDGET_MOUSE_DOWN_SIGNAL], ETK_OBJECT(widget), ETK_CALLBACK(_etk_widget_signal_mouse_down_cb), NULL, ETK_FALSE, ETK_FALSE); @@ -1633,6 +1656,15 @@ etk_widget_theme_object_signal_emit(widget, "unfocus"); } +/* Default handler for the "drag_drop" signal */ +static void _etk_widget_drag_drop_handler(Etk_Widget *widget) +{ + if (!widget) + return; + etk_widget_theme_object_signal_emit(widget, "drag_drop"); +} + + /* Sets the widget as visible and queues a visibility update */ static void _etk_widget_show_handler(Etk_Widget *widget) { @@ -1926,6 +1958,35 @@ _etk_widget_key_up_cb(widget->parent, evas, NULL, event_info); } +#if HAVE_ECORE_X +void etk_widget_xdnd_set(Etk_Widget *widget, Etk_Bool on) +{ + if(on) + widget->accepts_xdnd = 1; + else + widget->accepts_xdnd = 0; +} + +Etk_Bool etk_widget_xdnd_get(Etk_Widget *widget) +{ + if(widget->accepts_xdnd) return ETK_TRUE; + + return ETK_FALSE; +} + +const char ** etk_widget_xdnd_files_get(Etk_Widget *widget, int *num_files) +{ + if(!widget->accepts_xdnd || widget->xdnd_files == NULL) + return NULL; + + if(num_files) + *num_files = widget->xdnd_files_num; + + return widget->xdnd_files; +} +#endif + + /************************** * * Private functions @@ -2164,8 +2225,8 @@ evas_object_move(widget->theme_object, widget->geometry.x, widget->geometry.y); evas_object_resize(widget->theme_object, widget->geometry.w, widget->geometry.h); } - if (widget->size_allocate) - widget->size_allocate(widget, widget->inner_geometry); + if (widget->size_allocate) + widget->size_allocate(widget, widget->inner_geometry); widget->need_redraw = ETK_FALSE; } =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.h,v retrieving revision 1.12 retrieving revision 1.13 diff -u -3 -r1.12 -r1.13 --- etk_widget.h 19 Dec 2005 13:30:32 -0000 1.12 +++ etk_widget.h 8 Feb 2006 12:49:38 -0000 1.13 @@ -3,6 +3,7 @@ #define _ETK_WIDGET_H_ #include <Evas.h> +#include <Ecore_X.h> #include <stdarg.h> #include "etk_object.h" #include "etk_types.h" @@ -165,7 +166,8 @@ void (*scroll_size_get)(Etk_Widget *widget, Etk_Size *scroll_size); void (*scroll_margins_get)(Etk_Widget *widget, Etk_Size *margin_size); void (*scroll)(Etk_Widget *widget, int x, int y); - + void (*drag_drop)(Etk_Widget *widget); + void (*show)(Etk_Widget *widget); void (*enter)(Etk_Widget *widget); void (*leave)(Etk_Widget *widget); @@ -184,6 +186,12 @@ unsigned char need_redraw : 1; unsigned char need_theme_min_size_recalc : 1; unsigned char swallowed : 1; +//#if HAVE_ECORE_X + unsigned char accepts_xdnd : 1; + + char **xdnd_files; + int xdnd_files_num; +//#endif }; Etk_Type *etk_widget_type_get(); @@ -255,6 +263,13 @@ void etk_widget_clip_unset(Etk_Widget *widget); Evas_Object *etk_widget_clip_get(Etk_Widget *widget); +//#if HAVE_ECORE_X +void etk_widget_xdnd_set(Etk_Widget *widget, Etk_Bool on); +Etk_Bool etk_widget_xdnd_get(Etk_Widget *widget); +const char **etk_widget_xdnd_files_get(Etk_Widget *e, int *num_files); +void etk_widget_drag_drop(Etk_Widget *widget); +//#endif + /** @} */ #endif =================================================================== RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_window.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -3 -r1.9 -r1.10 --- etk_window.c 15 Jan 2006 11:07:17 -0000 1.9 +++ etk_window.c 8 Feb 2006 12:49:38 -0000 1.10 @@ -1,6 +1,7 @@ /** @file etk_window.c */ #include "etk_window.h" #include <stdlib.h> +#include <string.h> #include <Ecore_X.h> #include <Ecore_X_Cursor.h> #include "etk_main.h" @@ -447,6 +448,22 @@ return ETK_TRUE; } +#if HAVE_ECORE_X +/** + * @brief A utility function to use as a callback for the "delete_event" signal. It will hide the window and return ETK_TRUE to prevent the program to quit + * @param window the window to hide + * @param data the data passed when the signal is emitted - unused + * @return Return ETK_TRUE so the the program won't quit + */ +void etk_window_xdnd_aware_set(Etk_Window *window, Etk_Bool on) +{ + if(on) + ecore_x_dnd_aware_set(window->x_window, 1); + else + ecore_x_dnd_aware_set(window->x_window, 0); +} +#endif + /************************** * * Etk specific functions @@ -463,6 +480,25 @@ window->ecore_evas = ecore_evas_software_x11_new(NULL, 0, 0, 0, 0, 0); window->x_window = ecore_evas_software_x11_window_get(window->ecore_evas); + +#if HAVE_ECORE_X + { + const char *types[] = { "*" }; + char **drop_types; + int i; + + ecore_x_dnd_aware_set(window->x_window, 1); + + drop_types = calloc(1, sizeof(char *)); + + for (i = 0; i < 1; i++) + drop_types[i] = strdup(types[i]); + + ecore_x_dnd_types_set(window->x_window, drop_types , 1); + } + +#endif + ETK_TOPLEVEL_WIDGET(window)->evas = ecore_evas_get(window->ecore_evas); ETK_TOPLEVEL_WIDGET(window)->pointer_set = _etk_window_pointer_set; ETK_TOPLEVEL_WIDGET(window)->geometry_get = _etk_window_toplevel_geometry_get; |