Enlightenment CVS committal Author : dj2 Project : e17 Module : libs/ewl
Dir : e17/libs/ewl/src/lib Modified Files: ewl_paned.c ewl_paned.h Log Message: - rework the paned widget - get rid of the active_area stuff, not needed anymore - just append your widgets with the normal container functions and the grabbers will be automaticalloy added. Can hold as many panes as needed per paned widget =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_paned.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -3 -r1.11 -r1.12 --- ewl_paned.c 2 Dec 2005 19:53:44 -0000 1.11 +++ ewl_paned.c 28 Dec 2005 22:25:47 -0000 1.12 @@ -3,16 +3,24 @@ #include "ewl_macros.h" #include "ewl_private.h" -static void ewl_paned_grabber_mouse_down_cb(Ewl_Widget *w, void *ev, - void *user_data); -static void ewl_paned_grabber_mouse_up_cb(Ewl_Widget *w, void *ev, - void *user_data); -static void ewl_paned_grabber_mouse_move_cb(Ewl_Widget *w, void *ev, - void *user_data); -static void ewl_paned_grabber_mouse_in_cb(Ewl_Widget *w, void *ev, - void *user_data); -static void ewl_paned_grabber_mouse_out_cb(Ewl_Widget *w, void *ev, - void *user_data); +static void ewl_paned_grabber_cb_mouse_down(Ewl_Widget *w, void *ev, + void *data); +static void ewl_paned_grabber_cb_mouse_up(Ewl_Widget *w, void *ev, + void *data); +static void ewl_paned_grabber_cb_mouse_move(Ewl_Widget *w, void *ev, + void *data); +static void ewl_paned_grabber_cb_mouse_in(Ewl_Widget *w, void *ev, + void *data); +static void ewl_paned_grabber_cb_mouse_out(Ewl_Widget *w, void *ev, + void *data); + +static void ewl_paned_configure_horizontal(Ewl_Paned *p); +static void ewl_paned_configure_vertical(Ewl_Paned *p); + +static void ewl_paned_grabber_horizontal_shift(Ewl_Paned *p, + Ewl_Widget *w, int to); +static void ewl_paned_grabber_vertical_shift(Ewl_Paned *p, + Ewl_Widget *w, int to); /** * @return Returns NULL on failure, or a pointer to a new paned widget on success. @@ -21,7 +29,7 @@ Ewl_Widget * ewl_paned_new(void) { - Ewl_Paned *pane = NULL; + Ewl_Paned *pane; DENTER_FUNCTION(DLEVEL_STABLE); @@ -44,16 +52,9 @@ Ewl_Widget * ewl_hpaned_new(void) { - Ewl_Widget *pane = NULL; - DENTER_FUNCTION(DLEVEL_STABLE); - pane = ewl_paned_new(); - if (pane) - ewl_box_orientation_set(EWL_BOX(pane), - EWL_ORIENTATION_HORIZONTAL); - - DRETURN_PTR(pane, DLEVEL_STABLE); + DRETURN_PTR(ewl_paned_new(), DLEVEL_STABLE); } /** @@ -63,14 +64,13 @@ Ewl_Widget * ewl_vpaned_new(void) { - Ewl_Widget *pane = NULL; + Ewl_Widget *pane; DENTER_FUNCTION(DLEVEL_STABLE); pane = ewl_paned_new(); if (pane) - ewl_box_orientation_set(EWL_BOX(pane), - EWL_ORIENTATION_VERTICAL); + EWL_PANED(pane)->orientation = EWL_ORIENTATION_VERTICAL; DRETURN_PTR(pane, DLEVEL_STABLE); } @@ -83,117 +83,317 @@ int ewl_paned_init(Ewl_Paned *p) { - Ewl_Widget *w = NULL; + Ewl_Widget *w; DENTER_FUNCTION(DLEVEL_STABLE); DCHECK_PARAM_PTR_RET("p", p, FALSE); w = EWL_WIDGET(p); - if (!ewl_box_init(EWL_BOX(p))) { + if (!ewl_container_init(EWL_CONTAINER(p))) DRETURN_INT(FALSE, DLEVEL_STABLE); - } ewl_widget_appearance_set(w, "paned"); ewl_widget_inherit(w, "paned"); + + p->orientation = EWL_ORIENTATION_HORIZONTAL; - ewl_callback_prepend(EWL_WIDGET(p), EWL_CALLBACK_CONFIGURE, - ewl_paned_configure_cb, NULL); + ewl_container_add_notify_set(EWL_CONTAINER(p), + ewl_paned_cb_child_add); + ewl_container_remove_notify_set(EWL_CONTAINER(p), + ewl_paned_cb_child_remove); + ewl_container_show_notify_set(EWL_CONTAINER(p), + ewl_paned_cb_child_show); + ewl_container_hide_notify_set(EWL_CONTAINER(p), + ewl_paned_cb_child_hide); - p->grabbed = FALSE; + ewl_callback_append(w, EWL_CALLBACK_CONFIGURE, + ewl_paned_cb_configure, NULL); - p->first = EWL_BOX(ewl_vbox_new()); - ewl_container_child_append(EWL_CONTAINER(p), EWL_WIDGET(p->first)); - ewl_object_fill_policy_set(EWL_OBJECT(p->first), EWL_FLAG_FILL_ALL); - ewl_widget_show(EWL_WIDGET(p->first)); - - p->grabber = ewl_vseparator_new(); - ewl_object_custom_w_set(EWL_OBJECT(p->grabber), 10); - - ewl_container_child_append(EWL_CONTAINER(p), EWL_WIDGET(p->grabber)); - ewl_callback_append(EWL_WIDGET(p->grabber), EWL_CALLBACK_MOUSE_DOWN, - ewl_paned_grabber_mouse_down_cb, p); - ewl_callback_append(EWL_WIDGET(p->grabber), EWL_CALLBACK_MOUSE_UP, - ewl_paned_grabber_mouse_up_cb, p); - ewl_callback_append(EWL_WIDGET(p->grabber), EWL_CALLBACK_MOUSE_MOVE, - ewl_paned_grabber_mouse_move_cb, p); - ewl_callback_append(EWL_WIDGET(p->grabber), EWL_CALLBACK_MOUSE_IN, - ewl_paned_grabber_mouse_in_cb, p); - ewl_callback_append(EWL_WIDGET(p->grabber), EWL_CALLBACK_MOUSE_OUT, - ewl_paned_grabber_mouse_out_cb, p); - ewl_widget_layer_set(EWL_WIDGET(p->grabber), 100); - ewl_widget_show(EWL_WIDGET(p->grabber)); - - p->second = EWL_BOX(ewl_vbox_new()); - ewl_container_child_append(EWL_CONTAINER(p), EWL_WIDGET(p->second)); - ewl_object_fill_policy_set(EWL_OBJECT(p->second), EWL_FLAG_FILL_ALL); - ewl_widget_show(EWL_WIDGET(p->second)); - - ewl_widget_internal_set(EWL_WIDGET(p->first), TRUE); - ewl_widget_internal_set(EWL_WIDGET(p->second), TRUE); - ewl_widget_internal_set(EWL_WIDGET(p->grabber), TRUE); - - p->active = EWL_POSITION_LEFT; - ewl_container_redirect_set(EWL_CONTAINER(p), EWL_CONTAINER(p->first)); - - ewl_widget_appearance_set(EWL_WIDGET(p->first), "first"); - ewl_widget_appearance_set(EWL_WIDGET(p->second), "second"); - - /* Looks like we only do horizontally-split panes right now */ - ewl_object_fill_policy_set(EWL_OBJECT(p->second), EWL_FLAG_FILL_NORMAL); - ewl_object_fill_policy_set(EWL_OBJECT(p->first), - EWL_FLAG_FILL_HSHRINK | EWL_FLAG_FILL_VFILL ); - ewl_object_fill_policy_set(EWL_OBJECT(p), EWL_FLAG_FILL_NORMAL); + ewl_object_fill_policy_set(EWL_OBJECT(w), EWL_FLAG_FILL_FILL); - /* ewl_widget_appearance_set(EWL_WIDGET(p->grabber), "grabber_horizontal"); */ + /* XXX should this be focusable? */ + ewl_widget_focusable_set(w, FALSE); DRETURN_INT(TRUE, DLEVEL_STABLE); } /** - * @param p: the paned wiget to work on - * @param pos: The Ewl_Position to set to the active partition - * @returns Returns no value. - * @brief Changes the current active pane of the paned widget + * @param p: The paned to set the orientation on + * @param o: The Ewl_Orientation to set + * @return Returns no value. */ -void -ewl_paned_active_area_set(Ewl_Paned *p, Ewl_Position pos) +void +ewl_paned_orientation_set(Ewl_Paned *p, Ewl_Orientation o) { + Ewl_Widget *child; + Ewl_Orientation sep; + char *buf; + DENTER_FUNCTION(DLEVEL_STABLE); DCHECK_PARAM_PTR("p", p); DCHECK_TYPE("p", p, "paned"); - if ((pos == EWL_POSITION_LEFT) || (pos == EWL_POSITION_TOP)) - ewl_container_redirect_set(EWL_CONTAINER(p), - EWL_CONTAINER(p->first)); + if (p->orientation == o) + DRETURN(DLEVEL_STABLE); + + if (o == EWL_ORIENTATION_HORIZONTAL) + { + buf = "grabber/vertical"; + sep = EWL_ORIENTATION_VERTICAL; + } else - ewl_container_redirect_set(EWL_CONTAINER(p), - EWL_CONTAINER(p->second)); + { + buf = "grabber/horizontal"; + sep = EWL_ORIENTATION_HORIZONTAL; + } + ecore_list_goto_first(EWL_CONTAINER(p)->children); + while ((child = ecore_list_next(EWL_CONTAINER(p)->children))) + { + /* Update each internal child to have the correct + * appearance/orientation. XXX This assumes that all + * internal widgets will be grabbers ... */ + if (ewl_widget_internal_is(child)) + { + ewl_widget_appearance_set(child, buf); + ewl_separator_orientation_set(EWL_SEPARATOR(child), sep); + } + } DLEAVE_FUNCTION(DLEVEL_STABLE); } /** - * @param p: the paned wiget to work against - * @return Returns the Ewl_Position specifing the active position - * @brief Gets the current active partiton from the paned wiget + * @param p: The Ewl_Paned to get the orientation from + * @return Returns the Ewl_Orientation currently set on the paned */ -Ewl_Position -ewl_paned_active_area_get(Ewl_Paned *p) +Ewl_Orientation +ewl_paned_orientation_get(Ewl_Paned *p) { DENTER_FUNCTION(DLEVEL_STABLE); - DCHECK_PARAM_PTR_RET("p", p, FALSE); - DCHECK_TYPE("p", p, "paned"); + DCHECK_PARAM_PTR_RET("p", p, EWL_ORIENTATION_HORIZONTAL); + DCHECK_TYPE_RET("p", p, "paned", EWL_ORIENTATION_HORIZONTAL); + + DRETURN_INT(p->orientation, DLEVEL_STABLE); +} + +void +ewl_paned_cb_child_add(Ewl_Container *c, Ewl_Widget *w) +{ + Ewl_Widget *o; + int idx; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("c", c); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("c", c, "container"); + DCHECK_TYPE("w", w, "widget"); - DRETURN_INT(p->active, DLEVEL_STABLE); + /* if this is an internal widget then we skip it as I'm assuming + * that everything internal is a grabber. Or, if there is only one + * element in the container we don't need a grabber */ + if ((ewl_widget_internal_is(w)) + || (ewl_container_child_count_get(c) == 1)) + DRETURN(DLEVEL_STABLE); + + /* create the required grabber */ + if (EWL_PANED(c)->orientation == EWL_ORIENTATION_HORIZONTAL) + { + o = ewl_vseparator_new(); + ewl_widget_appearance_set(o, "grabber/vertical"); + } + else + { + o = ewl_hseparator_new(); + ewl_widget_appearance_set(o, "grabber/horizontal"); + } + ewl_widget_internal_set(o, TRUE); + + ewl_callback_append(o, EWL_CALLBACK_MOUSE_DOWN, + ewl_paned_grabber_cb_mouse_down, c); + ewl_callback_append(o, EWL_CALLBACK_MOUSE_UP, + ewl_paned_grabber_cb_mouse_up, c); + ewl_callback_append(o, EWL_CALLBACK_MOUSE_IN, + ewl_paned_grabber_cb_mouse_in, c); + ewl_callback_append(o, EWL_CALLBACK_MOUSE_OUT, + ewl_paned_grabber_cb_mouse_out, c); + + idx = ewl_container_child_index_get(c, w); + ewl_container_child_insert(c, o, idx); + + /* only show the grabber if the widget is visible */ + if (VISIBLE(w)) + ewl_widget_show(o); + + DLEAVE_FUNCTION(DLEVEL_STABLE); } +/* The widget will already have been removed from the container. So, + * we have to take a look at the first child and see if it's + * internal, if so, remove it and done. Otherwise we have to walk the + * children and look for 2 internals beside each other and remove + * one of them. If that isnt' found and the last widget is internal + * then remove that. */ void -ewl_paned_configure_cb(Ewl_Widget *w, void *ev __UNUSED__, - void *user_data __UNUSED__) +ewl_paned_cb_child_remove(Ewl_Container *c, Ewl_Widget *w) +{ + Ewl_Widget *child, *prev = NULL, *last = NULL; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("c", c); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("c", c, "container"); + DCHECK_TYPE("w", w, "widget"); + + /* check first widget */ + child = ecore_list_goto_first(c->children); + + /* if there are no children remaining in the container we're done */ + if (!child) + DRETURN(DLEVEL_STABLE); + + /* try to find the node to remove */ + while ((child = ecore_list_current(c->children))) + { + if (ewl_widget_internal_is(child)) + { + /* the widget before us was internal so we can + * remove one of them */ + if (prev) + { + ecore_list_remove(c->children); + last = NULL; + break; + } + else + prev = child; + } + else + prev = NULL; + + last = child; + ecore_list_next(c->children); + } + + /* the last widget was internal we need to remove it */ + if (last && ewl_widget_internal_is(last)) + { + ecore_list_goto(c->children, last); + ecore_list_remove(c->children); + } + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +void +ewl_paned_cb_child_show(Ewl_Container *c, Ewl_Widget *w) +{ + int cw, ch, ww, wh; + Ewl_Widget *cur, *prev = NULL; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("c", c); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("c", c, "container"); + DCHECK_TYPE("w", w, "widget"); + + ewl_object_preferred_size_get(EWL_OBJECT(w), &ww, &wh); + ewl_object_preferred_inner_size_get(EWL_OBJECT(c), &cw, &ch); + + /* increase the containers perferred width by the preferred width of + * the shown widget (including the grabbers */ + if (EWL_PANED(c)->orientation == EWL_ORIENTATION_HORIZONTAL) + cw += ww; + else + ch += wh; + + ewl_object_preferred_inner_size_set(EWL_OBJECT(c), cw, ch); + + /* don't do anything for the internal widgets */ + if (ewl_widget_internal_is(w)) + DRETURN(DLEVEL_STABLE); + + /* show the grabber */ + ecore_list_goto_first(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (cur == w) + { + /* prev was visible so we need to make the next + * visible */ + if (!prev || VISIBLE(prev)) + { + prev = ecore_list_next(c->children); + if (prev) ewl_widget_show(prev); + } + else if (prev) + ewl_widget_show(prev); + + break; + } + prev = cur; + } + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +void +ewl_paned_cb_child_hide(Ewl_Container *c, Ewl_Widget *w) +{ + int cw, ch, ww, wh; + Ewl_Widget *cur, *prev = NULL; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("c", c); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("c", c, "container"); + DCHECK_TYPE("w", w, "widget"); + + ewl_object_preferred_size_get(EWL_OBJECT(w), &ww, &wh); + ewl_object_preferred_inner_size_get(EWL_OBJECT(c), &cw, &ch); + + /* decrease the containers perferred width by the preferred width of + * the hidden widget (including the grabbers */ + if (EWL_PANED(c)->orientation == EWL_ORIENTATION_HORIZONTAL) + cw -= ww; + else + ch -= wh; + + ewl_object_preferred_inner_size_set(EWL_OBJECT(c), cw, ch); + + /* don't do anything for internal widgets */ + if (ewl_widget_internal_is(w)) + DRETURN(DLEVEL_STABLE); + + /* hide the grabber */ + ecore_list_goto_first(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (cur == w) + { + /* prev was visible so we need to make the next + * visible */ + if (!prev || (!VISIBLE(prev))) + { + prev = ecore_list_next(c->children); + if (prev) + ewl_widget_hide(prev); + } + else if (prev) + ewl_widget_hide(prev); + break; + } + prev = cur; + } + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +/* this will size widgets as needed depending on where their grabber is. The + * widget can not be smaller then it's minimum size */ +void +ewl_paned_cb_configure(Ewl_Widget *w, void *ev, void *data) { - Ewl_Orientation o; Ewl_Paned *p; + Ewl_Widget *cur; DENTER_FUNCTION(DLEVEL_STABLE); DCHECK_PARAM_PTR("w", w); @@ -201,114 +401,519 @@ p = EWL_PANED(w); - /* - * Swap the orientation on the internal boxes if they are changed - */ - o = ewl_box_orientation_get(EWL_BOX(p)); - if (o == ewl_separator_orientation_get(EWL_SEPARATOR(p->grabber))) { - if (o == EWL_ORIENTATION_HORIZONTAL) { - ewl_separator_orientation_set(EWL_SEPARATOR(p->grabber), - EWL_ORIENTATION_VERTICAL); - } - else { - ewl_separator_orientation_set(EWL_SEPARATOR(p->grabber), - EWL_ORIENTATION_HORIZONTAL); + /* the easy one */ + if (ecore_list_is_empty(EWL_CONTAINER(w)->children)) + DRETURN(DLEVEL_STABLE); + + /* only one widget, give entire size */ + if (ecore_list_nodes(EWL_CONTAINER(w)->children) == 1) + { + cur = ecore_list_goto_first(EWL_CONTAINER(w)->children); + ewl_object_place(EWL_OBJECT(cur), CURRENT_X(p), CURRENT_Y(p), + CURRENT_W(p), CURRENT_H(p)); + DRETURN(DLEVEL_STABLE); + } + + if (p->orientation == EWL_ORIENTATION_HORIZONTAL) + ewl_paned_configure_horizontal(p); + else + ewl_paned_configure_vertical(p); + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +static void +ewl_paned_configure_horizontal(Ewl_Paned *p) +{ + Ewl_Widget *cur, *prev = NULL; + Ewl_Container *c; + int cur_pos, size, new_size, pos; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("p", p); + DCHECK_TYPE("p", p, "paned"); + + cur_pos = CURRENT_X(p); + size = CURRENT_W(p); + + c = EWL_CONTAINER(p); + + ecore_list_goto_first(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (!VISIBLE(cur)) continue; + + /* if we aren't internal then we're a pane, store us away + * and goto the next widget which _should_ be an internal + * grabber */ + if (!ewl_widget_internal_is(cur)) + { + prev = cur; + continue; + } + + /* the grabber is before the start of the pane, so we're + * assuming it hasn't been placed yet */ + if ((CURRENT_X(cur) < CURRENT_X(p))) + { + int panes, pane_size, grabbers, grab_size, i; + Ewl_Widget *skip; + + /* the previous widget and this grabber */ + panes = 1; + grabbers = 1; + grab_size = CURRENT_W(cur); + pane_size = 0; + skip = cur; + + while ((skip = ecore_list_next(c->children))) + { + if (!VISIBLE(skip)) continue; + if (!ewl_widget_internal_is(skip)) + { + panes ++; + continue; + } + + if ((CURRENT_X(skip) < CURRENT_X(p))) + { + grab_size += CURRENT_W(skip); + grabbers ++; + continue; + } + break; + } + + /* we have a grabber thats been placed, + * calculate the size per pane */ + if (skip) + pane_size = CURRENT_X(skip) - cur_pos; + else + pane_size = CURRENT_W(p) - cur_pos; + + pane_size -= grab_size; + pane_size /= panes; + + ecore_list_goto(c->children, prev); + i = 0; + while ((prev = ecore_list_next(c->children))) + { + if (ewl_widget_internal_is(prev)) + { + ewl_object_place(EWL_OBJECT(prev), + cur_pos, CURRENT_Y(p), + CURRENT_W(prev), + CURRENT_H(p)); + + cur_pos += CURRENT_W(prev); + } + else + { + ewl_object_place(EWL_OBJECT(prev), + cur_pos, CURRENT_Y(p), + pane_size, CURRENT_H(p)); + + cur_pos += pane_size; + } + + i++; + if (i == (panes + grabbers)) + break; + } + prev = NULL; + continue; } + + pos = ewl_object_current_x_get(EWL_OBJECT(cur)); + new_size = pos - cur_pos; + + ewl_object_place(EWL_OBJECT(prev), cur_pos, CURRENT_Y(p), + new_size, CURRENT_H(p)); + cur_pos += new_size; + + /* place the grabber and move to its left side */ + ewl_object_place(EWL_OBJECT(cur), cur_pos, CURRENT_Y(p), + CURRENT_W(cur), CURRENT_H(p)); + cur_pos += CURRENT_W(cur); + prev = NULL; + } + + /* if there is one left over, place it ... */ + if (prev) + { + int new_size; + new_size = size - cur_pos; + ewl_object_place(EWL_OBJECT(prev), cur_pos, CURRENT_Y(p), + new_size, CURRENT_H(p)); } DLEAVE_FUNCTION(DLEVEL_STABLE); } static void -ewl_paned_grabber_mouse_down_cb(Ewl_Widget *w __UNUSED__, void *ev __UNUSED__, - void *user_data) +ewl_paned_configure_vertical(Ewl_Paned *p) { - Ewl_Paned *p; + Ewl_Widget *cur, *prev = NULL; + Ewl_Container *c; + int cur_pos, size, new_size, pos; DENTER_FUNCTION(DLEVEL_STABLE); - DCHECK_PARAM_PTR("user_data", user_data); + DCHECK_PARAM_PTR("p", p); + DCHECK_TYPE("p", p, "paned"); + + cur_pos = CURRENT_Y(p); + size = CURRENT_H(p); + + c = EWL_CONTAINER(p); + + ecore_list_goto_first(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (!VISIBLE(cur)) continue; + + /* if we aren't internal then we're a pane, store us away + * and goto the next widget which _should_ be an internal + * grabber */ + if (!ewl_widget_internal_is(cur)) + { + prev = cur; + continue; + } + + /* the grabber is before the start of the pane, so we're + * assuming it hasn't been placed yet */ + if ((CURRENT_Y(cur) < CURRENT_Y(p))) + { + int panes, pane_size, grabbers, grab_size, i; + Ewl_Widget *skip; + + /* the previous widget and this grabber */ + panes = 1; + grabbers = 1; + grab_size = CURRENT_H(cur); + pane_size = 0; + skip = cur; + + while ((skip = ecore_list_next(c->children))) + { + if (!VISIBLE(skip)) continue; + if (!ewl_widget_internal_is(skip)) + { + panes ++; + continue; + } + + if ((CURRENT_Y(skip) < CURRENT_Y(p))) + { + grab_size += CURRENT_H(skip); + grabbers ++; + continue; + } + break; + } + + /* we have a grabber thats been placed, + * calculate the size per pane */ + if (skip) + pane_size = CURRENT_Y(skip) - cur_pos; + else + pane_size = CURRENT_H(p) - cur_pos; + + pane_size -= grab_size; + pane_size /= panes; + + ecore_list_goto(c->children, prev); + i = 0; + while ((prev = ecore_list_next(c->children))) + { + if (ewl_widget_internal_is(prev)) + { + ewl_object_place(EWL_OBJECT(prev), + CURRENT_X(p), cur_pos, + CURRENT_W(p), + CURRENT_H(prev)); + + cur_pos += CURRENT_H(prev); + } + else + { + ewl_object_place(EWL_OBJECT(prev), + CURRENT_X(p), cur_pos, + CURRENT_W(p), pane_size); + + cur_pos += pane_size; + } + + i++; + if (i == (panes + grabbers)) + break; + } + prev = NULL; + continue; + } + + pos = ewl_object_current_y_get(EWL_OBJECT(cur)); + new_size = pos - cur_pos; - p = EWL_PANED(user_data); - p->grabbed = TRUE; + ewl_object_place(EWL_OBJECT(prev), CURRENT_X(p), cur_pos, + CURRENT_H(p), new_size); + cur_pos += new_size; + + /* place the grabber and move to its left side */ + ewl_object_place(EWL_OBJECT(cur), CURRENT_Y(p), cur_pos, + CURRENT_W(p), CURRENT_H(cur)); + cur_pos += CURRENT_H(cur); + prev = NULL; + } + + /* if there is one left over, place it ... */ + if (prev) + { + int new_size; + new_size = size - cur_pos; + ewl_object_place(EWL_OBJECT(prev), CURRENT_Y(p), cur_pos, + CURRENT_W(p), new_size); + } DLEAVE_FUNCTION(DLEVEL_STABLE); } static void -ewl_paned_grabber_mouse_up_cb(Ewl_Widget *w __UNUSED__, void *ev __UNUSED__, - void *user_data) +ewl_paned_grabber_cb_mouse_down(Ewl_Widget *w, void *ev __UNUSED__, + void *data) { - Ewl_Paned *p; + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("w", w, "widget"); + ewl_callback_append(w, EWL_CALLBACK_MOUSE_MOVE, + ewl_paned_grabber_cb_mouse_move, data); + ewl_widget_state_set(w, "selected"); + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +static void +ewl_paned_grabber_cb_mouse_up(Ewl_Widget *w, void *ev __UNUSED__, + void *data) +{ DENTER_FUNCTION(DLEVEL_STABLE); - DCHECK_PARAM_PTR("user_data", user_data); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("w", w, "widget"); - p = EWL_PANED(user_data); - p->grabbed = FALSE; + ewl_callback_del(w, EWL_CALLBACK_MOUSE_MOVE, + ewl_paned_grabber_cb_mouse_move); + ewl_widget_state_set(w, "default"); DLEAVE_FUNCTION(DLEVEL_STABLE); } static void -ewl_paned_grabber_mouse_move_cb(Ewl_Widget *w __UNUSED__, void *ev, void *user_data) +ewl_paned_grabber_cb_mouse_move(Ewl_Widget *w, void *ev, void *data) { - Ewl_Paned *p = NULL; - Ewl_Event_Mouse_Move *mm = NULL; + Ewl_Paned *p; + Ewl_Event_Mouse_Move *e; DENTER_FUNCTION(DLEVEL_STABLE); - DCHECK_PARAM_PTR("ev", ev); - DCHECK_PARAM_PTR("user_data", user_data); - - p = EWL_PANED(user_data); - if (!p->grabbed) - DRETURN(DLEVEL_STABLE); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("w", w, "widget"); - mm = (Ewl_Event_Mouse_Move *)ev; - if (ewl_box_orientation_get(EWL_BOX(p)) == EWL_ORIENTATION_HORIZONTAL) { - int x = mm->x; - - // ewl_object_x_request(EWL_OBJECT(p->grabber), x); - if (mm->x > CURRENT_X(p) && mm->x < CURRENT_X(p) + CURRENT_W(p)) { - ewl_object_preferred_inner_w_set(EWL_OBJECT(p->first), - x); - } - - } else { - int y = mm->y; - - // ewl_object_y_request(EWL_OBJECT(p->grabber), y); - if (mm->y > CURRENT_Y(p) && mm->y < CURRENT_Y(p) + CURRENT_H(p)) { - ewl_object_preferred_inner_h_set(EWL_OBJECT(p->first), - y); - } + p = data; + e = ev; + + if (p->orientation == EWL_ORIENTATION_HORIZONTAL) + { + if ((e->x > CURRENT_X(p)) + && (e->x < (CURRENT_X(p) + CURRENT_W(p)))) + ewl_paned_grabber_horizontal_shift(p, w, e->x); + } + else + { + if ((e->y > CURRENT_Y(p)) + && (e->y < (CURRENT_Y(p) + CURRENT_H(p)))) + ewl_paned_grabber_vertical_shift(p, w, e->y); } - ewl_widget_configure(EWL_WIDGET(p)); + DLEAVE_FUNCTION(DLEVEL_STABLE); +} + +static void +ewl_paned_grabber_cb_mouse_in(Ewl_Widget *w, void *ev __UNUSED__, + void *data __UNUSED__) +{ + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("w", w, "widget"); + + /* XXX change cursor */ DLEAVE_FUNCTION(DLEVEL_STABLE); } static void -ewl_paned_grabber_mouse_in_cb(Ewl_Widget *w __UNUSED__, void *ev __UNUSED__, - void *user_data __UNUSED__) +ewl_paned_grabber_cb_mouse_out(Ewl_Widget *w, void *ev __UNUSED__, + void *data __UNUSED__) { DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("w", w, "widget"); - /* FIXME : Fiddle mouse pointer */ + /* XXX change cursor */ DLEAVE_FUNCTION(DLEVEL_STABLE); } static void -ewl_paned_grabber_mouse_out_cb(Ewl_Widget *w __UNUSED__, void *ev __UNUSED__, - void *user_data __UNUSED__) +ewl_paned_grabber_horizontal_shift(Ewl_Paned *p, Ewl_Widget *w, int to) { + Ewl_Container *c; + Ewl_Widget *before = NULL, *after = NULL, *cur; + int bx, ax, found = 0; + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("p", p); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("p", p, "paned"); + DCHECK_TYPE("w", w, "widget"); + + bx = CURRENT_X(p); + ax = CURRENT_X(p) + CURRENT_W(p); + + c = EWL_CONTAINER(p); + + ecore_list_goto_first(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (!ewl_widget_internal_is(cur)) + { + if (!found) before = cur; + else after = cur; + } + else + { + /* is this hte grabber we want? */ + if (cur == w) + found = 1; + else + { + if (!found) + bx = CURRENT_X(cur) + + CURRENT_W(cur); + else + { + ax = CURRENT_X(cur); + break; + } + } + } + } + + /* if we don't have a prev/next pane we're fucked */ + if (!before || !after) + { + DWARNING("Grabber but no panes beside it...\n"); + DRETURN(DLEVEL_STABLE); + } - /* FIXME : Un-fiddle mouse pointer */ + /* don't move to the left of the grabber to the left of us */ + if (to < (bx + CURRENT_W(before))) + to = bx + CURRENT_W(before); + + /* dont' move to the right of the grabber to the right of us */ + if (to > ax) + to = ax; + + /* XXX shoud check min widget sizes here */ + ewl_object_place(EWL_OBJECT(before), CURRENT_X(before), + CURRENT_Y(before), + to - (bx + CURRENT_W(before)), + CURRENT_H(before)); + + ewl_object_place(EWL_OBJECT(after), to + CURRENT_W(w), + CURRENT_Y(after), + ax - (to + CURRENT_W(w)), + CURRENT_H(after)); + + ewl_object_x_request(EWL_OBJECT(w), to); + ewl_widget_configure(EWL_WIDGET(p)); DLEAVE_FUNCTION(DLEVEL_STABLE); } +static void +ewl_paned_grabber_vertical_shift(Ewl_Paned *p, Ewl_Widget *w, int to) +{ + Ewl_Container *c; + Ewl_Widget *before = NULL, *after = NULL, *cur; + int by, ay, found = 0; + + DENTER_FUNCTION(DLEVEL_STABLE); + DCHECK_PARAM_PTR("p", p); + DCHECK_PARAM_PTR("w", w); + DCHECK_TYPE("p", p, "paned"); + DCHECK_TYPE("w", w, "widget"); + + by = CURRENT_Y(p); + ay = CURRENT_Y(p) + CURRENT_H(p); + + c = EWL_CONTAINER(p); + + ecore_list_goto_first(c->children); + while ((cur = ecore_list_next(c->children))) + { + if (!ewl_widget_internal_is(cur)) + { + if (!found) before = cur; + else after = cur; + } + else + { + /* is this hte grabber we want? */ + if (cur == w) + found = 1; + else + { + if (!found) + by = CURRENT_Y(cur) + + CURRENT_H(cur); + else + { + ay = CURRENT_Y(cur); + break; + } + } + } + } + + /* if we don't have a prev/next pane we're fucked */ + if (!before || !after) + { + DWARNING("Grabber but no panes beside it...\n"); + DRETURN(DLEVEL_STABLE); + } + + /* don't move above the grabber above us */ + if (to < (by + CURRENT_H(before))) + to = by + CURRENT_H(before); + + /* dont' move to the right of the grabber to the right of us */ + if (to > ay) + to = ay; + + /* XXX shoud check min widget sizes here */ + ewl_object_place(EWL_OBJECT(before), CURRENT_X(before), + CURRENT_Y(before), CURRENT_W(before), + to - (by + CURRENT_H(before))); + + ewl_object_place(EWL_OBJECT(after), CURRENT_X(after), + to + CURRENT_H(w), + CURRENT_W(after), + ay - (to + CURRENT_H(w))); + + ewl_object_y_request(EWL_OBJECT(w), to); + ewl_widget_configure(EWL_WIDGET(p)); + + DLEAVE_FUNCTION(DLEVEL_STABLE); +} =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_paned.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -3 -r1.7 -r1.8 --- ewl_paned.h 25 Oct 2005 00:59:46 -0000 1.7 +++ ewl_paned.h 28 Dec 2005 22:25:47 -0000 1.8 @@ -12,6 +12,10 @@ /** * @themekey /paned/file * @themekey /paned/group + * @themekey /grabber/vertical/file + * @themekey /grabber/vertical/group + * @themekey /grabber/horizontal/file + * @themekey /grabber/horizontal/group */ /** @@ -26,31 +30,33 @@ /** * @struct Ewl_Paned - * Inherits from Ewl_Widget and extends to provided the paned widget + * Inherits from Ewl_Container and extends to provided the paned widget */ struct Ewl_Paned { - Ewl_Box base; - Ewl_Box *first; - Ewl_Widget *grabber; - Ewl_Box *second; - Ewl_Position active; - Ewl_Orientation orientation; - int grabbed; + Ewl_Container container; + Ewl_Orientation orientation; }; -Ewl_Widget *ewl_paned_new(void); -Ewl_Widget *ewl_hpaned_new(void); -Ewl_Widget *ewl_vpaned_new(void); -int ewl_paned_init(Ewl_Paned *p); +Ewl_Widget *ewl_paned_new(void); +Ewl_Widget *ewl_hpaned_new(void); +Ewl_Widget *ewl_vpaned_new(void); +int ewl_paned_init(Ewl_Paned *p); + +void ewl_paned_orientation_set(Ewl_Paned *p, Ewl_Orientation o); +Ewl_Orientation ewl_paned_orientation_get(Ewl_Paned *p); + +/* + * Internal functions. Override at your risk. + */ +void ewl_paned_cb_child_add(Ewl_Container *c, Ewl_Widget *w); +void ewl_paned_cb_child_remove(Ewl_Container *c, Ewl_Widget *w); +void ewl_paned_cb_child_resize(Ewl_Container *c, Ewl_Widget *w, int size, + Ewl_Orientation o); +void ewl_paned_cb_child_show(Ewl_Container *c, Ewl_Widget *w); +void ewl_paned_cb_child_hide(Ewl_Container *c, Ewl_Widget *w); -void ewl_paned_active_area_set(Ewl_Paned *p, Ewl_Position pos); -Ewl_Position ewl_paned_active_area_get(Ewl_Paned *p); - -/* - * Internally used callbacks, override at your own risk. - */ -void ewl_paned_configure_cb(Ewl_Widget *w, void *ev, void *user_data); +void ewl_paned_cb_configure(Ewl_Widget *w, void *ev, void *data); /** * @} ------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Do you grep through log files for problems? Stop! Download the new AJAX search engine that makes searching your log files as easy as surfing the web. DOWNLOAD SPLUNK! http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs