From: Enlightenment C. <no...@cv...> - 2006-12-26 14:51:32
|
Enlightenment CVS committal Author : moom Project : e17 Module : proto Dir : e17/proto/etk/src/lib Modified Files: etk_spinner.c etk_spinner.h etk_tree2.c etk_tree2.h etk_utils.h etk_widget.c Log Message: Lib: ---- * [Spinner] The spinner is now completely done. It may need some theming though... * [Tree2] More work! Theme: ------ * [Tree2] Improve the theme of the tree2's headers Misc: ----- * [Documentation] More doc =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_spinner.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- etk_spinner.c 19 Dec 2006 21:43:50 -0000 1.3 +++ etk_spinner.c 26 Dec 2006 14:51:23 -0000 1.4 @@ -22,7 +22,9 @@ enum Etk_Spinner_Propery_Id { - ETK_SPINNER_DIGITS_PROPERTY + ETK_SPINNER_DIGITS_PROPERTY, + ETK_SPINNER_SNAP_TO_TICKS_PROPERTY, + ETK_SPINNER_WRAP_PROPERTY }; static void _etk_spinner_constructor(Etk_Spinner *spinner); @@ -35,6 +37,7 @@ static void _etk_spinner_unfocus_cb(Etk_Object *object, void *data); static void _etk_spinner_key_down_cb(Etk_Object *object, Etk_Event_Key_Down *event, void *data); +static void _etk_spinner_key_up_cb(Etk_Object *object, Etk_Event_Key_Up *event, void *data); static void _etk_spinner_editable_mouse_in_cb(void *data, Evas *evas, Evas_Object *object, void *event_info); static void _etk_spinner_editable_mouse_out_cb(void *data, Evas *evas, Evas_Object *object, void *event_info); static void _etk_spinner_editable_mouse_down_cb(void *data, Evas *evas, Evas_Object *object, void *event_info); @@ -43,6 +46,7 @@ static void _etk_spinner_selection_received_cb(Etk_Object *object, void *event, void *data); static void _etk_spinner_value_changed_handler(Etk_Range *range, double value); +static void _etk_spinner_step_increment_changed_cb(Etk_Object *object, const char *property_name, void *data); static void _etk_spinner_step_start_cb(void *data, Evas_Object *obj, const char *emission, const char *source); static void _etk_spinner_step_stop_cb(void *data, Evas_Object *obj, const char *emission, const char *source); @@ -51,8 +55,11 @@ static void _etk_spinner_update_text_from_value(Etk_Spinner *spinner); static void _etk_spinner_update_value_from_text(Etk_Spinner *spinner); +static void _etk_spinner_spin(Etk_Spinner *spinner, double increment); +static double _etk_spinner_value_snap(Etk_Spinner *spinner, double value); static void _etk_spinner_selection_copy(Etk_Spinner *spinner, Etk_Selection_Type selection, Etk_Bool cut); + /************************** * * Implementation @@ -75,6 +82,10 @@ etk_type_property_add(spinner_type, "digits", ETK_SPINNER_DIGITS_PROPERTY, ETK_PROPERTY_INT, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_int(0)); + etk_type_property_add(spinner_type, "snap_to_ticks", ETK_SPINNER_SNAP_TO_TICKS_PROPERTY, + ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_bool(ETK_FALSE)); + etk_type_property_add(spinner_type, "wrap", ETK_SPINNER_WRAP_PROPERTY, + ETK_PROPERTY_BOOL, ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_bool(ETK_FALSE)); spinner_type->property_set = _etk_spinner_property_set; spinner_type->property_get = _etk_spinner_property_get; @@ -85,6 +96,11 @@ /** * @brief Creates a new spinner + * @param lower the minimal value of the spinner + * @param upper the maximal value of the spinner + * @param value the value to set to the spinner + * @param step_increment specifies by how much the value should be changed when an arrow is clicked + * @param page_increment specifies by how much the value should be changed when the "page down/up" keys are pressed * @return Returns the new spinner widget */ Etk_Widget *etk_spinner_new(double lower, double upper, double value, double step_increment, double page_increment) @@ -124,6 +140,70 @@ return spinner->digits; } +/** + * @brief Sets whether or not the value of the spinner should be automatically + * corrected to the nearest step-increment + * @param spinner a spinner + * @param snap_to_ticks ETK_TRUE if you want the value to be corrected, ETK_FALSE otherwise + */ +void etk_spinner_snap_to_ticks_set(Etk_Spinner *spinner, Etk_Bool snap_to_ticks) +{ + if (!spinner || spinner->snap_to_ticks == snap_to_ticks) + return; + + spinner->snap_to_ticks = snap_to_ticks; + + if (snap_to_ticks) + { + double new_value; + + new_value = _etk_spinner_value_snap(spinner, etk_range_value_get(ETK_RANGE(spinner))); + etk_range_value_set(ETK_RANGE(spinner), new_value); + } + etk_object_notify(ETK_OBJECT(spinner), "snap_to_ticks"); +} + +/** + * @brief Gets whether or not the value of the spinner are automatically + * corrected to the nearest step-increment + * @param spinner a spinner + * @return Returns ETK_TRUE if the value is automatically corrected, ETK_FALSE otherwise + */ +Etk_Bool etk_spinner_snap_to_ticks_get(Etk_Spinner *spinner) +{ + if (!spinner) + return ETK_FALSE; + return spinner->snap_to_ticks; +} + +/** + * @brief Sets whether or not the spinner's value should wrap around to the opposite limit when the value exceed one + * of the spinner's bounds + * @param spinner a spinner + * @param wrap ETK_TRUE to make the value wrap around, ETK_FALSE otherwise + */ +void etk_spinner_wrap_set(Etk_Spinner *spinner, Etk_Bool wrap) +{ + if (!spinner || spinner->wrap == wrap) + return; + + spinner->wrap = wrap; + etk_object_notify(ETK_OBJECT(spinner), "wrap"); +} + +/** + * @brief Gets whether or not the spinner's value is wrapped around to the opposite limit when the value exceed one + * of the spinner's bounds + * @param spinner a spinner + * @return Returns ETK_TRUE if the spinner's value is wrapped around, ETK_FALSE otherwise + */ +Etk_Bool etk_spinner_wrap_get(Etk_Spinner *spinner) +{ + if (!spinner) + return ETK_FALSE; + return spinner->wrap; +} + /************************** * * Etk specific functions @@ -138,6 +218,9 @@ spinner->digits = 0; strcpy(spinner->value_format, "%.0f"); + spinner->snap_to_ticks = ETK_FALSE; + spinner->wrap = ETK_FALSE; + spinner->step_timer = NULL; spinner->successive_steps = 0; @@ -148,10 +231,13 @@ etk_signal_connect("realize", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_realize_cb), NULL); etk_signal_connect("unrealize", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_unrealize_cb), NULL); etk_signal_connect("key_down", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_key_down_cb), NULL); + etk_signal_connect("key_up", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_key_up_cb), NULL); etk_signal_connect("focus", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_focus_cb), NULL); etk_signal_connect("unfocus", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_unfocus_cb), NULL); etk_signal_connect("selection_received", ETK_OBJECT(spinner), ETK_CALLBACK(_etk_spinner_selection_received_cb), NULL); + etk_object_notification_callback_add(ETK_OBJECT(spinner), "step_increment", + _etk_spinner_step_increment_changed_cb, NULL); } /* Sets the property whose id is "property_id" to the value "value" */ @@ -167,6 +253,12 @@ case ETK_SPINNER_DIGITS_PROPERTY: etk_spinner_digits_set(spinner, etk_property_value_int_get(value)); break; + case ETK_SPINNER_SNAP_TO_TICKS_PROPERTY: + etk_spinner_snap_to_ticks_set(spinner, etk_property_value_bool_get(value)); + break; + case ETK_SPINNER_WRAP_PROPERTY: + etk_spinner_wrap_set(spinner, etk_property_value_bool_get(value)); + break; default: break; } @@ -185,6 +277,12 @@ case ETK_SPINNER_DIGITS_PROPERTY: etk_property_value_int_set(value, spinner->digits); break; + case ETK_SPINNER_SNAP_TO_TICKS_PROPERTY: + etk_property_value_bool_set(value, spinner->snap_to_ticks); + break; + case ETK_SPINNER_WRAP_PROPERTY: + etk_property_value_bool_set(value, spinner->wrap); + break; default: break; } @@ -291,6 +389,7 @@ Evas_Object *editable; int cursor_pos, selection_pos; int start_pos, end_pos; + int climb_factor; Etk_Bool selecting; Etk_Bool changed = ETK_FALSE; Etk_Bool selection_changed = ETK_FALSE; @@ -307,6 +406,9 @@ end_pos = ETK_MAX(cursor_pos, selection_pos); selecting = (start_pos != end_pos); + /* TODO: increment faster if the key has been pressed for a long time... */ + climb_factor = 1; + /* Move the cursor/selection to the left */ if (strcmp(event->keyname, "Left") == 0) { @@ -386,18 +488,28 @@ /* Increment the value */ else if (strcmp(event->keyname, "Up") == 0) { - /* TODO: increment faster if the key has been pressed for a long time... */ - etk_range_value_set(range, range->value + range->step_increment); + _etk_spinner_spin(spinner, climb_factor * range->step_increment); } /* Decrement the value */ else if (strcmp(event->keyname, "Down") == 0) { - /* TODO: decrement faster if the key has been pressed for a long time... */ - etk_range_value_set(range, range->value - range->step_increment); + _etk_spinner_spin(spinner, -(climb_factor * range->step_increment)); + } + /* Increment the value by the page-increment */ + else if (strcmp(event->keyname, "Prior") == 0) + { + _etk_spinner_spin(spinner, climb_factor * range->page_increment); + } + /* Decrement the value by the page-increment */ + else if (strcmp(event->keyname, "Next") == 0) + { + _etk_spinner_spin(spinner, -(climb_factor * range->page_increment)); } /* Validate the value entered in the spinner */ else if (strcmp(event->keyname, "Return") == 0 || strcmp(event->keyname, "KP_Enter") == 0) + { _etk_spinner_update_value_from_text(spinner); + } /* Ctrl + A,C,X,V */ else if (event->modifiers & ETK_MODIFIER_CTRL) { @@ -429,6 +541,21 @@ etk_signal_stop(); } +/* Called when a key is released while the spinner is focused */ +static void _etk_spinner_key_up_cb(Etk_Object *object, Etk_Event_Key_Up *event, void *data) +{ + Etk_Spinner *spinner; + + if (!(spinner = ETK_SPINNER(object))) + return; + + if (strcmp(event->keyname, "Prior") == 0 || strcmp(event->keyname, "Next") == 0 + || strcmp(event->keyname, "Up") == 0 || strcmp(event->keyname, "Down") == 0) + { + spinner->successive_steps = 0; + } +} + /* Called when the mouse enters the spinner's editable-object */ static void _etk_spinner_editable_mouse_in_cb(void *data, Evas *evas, Evas_Object *object, void *event_info) { @@ -559,10 +686,38 @@ if (!(spinner = ETK_SPINNER(range))) return; + + if (spinner->snap_to_ticks) + { + double new_value; + + new_value = _etk_spinner_value_snap(spinner, value); + if (value != range->lower && value != range->upper && value != value) + etk_range_value_set(ETK_RANGE(spinner), new_value); + } + _etk_spinner_update_text_from_value(spinner); } -/* TODOC */ +/* Called when the step-increment of the spinner is changed: + * We correct the value if the "snap-to-ticks" setting is on */ +static void _etk_spinner_step_increment_changed_cb(Etk_Object *object, const char *property_name, void *data) +{ + Etk_Spinner *spinner; + double value; + + if (!(spinner = ETK_SPINNER(object))) + return; + + if (spinner->snap_to_ticks) + { + value = etk_range_value_get(ETK_RANGE(spinner)); + value = _etk_spinner_value_snap(spinner, value); + etk_range_value_set(ETK_RANGE(spinner), value); + } +} + +/* Called when one of the arrows is pressed: it starts to increment or decrement the value */ static void _etk_spinner_step_start_cb(void *data, Evas_Object *obj, const char *emission, const char *source) { Etk_Spinner *spinner; @@ -583,7 +738,7 @@ spinner->step_timer = ecore_timer_add(0.0, _etk_spinner_step_increment_timer_cb, spinner); } -/* TODOC */ +/* Called when one of the arrows is released: it stops incrementing or decrementing the value */ static void _etk_spinner_step_stop_cb(void *data, Evas_Object *obj, const char *emission, const char *source) { Etk_Spinner *spinner; @@ -598,42 +753,34 @@ } } -/* TODOC */ +/* A timer used to decrement the value */ static int _etk_spinner_step_decrement_timer_cb(void *data) { Etk_Spinner *spinner; - Etk_Range *range; if (!(spinner = ETK_SPINNER(data))) return 1; _etk_spinner_update_value_from_text(spinner); - range = ETK_RANGE(spinner); - etk_range_value_set(range, range->value - range->step_increment); - ecore_timer_interval_set(spinner->step_timer, (spinner->successive_steps == 0) ? FIRST_DELAY : REPEAT_DELAY); - spinner->successive_steps++; + _etk_spinner_spin(spinner, -ETK_RANGE(spinner)->step_increment); return 1; } -/* TODOC */ +/* A timer used to increment the value */ static int _etk_spinner_step_increment_timer_cb(void *data) { Etk_Spinner *spinner; - Etk_Range *range; if (!(spinner = ETK_SPINNER(data))) return 1; _etk_spinner_update_value_from_text(spinner); - range = ETK_RANGE(spinner); - etk_range_value_set(range, range->value + range->step_increment); - ecore_timer_interval_set(spinner->step_timer, (spinner->successive_steps == 0) ? FIRST_DELAY : REPEAT_DELAY); - spinner->successive_steps++; + _etk_spinner_spin(spinner, ETK_RANGE(spinner)->step_increment); return 1; } @@ -668,7 +815,55 @@ text = etk_editable_text_get(spinner->editable_object); if (sscanf(text, "%f", &value) != 1) value = 0.0; - etk_range_value_set(ETK_RANGE(spinner), value); + + if (spinner->snap_to_ticks) + value = _etk_spinner_value_snap(spinner, value); + + if (etk_range_value_get(ETK_RANGE(spinner)) != value) + etk_range_value_set(ETK_RANGE(spinner), value); + else + _etk_spinner_update_text_from_value(spinner); +} + +/* Increases the spinner's value by "increment" */ +static void _etk_spinner_spin(Etk_Spinner *spinner, double increment) +{ + Etk_Range *range; + double value; + + if (!(range = ETK_RANGE(spinner))) + return; + + if (spinner->wrap) + { + if (range->value == range->lower && increment < 0) + value = range->upper; + else if (range->value == range->upper && increment > 0) + value = range->lower; + else + value = range->value + increment; + } + else + value = range->value + increment; + + if (spinner->snap_to_ticks) + value = _etk_spinner_value_snap(spinner, value); + + etk_range_value_set(range, value); + spinner->successive_steps++; +} + +/* Gets the value corrected to the nearest step-increment */ +static double _etk_spinner_value_snap(Etk_Spinner *spinner, double value) +{ + Etk_Range *range; + int factor; + + if (!(range = ETK_RANGE(spinner))) + return 0.0; + + factor = ETK_ROUND(value / range->step_increment); + return range->step_increment * factor; } /* Copies the selected text of the spinner to the given selection */ @@ -714,5 +909,40 @@ /** * @addtogroup Etk_Spinner * - * TODOC + * @image html widgets/spinner.png + * The user can either type the value in the entry, or use the arrows to increment or decrement the value. @n + * The spinner's value can be automatically corrected to the nearest step-increment if you set the @a "snap_to_ticks" + * property to ETK_TRUE with etk_spinner_snap_to_ticks_set(). It may be useful if you only want integer values for + * example. @n + * The spinner's value can also automatically wrap around to the opposite limit when it exceeds one of the spinner's + * bounds. This setting can be set with etk_spinner_wrap_set(). @n + * + * Since Etk_Spinner inherits from Etk_Range, you can be notified when the value is changed with the signal + * @a "value_changed". You can also call etk_range_value_set() and etk_range_value_get() to set or get the value of the + * spinner. + * + * + * \par Object Hierarchy: + * - Etk_Object + * - Etk_Widget + * - Etk_Range + * - Etk_Spinner + * + * \par Properties: + * @prop_name "digits": The number of digits the spinner should display + * @prop_type Integer + * @prop_rw + * @prop_val 0 + * \par + * @prop_name "snap_to_ticks": Whether or not the value of the spinner should be corrected + * to the nearest step-increment + * @prop_type Boolean + * @prop_rw + * @prop_val ETK_FALSE + * \par + * @prop_name "wrap": Whether or not the spinner's value wraps around to the opposite limit when + * it exceeds one of the spinner's bounds + * @prop_type Boolean + * @prop_rw + * @prop_val ETK_FALSE */ =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_spinner.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- etk_spinner.h 28 Nov 2006 21:40:07 -0000 1.1 +++ etk_spinner.h 26 Dec 2006 14:51:23 -0000 1.2 @@ -8,7 +8,7 @@ /** * @defgroup Etk_Spinner Etk_Spinner - * @brief TODOC + * @brief A spinner is a widget that allows the user to set the value of a setting * @{ */ @@ -20,7 +20,7 @@ #define ETK_IS_SPINNER(obj) (ETK_OBJECT_CHECK_TYPE((obj), ETK_SPINNER_TYPE)) /** - * @brief @widget TODOC + * @brief @widget A widget that allows the user to set the value of a setting * @structinfo */ struct Etk_Spinner @@ -34,6 +34,9 @@ int digits; char value_format[16]; + Etk_Bool snap_to_ticks; + Etk_Bool wrap; + int successive_steps; Ecore_Timer *step_timer; }; @@ -42,8 +45,12 @@ Etk_Type *etk_spinner_type_get(); Etk_Widget *etk_spinner_new(double lower, double upper, double value, double step_increment, double page_increment); -void etk_spinner_digits_set(Etk_Spinner *spinner, int digits); -int etk_spinner_digits_get(Etk_Spinner *spinner); +void etk_spinner_digits_set(Etk_Spinner *spinner, int digits); +int etk_spinner_digits_get(Etk_Spinner *spinner); +void etk_spinner_snap_to_ticks_set(Etk_Spinner *spinner, Etk_Bool snap_to_ticks); +Etk_Bool etk_spinner_snap_to_ticks_get(Etk_Spinner *spinner); +void etk_spinner_wrap_set(Etk_Spinner *spinner, Etk_Bool wrap); +Etk_Bool etk_spinner_wrap_get(Etk_Spinner *spinner); /** @} */ =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_tree2.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- etk_tree2.c 10 Dec 2006 12:52:52 -0000 1.3 +++ etk_tree2.c 26 Dec 2006 14:51:23 -0000 1.4 @@ -18,7 +18,8 @@ * @{ */ -#define TREE_GET(widget) ETK_TREE2(etk_object_data_get(ETK_OBJECT(widget), "_Etk_Tree2::Tree")) +#define TREE_GET(widget) \ + ETK_TREE2(etk_object_data_get(ETK_OBJECT(widget), "_Etk_Tree2::Tree")) #define COL_MIN_WIDTH 24 #define COL_RESIZE_THRESHOLD 3 @@ -90,7 +91,6 @@ static void _etk_tree2_size_request(Etk_Widget *widget, Etk_Size *size); static void _etk_tree2_size_allocate(Etk_Widget *widget, Etk_Geometry geometry); static void _etk_tree2_realize_cb(Etk_Object *object, void *data); -static void _etk_tree2_unrealize_cb(Etk_Object *object, void *data); static void _etk_tree2_col_constructor(Etk_Tree2_Col *tree_col); static void _etk_tree2_col_destructor(Etk_Tree2_Col *tree_col); @@ -107,8 +107,6 @@ static void _etk_tree2_focus_cb(Etk_Object *object, void *event, void *data); static void _etk_tree2_unfocus_cb(Etk_Object *object, void *event, void *data); static void _etk_tree2_key_down_cb(Etk_Object *object, Etk_Event_Key_Down *event, void *data); -static void _etk_tree2_scroll_content_realize_cb(Etk_Object *object, void *data); -static void _etk_tree2_scroll_content_unrealize_cb(Etk_Object *object, void *data); static void _etk_tree2_grid_realize_cb(Etk_Object *object, void *data); static void _etk_tree2_grid_unrealize_cb(Etk_Object *object, void *data); @@ -468,8 +466,6 @@ etk_widget_parent_set(new_header, ETK_WIDGET(tree)); else etk_widget_parent_set(new_header, tree->scroll_content); - if (tree->headers_clip) - etk_widget_clip_set(new_header, tree->headers_clip); new_col->header = new_header; etk_signal_connect("mouse_down", ETK_OBJECT(new_header), ETK_CALLBACK(_etk_tree2_header_mouse_down_cb), new_col); @@ -806,7 +802,7 @@ } /** - * @param Inserts a new row after an existing row + * @brief Inserts a new row after an existing row * @param tree a tree * @param parent the parent row of the row to insert. If @a after is not NULL, @a parent is optionnal (the parent of the * new row will be the parent of @a after) @@ -833,7 +829,7 @@ } /** - * @param Inserts a new row after an existing row + * @brief Inserts a new row after an existing row * @param tree a tree * @param parent the parent row of the row to insert. If @a after is not NULL, @a parent is optionnal (the parent of the * new row will be the parent of @a after) @@ -1399,10 +1395,6 @@ tree->scroll_content->size_allocate = _etk_tree2_scroll_content_size_allocate; tree->scroll_content->scroll = _etk_tree2_scroll_content_scroll; tree->scroll_content->scroll_size_get = _etk_tree2_scroll_content_scroll_size_get; - etk_signal_connect("realize", ETK_OBJECT(tree->scroll_content), - ETK_CALLBACK(_etk_tree2_scroll_content_realize_cb), NULL); - etk_signal_connect("unrealize", ETK_OBJECT(tree->scroll_content), - ETK_CALLBACK(_etk_tree2_scroll_content_unrealize_cb), NULL); tree->grid = etk_widget_new(ETK_WIDGET_TYPE, "theme_group", "grid", "theme_parent", tree, "repeat_mouse_events", ETK_TRUE, "internal", ETK_TRUE, "visible", ETK_TRUE, NULL); @@ -1418,7 +1410,6 @@ tree->columns = NULL; tree->col_to_resize = NULL; tree->headers_visible = ETK_TRUE; - tree->headers_clip = NULL; tree->grid_clip = NULL; tree->root.tree = tree; @@ -1458,7 +1449,6 @@ ETK_WIDGET(tree)->size_allocate = _etk_tree2_size_allocate; etk_signal_connect("realize", ETK_OBJECT(tree), ETK_CALLBACK(_etk_tree2_realize_cb), NULL); - etk_signal_connect("unrealize", ETK_OBJECT(tree), ETK_CALLBACK(_etk_tree2_unrealize_cb), NULL); etk_signal_connect("focus", ETK_OBJECT(tree), ETK_CALLBACK(_etk_tree2_focus_cb), NULL); etk_signal_connect("unfocus", ETK_OBJECT(tree), ETK_CALLBACK(_etk_tree2_unfocus_cb), NULL); etk_signal_connect("key_down", ETK_OBJECT(tree), ETK_CALLBACK(_etk_tree2_key_down_cb), NULL); @@ -1721,12 +1711,19 @@ Etk_Geometry header_bar_geometry; int header_bar_xoffset; + etk_widget_inner_geometry_get(tree->grid, &header_bar_geometry.x, NULL, &header_bar_geometry.w, NULL); + header_bar_geometry.y = geometry.y; + header_bar_geometry.h = geometry.h; + header_bar_xoffset = header_bar_geometry.x - geometry.x; + first_visible_col = NULL; last_visible_col = NULL; for (i = 0; i < tree->num_cols; i++) { col = tree->columns[i]; - if (col->visible) + if (col->visible + && header_bar_geometry.x + col->xoffset <= geometry.x + geometry.w + && header_bar_geometry.x + col->xoffset + col->visible_width >= geometry.x) { if (!first_visible_col || first_visible_col->position > col->position) first_visible_col = col; @@ -1735,39 +1732,47 @@ } } - etk_widget_inner_geometry_get(tree->grid, &header_bar_geometry.x, NULL, &header_bar_geometry.w, NULL); - header_bar_geometry.y = geometry.y; - header_bar_geometry.h = geometry.h; - header_bar_xoffset = header_bar_geometry.x - geometry.x; - header_geometry.y = header_bar_geometry.y; header_geometry.h = header_bar_geometry.h; for (i = 0; i < tree->num_cols; i++) { - header_geometry.x = header_bar_geometry.x + tree->columns[i]->xoffset; - header_geometry.w = tree->columns[i]->visible_width; - if (tree->columns[i] == first_visible_col) + if (tree->columns[i]->visible + && first_visible_col->position <= tree->columns[i]->position + && last_visible_col->position >= tree->columns[i]->position) { - header_geometry.x -= header_bar_xoffset; - header_geometry.w += header_bar_xoffset; + header_geometry.x = header_bar_geometry.x + tree->columns[i]->xoffset; + header_geometry.w = tree->columns[i]->visible_width; + if (tree->columns[i] == first_visible_col) + { + header_geometry.w += (header_geometry.x - geometry.x); + header_geometry.x = geometry.x; + } + if (tree->columns[i] == last_visible_col) + header_geometry.w = geometry.x + geometry.w - header_geometry.x; + + /* TODO: what if the group doesn't exist... */ + if (tree->columns[i] == first_visible_col && tree->columns[i] == last_visible_col) + etk_widget_theme_group_set(tree->columns[i]->header, "header_unique"); + else if (tree->columns[i] == first_visible_col) + etk_widget_theme_group_set(tree->columns[i]->header, "header_first"); + else if (tree->columns[i] == last_visible_col) + etk_widget_theme_group_set(tree->columns[i]->header, "header_last"); + else + etk_widget_theme_group_set(tree->columns[i]->header, "header"); + + etk_widget_show(tree->columns[i]->header); + etk_widget_raise(tree->columns[i]->header); + etk_widget_size_allocate(tree->columns[i]->header, header_geometry); } - if (tree->columns[i] == last_visible_col) - header_geometry.w += (geometry.x + geometry.w) - (header_bar_geometry.x + header_bar_geometry.w); - - etk_widget_show(tree->columns[i]->header); - etk_widget_size_allocate(tree->columns[i]->header, header_geometry); + else + etk_widget_hide(tree->columns[i]->header); } - - evas_object_show(tree->headers_clip); - evas_object_move(tree->headers_clip, geometry.x, geometry.y); - evas_object_resize(tree->headers_clip, geometry.w, geometry.h); } else { for (i = 0; i < tree->num_cols; i++) etk_widget_hide(tree->columns[i]->header); - evas_object_hide(tree->headers_clip); } } @@ -2212,31 +2217,6 @@ } tree->tree_contains_headers = (tree_contains_headers != 0); } - - /* Clip the column headers */ - if (tree->tree_contains_headers) - { - if (tree->headers_clip) - evas_object_del(tree->headers_clip); - tree->headers_clip = evas_object_rectangle_add(evas); - evas_object_show(tree->headers_clip); - etk_widget_member_object_add(ETK_WIDGET(tree), tree->headers_clip); - - for (i = 0; i < tree->num_cols; i++) - etk_widget_clip_set(tree->columns[i]->header, tree->headers_clip); - } -} - -/* Called when the tree is unrealized */ -static void _etk_tree2_unrealize_cb(Etk_Object *object, void *data) -{ - Etk_Tree2 *tree; - - if (!(tree = ETK_TREE2(object))) - return; - - if (tree->tree_contains_headers) - tree->headers_clip = NULL; } /* Called when the tree is focused */ @@ -2286,46 +2266,6 @@ } /************************** - * Tree Scroll Content - **************************/ - -/* Called when the scroll-content widget is realized */ -static void _etk_tree2_scroll_content_realize_cb(Etk_Object *object, void *data) -{ - Etk_Tree2 *tree; - Evas *evas; - int i; - - if (!(tree = TREE_GET(object)) || !(evas = etk_widget_toplevel_evas_get(tree->scroll_content))) - return; - - /* Clip the column headers */ - if (!tree->tree_contains_headers) - { - if (tree->headers_clip) - evas_object_del(tree->headers_clip); - tree->headers_clip = evas_object_rectangle_add(evas); - evas_object_show(tree->headers_clip); - etk_widget_member_object_add(tree->scroll_content, tree->headers_clip); - - for (i = 0; i < tree->num_cols; i++) - etk_widget_clip_set(tree->columns[i]->header, tree->headers_clip); - } -} - -/* Called when the scroll-content widget is unrealized */ -static void _etk_tree2_scroll_content_unrealize_cb(Etk_Object *object, void *data) -{ - Etk_Tree2 *tree; - - if (!(tree = TREE_GET(object))) - return; - - if (!tree->tree_contains_headers) - tree->headers_clip = NULL; -} - -/************************** * Tree Grid **************************/ @@ -2388,6 +2328,7 @@ { col->tree->col_resize_orig_width = col->tree->col_to_resize->width; col->tree->col_resize_orig_mouse_x = event->canvas.x; + etk_signal_stop(); } } =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_tree2.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- etk_tree2.h 10 Dec 2006 12:52:52 -0000 1.3 +++ etk_tree2.h 26 Dec 2006 14:51:23 -0000 1.4 @@ -118,7 +118,6 @@ int col_resize_orig_width; int col_resize_orig_mouse_x; Etk_Bool headers_visible; - Evas_Object *headers_clip; Evas_Object *grid_clip; int total_rows; =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_utils.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -3 -r1.13 -r1.14 --- etk_utils.h 5 Sep 2006 00:14:57 -0000 1.13 +++ etk_utils.h 26 Dec 2006 14:51:23 -0000 1.14 @@ -3,6 +3,7 @@ #define _ETK_UTILS_H_ #include <stdio.h> +#include <math.h> #include <libintl.h> /** =================================================================== RCS file: /cvs/e/e17/proto/etk/src/lib/etk_widget.c,v retrieving revision 1.87 retrieving revision 1.88 diff -u -3 -r1.87 -r1.88 --- etk_widget.c 28 Nov 2006 21:40:07 -0000 1.87 +++ etk_widget.c 26 Dec 2006 14:51:23 -0000 1.88 @@ -460,7 +460,8 @@ if (!widget) return; - if (theme_group != widget->theme_group) + if (theme_group != widget->theme_group + && !(widget->theme_group && theme_group && strcmp(widget->theme_group, theme_group) == 0)) { free(widget->theme_group); widget->theme_group = theme_group ? strdup(theme_group) : NULL; |