Enlightenment CVS committal

Author  : moom16
Project : e17
Module  : proto

Dir     : e17/proto/etk/src/lib


Modified Files:
        Etk.h Makefile.am etk_range.c etk_range.h etk_scrollbar.c 
        etk_scrollbar.h etk_types.h etk_widget.c etk_widget.h 
Added Files:
        etk_viewport.c etk_viewport.h 


Log Message:
* Clip the watermark in the tree theme
* Rewrite the scrollbar to take profit of the drag features of edje
* Add the ability to clip a widget against an evas object
* Add a scrolled view!!! :)
* Add a viewport to make every widgets scrollable


===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/Etk.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- Etk.h       30 Oct 2005 10:25:25 -0000      1.6
+++ Etk.h       31 Oct 2005 21:36:40 -0000      1.7
@@ -25,6 +25,8 @@
 #include "etk_alignment.h"
 #include "etk_frame.h"
 #include "etk_paned.h"
+#include "etk_scrolled_view.h"
+#include "etk_viewport.h"
 #include "etk_window.h"
 #include "etk_label.h"
 #include "etk_image.h"
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/Makefile.am,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -3 -r1.9 -r1.10
--- Makefile.am 30 Oct 2005 10:25:25 -0000      1.9
+++ Makefile.am 31 Oct 2005 21:36:40 -0000      1.10
@@ -23,6 +23,7 @@
 etk_container.h etk_bin.h etk_table.h etk_alignment.h \
 etk_box.h etk_hbox.h etk_vbox.h \
 etk_paned.h etk_frame.h \
+etk_scrolled_view.h etk_viewport.h \
 etk_window.h \
 etk_image.h \
 etk_string.h etk_editable_text_object.h etk_label.h \
@@ -42,6 +43,7 @@
 etk_container.c etk_bin.c etk_table.c etk_alignment.c \
 etk_box.c etk_hbox.c etk_vbox.c \
 etk_paned.c etk_frame.c \
+etk_scrolled_view.c etk_viewport.c \
 etk_window.c \
 etk_image.c \
 etk_string.c etk_editable_text_object.c etk_label.c \
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_range.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- etk_range.c 23 Oct 2005 08:05:34 -0000      1.3
+++ etk_range.c 31 Oct 2005 21:36:40 -0000      1.4
@@ -61,6 +61,7 @@
       etk_type_property_add(range_type, "value", ETK_RANGE_VALUE_PROPERTY, 
ETK_PROPERTY_DOUBLE, ETK_PROPERTY_READABLE_WRITABLE,  
etk_property_value_double(0.0));
       etk_type_property_add(range_type, "step_increment", 
ETK_RANGE_STEP_INC_PROPERTY, ETK_PROPERTY_DOUBLE, 
ETK_PROPERTY_READABLE_WRITABLE,  etk_property_value_double(0.0));
       etk_type_property_add(range_type, "page_increment", 
ETK_RANGE_PAGE_INC_PROPERTY, ETK_PROPERTY_DOUBLE, 
ETK_PROPERTY_READABLE_WRITABLE,  etk_property_value_double(0.0));
+      etk_type_property_add(range_type, "page_size", 
ETK_RANGE_PAGE_SIZE_PROPERTY, ETK_PROPERTY_DOUBLE, 
ETK_PROPERTY_READABLE_WRITABLE,  etk_property_value_double(0.0));
       
       range_type->property_set = _etk_range_property_set;
       range_type->property_get = _etk_range_property_get;
@@ -96,7 +97,7 @@
    if (!range)
       return;
 
-   new_value = ETK_CLAMP(value, range->lower, range->upper);
+   new_value = ETK_CLAMP(value, range->lower, range->upper - range->page_size);
    if (new_value != range->value)
    {
       etk_signal_emit(_etk_range_signals[ETK_RANGE_CHANGE_VALUE_SIGNAL], 
ETK_OBJECT(range), &result, new_value);
@@ -119,8 +120,8 @@
    if (!range)
       return;
 
-   if (upper < lower)
-      upper = lower;
+   if (upper < lower + range->page_size)
+      upper = lower + range->page_size;
    
    if (range->lower != lower)
    {
@@ -159,6 +160,38 @@
    }
 }
 
+/**
+ * @brief Sets the page size of the range: this value will be used by the 
scrollbars to know the size of the drag button
+ * @param range a range
+ * @param page_size the value to set
+ */
+void etk_range_page_size_set(Etk_Range *range, double page_size)
+{
+   if (!range)
+      return;
+
+   page_size = ETK_MIN(page_size, range->upper - range->lower);
+   if (page_size != range->page_size)
+   {
+      range->page_size = page_size;
+      etk_object_notify(ETK_OBJECT(range), "page_size");
+      etk_widget_redraw_queue(ETK_WIDGET(range));
+   }
+}
+
+/**
+ * @brief Gets the page size of the range
+ * @param range a range
+ * @return Returns the page size of the range
+ */
+double etk_scrollbar_page_size_get(Etk_Range *range)
+{
+   if (!range)
+      return 0.0;
+   return range->page_size;
+}
+
+
 /**************************
  *
  * Etk specific functions
@@ -176,6 +209,7 @@
    range->value = 0.0;
    range->step_increment = 0.0;
    range->page_increment = 0.0;
+   range->page_size = 0.0;
 
    range->change_value = _etk_range_change_value_handler;
    range->value_changed = NULL;
@@ -206,6 +240,9 @@
       case ETK_RANGE_PAGE_INC_PROPERTY:
          etk_range_increments_set(range, range->step_increment, 
etk_property_value_double_get(value));
          break;
+      case ETK_RANGE_PAGE_SIZE_PROPERTY:
+         etk_range_page_size_set(range, etk_property_value_double_get(value));
+         break;
       default:
          break;
    }
@@ -236,6 +273,9 @@
       case ETK_RANGE_PAGE_INC_PROPERTY:
          etk_property_value_double_set(value, range->page_increment);
          break;
+      case ETK_RANGE_PAGE_SIZE_PROPERTY:
+         etk_property_value_double_set(value, range->page_size);
+         break;
       default:
          break;
    }
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_range.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- etk_range.h 23 Oct 2005 08:05:34 -0000      1.3
+++ etk_range.h 31 Oct 2005 21:36:40 -0000      1.4
@@ -29,6 +29,7 @@
 
    double step_increment;
    double page_increment;
+   double page_size;
 
    Etk_Bool (*change_value)(Etk_Range *range, double value);
    void (*value_changed)(Etk_Range *range, double value);
@@ -42,6 +43,9 @@
 void etk_range_range_set(Etk_Range *range, double lower, double upper);
 void etk_range_increments_set(Etk_Range *range, double step, double page);
 
+void etk_range_page_size_set(Etk_Range *range, double page_size);
+double etk_range_page_size_get(Etk_Range *range);
+
 /** @} */
 
 #endif
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_scrollbar.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -3 -r1.3 -r1.4
--- etk_scrollbar.c     29 Oct 2005 19:57:20 -0000      1.3
+++ etk_scrollbar.c     31 Oct 2005 21:36:40 -0000      1.4
@@ -15,28 +15,11 @@
 #define ETK_SCROLLBAR_FIRST_DELAY 0.4
 #define ETK_SCROLLBAR_REPEAT_DELAY 0.05
 
-enum _Etk_Scrollbar_Property_Id
-{
-   ETK_SCROLLBAR_PAGE_SIZE_PROPERTY
-};
-
 static void _etk_scrollbar_constructor(Etk_Scrollbar *scrollbar);
-static void _etk_scrollbar_destructor(Etk_Scrollbar *scrollbar);
-static void _etk_hscrollbar_constructor(Etk_HScrollbar *hscrollbar);
-static void _etk_vscrollbar_constructor(Etk_VScrollbar *vscrollbar);
-static void _etk_scrollbar_property_set(Etk_Object *object, int property_id, 
Etk_Property_Value *value);
-static void _etk_scrollbar_property_get(Etk_Object *object, int property_id, 
Etk_Property_Value *value);
-static void _etk_hscrollbar_move_resize(Etk_Widget *widget, int x, int y, int 
w, int h);
-static void _etk_vscrollbar_move_resize(Etk_Widget *widget, int x, int y, int 
w, int h);
-static void _etk_hscrollbar_realize_cb(Etk_Object *object, void *data);
-static void _etk_vscrollbar_realize_cb(Etk_Object *object, void *data);
+static void _etk_scrollbar_realize_cb(Etk_Object *object, void *data);
+static void _etk_scrollbar_drag_dragged_cb(void *data, Evas_Object *obj, const 
char *emission, const char *source);
 static void _etk_scrollbar_value_changed_handler(Etk_Range *range, double 
value);
-
-static void _etk_hscrollbar_drag_pressed_cb(void *data, Evas *evas, 
Evas_Object *object, void *event_info);
-static void _etk_vscrollbar_drag_pressed_cb(void *data, Evas *evas, 
Evas_Object *object, void *event_info);
-static void _etk_scrollbar_drag_released_cb(void *data, Evas *evas, 
Evas_Object *object, void *event_info);
-static void _etk_hscrollbar_drag_moved_cb(void *data, Evas *evas, Evas_Object 
*object, void *event_info);
-static void _etk_vscrollbar_drag_moved_cb(void *data, Evas *evas, Evas_Object 
*object, void *event_info);
+static void _etk_scrollbar_page_size_changed_cb(Etk_Object *object, const char 
*property_name, void *data);
 
 static void _etk_scrollbar_scroll_start_cb(void *data, Evas_Object *obj, const 
char *emission, const char *source);
 static void _etk_scrollbar_scroll_stop_cb(void *data, Evas_Object *obj, const 
char *emission, const char *source);
@@ -59,12 +42,7 @@
 
    if (!scrollbar_type)
    {
-      scrollbar_type = etk_type_new("Etk_Scrollbar", ETK_RANGE_TYPE, 
sizeof(Etk_Scrollbar), ETK_CONSTRUCTOR(_etk_scrollbar_constructor), 
ETK_DESTRUCTOR(_etk_scrollbar_destructor), NULL);
-
-      etk_type_property_add(scrollbar_type, "page_size", 
ETK_SCROLLBAR_PAGE_SIZE_PROPERTY, ETK_PROPERTY_DOUBLE, 
ETK_PROPERTY_READABLE_WRITABLE, etk_property_value_double(0.0));
-   
-      scrollbar_type->property_set = _etk_scrollbar_property_set;
-      scrollbar_type->property_get = _etk_scrollbar_property_get;
+      scrollbar_type = etk_type_new("Etk_Scrollbar", ETK_RANGE_TYPE, 
sizeof(Etk_Scrollbar), ETK_CONSTRUCTOR(_etk_scrollbar_constructor), NULL, NULL);
    }
 
    return scrollbar_type;
@@ -80,7 +58,7 @@
 
    if (!hscrollbar_type)
    {
-      hscrollbar_type = etk_type_new("Etk_HScrollbar", ETK_SCROLLBAR_TYPE, 
sizeof(Etk_HScrollbar), ETK_CONSTRUCTOR(_etk_hscrollbar_constructor), NULL, 
NULL);
+      hscrollbar_type = etk_type_new("Etk_HScrollbar", ETK_SCROLLBAR_TYPE, 
sizeof(Etk_HScrollbar), NULL, NULL, NULL);
    }
 
    return hscrollbar_type;
@@ -112,7 +90,7 @@
 
    if (!vscrollbar_type)
    {
-      vscrollbar_type = etk_type_new("Etk_VScrollbar", ETK_SCROLLBAR_TYPE, 
sizeof(Etk_VScrollbar), ETK_CONSTRUCTOR(_etk_vscrollbar_constructor), NULL, 
NULL);
+      vscrollbar_type = etk_type_new("Etk_VScrollbar", ETK_SCROLLBAR_TYPE, 
sizeof(Etk_VScrollbar), NULL, NULL, NULL);
    }
 
    return vscrollbar_type;
@@ -120,12 +98,6 @@
 
 /**
  * @brief Creates a new vertical scrollbar
- * @param lower the lower bound of the scrollbar
- * @param upper the upper bound of the scrollbar
- * @param value the initial value of the scrollbar
- * @param step the step increment value. Used when the arrow of a scrollbar is 
clicked, or when the keyboard arrows are pressed (for a scale)
- * @param page the page increment value. Used when the trough of a scrollbar 
is clicked, or when page up/down are pressed
- * @param page_size the page size value of the scrollbar: this value is used 
to know the size of the drag button of the scrollbar
  * @return Returns the new vertical scrollbar widget
  */
 Etk_Widget *etk_vscrollbar_new(double lower, double upper, double value, 
double step_increment, double page_increment, double page_size)
@@ -134,35 +106,6 @@
       "value", value, "step_increment", step_increment, "page_increment", 
page_increment, "page_size", page_size, NULL);
 }
 
-/**
- * @brief Sets the page size of the scrollbar:this value is used to know the 
size of the drag button of the scrollbar
- * @param scrollbar a scrollbar
- * @param page_size the value to set
- */
-void etk_scrollbar_page_size_set(Etk_Scrollbar *scrollbar, double page_size)
-{
-   if (!scrollbar)
-      return;
-
-   scrollbar->page_size = page_size;
-   etk_object_notify(ETK_OBJECT(scrollbar), "page_size");
-   etk_widget_redraw_queue(ETK_WIDGET(scrollbar));
-}
-
-/**
- * @brief Gets the page size of the scrollbar
- * @param scrollbar a scrollbar
- * @return Returns the page size of the scrollbar
- */
-double etk_scrollbar_page_size_get(Etk_Scrollbar *scrollbar)
-{
-   if (!scrollbar)
-      return 0.0;
-
-   return scrollbar->page_size;
-}
-
-
 /**************************
  *
  * Etk specific functions
@@ -175,152 +118,12 @@
    if (!scrollbar)
       return;
 
-   scrollbar->page_size = 0.0;
-   scrollbar->drag_button = NULL;
-   scrollbar->drag_orig_position = -1;
-   scrollbar->drag_size = 0;
-   scrollbar->confine_size = 0;
    scrollbar->scrolling_timer = NULL;
    scrollbar->first_scroll = FALSE;
-   ETK_RANGE(scrollbar)->value_changed = _etk_scrollbar_value_changed_handler;
-}
-
-/* Destroys the scrollbar */
-static void _etk_scrollbar_destructor(Etk_Scrollbar *scrollbar)
-{
-   if (!scrollbar)
-      return;
-
-   if (scrollbar->scrolling_timer)
-      ecore_timer_del(scrollbar->scrolling_timer);
-}
-
-/* Initializes the default values of the hscrollbar */
-static void _etk_hscrollbar_constructor(Etk_HScrollbar *hscrollbar)
-{
-   if (!hscrollbar)
-      return;
-
-   ETK_WIDGET(hscrollbar)->move_resize = _etk_hscrollbar_move_resize;
-   etk_signal_connect_after("realize", ETK_OBJECT(hscrollbar), 
ETK_CALLBACK(_etk_hscrollbar_realize_cb), NULL);
-}
-
-/* Initializes the default values of the vscrollbar */
-static void _etk_vscrollbar_constructor(Etk_VScrollbar *vscrollbar)
-{
-   if (!vscrollbar)
-      return;
-
-   ETK_WIDGET(vscrollbar)->move_resize = _etk_vscrollbar_move_resize;
-   etk_signal_connect_after("realize", ETK_OBJECT(vscrollbar), 
ETK_CALLBACK(_etk_vscrollbar_realize_cb), NULL);
-}
-
-/* Sets the property whose id is "property_id" to the value "value" */
-static void _etk_scrollbar_property_set(Etk_Object *object, int property_id, 
Etk_Property_Value *value)
-{
-   Etk_Scrollbar *scrollbar;
-
-   if (!(scrollbar = ETK_SCROLLBAR(object)) || !value)
-      return;
-
-   switch (property_id)
-   {
-      case ETK_SCROLLBAR_PAGE_SIZE_PROPERTY:
-         etk_scrollbar_page_size_set(scrollbar, 
etk_property_value_double_get(value)); 
-         break;
-   }
-}
-
-/* Gets the value of the property whose id is "property_id" */
-static void _etk_scrollbar_property_get(Etk_Object *object, int property_id, 
Etk_Property_Value *value)
-{
-   Etk_Scrollbar *scrollbar;
-
-   if (!(scrollbar = ETK_SCROLLBAR(object)) || !value)
-      return;
-
-   switch (property_id)
-   {
-      case ETK_SCROLLBAR_PAGE_SIZE_PROPERTY:
-         etk_property_value_double_set(value, scrollbar->page_size);
-         break;
-   }
-}
-
-/* Moves and resizes the hscrollbar */ 
-static void _etk_hscrollbar_move_resize(Etk_Widget *widget, int x, int y, int 
w, int h)
-{
-   Etk_Scrollbar *scrollbar;
-   Etk_Range *range;
-   Evas_Coord tx, ty, cx, cy, cw, ch, mw;
-   float x_offset, drag_width; 
-
-   if (!(scrollbar = ETK_SCROLLBAR(widget)) || !widget->theme_object || 
!scrollbar->drag_button)
-      return;
-
-   range = ETK_RANGE(scrollbar);
-   evas_object_geometry_get(widget->theme_object, &tx, &ty, NULL, NULL);
-   edje_object_part_geometry_get(widget->theme_object, "confine", &cx, &cy, 
&cw, &ch);
-   edje_object_size_min_get(scrollbar->drag_button, &mw, NULL);
-
-   if (scrollbar->page_size > 0 && range->lower < range->upper)
-   {
-      drag_width = ((float)scrollbar->page_size / (range->upper - 
range->lower)) * cw;
-      drag_width = ETK_MAX(mw, drag_width);
-      x_offset = (cw - drag_width) * ((float)(range->value - range->lower) / 
(range->upper - range->lower));
-   }
-   else
-   {
-      drag_width = 0.3 * cw;
-      drag_width = ETK_MAX(mw, drag_width);
-      if (range->lower < range->upper)
-         x_offset = (cw - drag_width) * ((float)(range->value - range->lower) 
/ (range->upper - range->lower));
-      else
-         x_offset = 0.0;
-   }
-   evas_object_move(ETK_SCROLLBAR(widget)->drag_button, tx + cx + x_offset, ty 
+ cy);
-   evas_object_resize(ETK_SCROLLBAR(widget)->drag_button, drag_width, ch);
-
-   ETK_SCROLLBAR(widget)->confine_size = cw;
-   ETK_SCROLLBAR(widget)->drag_size = drag_width;
-}
-
-/* Moves and resizes the vscrollbar */ 
-static void _etk_vscrollbar_move_resize(Etk_Widget *widget, int x, int y, int 
w, int h)
-{
-   Etk_Scrollbar *scrollbar;
-   Etk_Range *range;
-   Evas_Coord tx, ty, cx, cy, cw, ch, mh;
-   float y_offset, drag_height; 
 
-   if (!(scrollbar = ETK_SCROLLBAR(widget)) || !widget->theme_object || 
!scrollbar->drag_button)
-      return;
-
-   range = ETK_RANGE(scrollbar);
-   evas_object_geometry_get(widget->theme_object, &tx, &ty, NULL, NULL);
-   edje_object_part_geometry_get(widget->theme_object, "confine", &cx, &cy, 
&cw, &ch);
-   edje_object_size_min_get(scrollbar->drag_button, NULL, &mh);
-
-   if (scrollbar->page_size > 0 && range->lower < range->upper)
-   {
-      drag_height = ((float)scrollbar->page_size / (range->upper - 
range->lower)) * ch;
-      drag_height = ETK_MAX(mh, drag_height);
-      y_offset = (ch - drag_height) * ((float)(range->value - range->lower) / 
(range->upper - range->lower));
-   }
-   else
-   {
-      drag_height = 0.3 * ch;
-      drag_height = ETK_MAX(mh, drag_height);
-      if (range->lower < range->upper)
-         y_offset = (ch - drag_height) * ((float)(range->value - range->lower) 
/ (range->upper - range->lower));
-      else
-         y_offset = 0.0;
-   }
-   evas_object_move(ETK_SCROLLBAR(widget)->drag_button, tx + cx, ty + cy + 
y_offset);
-   evas_object_resize(ETK_SCROLLBAR(widget)->drag_button, cw, drag_height);
-   
-   ETK_SCROLLBAR(widget)->confine_size = ch;
-   ETK_SCROLLBAR(widget)->drag_size = drag_height;
+   ETK_RANGE(scrollbar)->value_changed = _etk_scrollbar_value_changed_handler;
+   etk_signal_connect_after("realize", ETK_OBJECT(scrollbar), 
ETK_CALLBACK(_etk_scrollbar_realize_cb), NULL);
+   etk_object_notification_callback_add(ETK_OBJECT(scrollbar), "page_size", 
_etk_scrollbar_page_size_changed_cb, NULL);
 }
 
 /**************************
@@ -330,132 +133,72 @@
  **************************/
 
 /* Called when the hscrollbar is realized */
-static void _etk_hscrollbar_realize_cb(Etk_Object *object, void *data)
+static void _etk_scrollbar_realize_cb(Etk_Object *object, void *data)
 {
-   Etk_Scrollbar *scrollbar;
-   Etk_Widget *scrollbar_widget;
-   Evas *evas;
+   Evas_Object *theme_object;
 
-   if (!(scrollbar_widget = ETK_WIDGET(object)) || !(evas = 
etk_widget_toplevel_evas_get(scrollbar_widget)))
+   if (!object || !(theme_object = ETK_WIDGET(object)->theme_object))
       return;
-   scrollbar = ETK_SCROLLBAR(scrollbar_widget);
-
-   scrollbar->drag_button = edje_object_add(evas);
-   edje_object_file_set(scrollbar->drag_button, scrollbar_widget->theme_file, 
"hscrollbar_drag");
-   evas_object_show(scrollbar->drag_button);
-   etk_widget_member_object_add(scrollbar_widget, scrollbar->drag_button);
-
-   evas_object_event_callback_add(scrollbar->drag_button, 
EVAS_CALLBACK_MOUSE_DOWN, _etk_hscrollbar_drag_pressed_cb, scrollbar);
-   evas_object_event_callback_add(scrollbar->drag_button, 
EVAS_CALLBACK_MOUSE_UP, _etk_scrollbar_drag_released_cb, scrollbar);
-   evas_object_event_callback_add(scrollbar->drag_button, 
EVAS_CALLBACK_MOUSE_MOVE, _etk_hscrollbar_drag_moved_cb, scrollbar);
 
-   edje_object_signal_callback_add(scrollbar_widget->theme_object, 
"scroll_left_start", "", _etk_scrollbar_scroll_start_cb, scrollbar);
-   edje_object_signal_callback_add(scrollbar_widget->theme_object, 
"scroll_right_start", "", _etk_scrollbar_scroll_start_cb, scrollbar);
-   edje_object_signal_callback_add(scrollbar_widget->theme_object, 
"scroll_stop", "", _etk_scrollbar_scroll_stop_cb, scrollbar);
+   _etk_scrollbar_value_changed_handler(ETK_RANGE(object), 
ETK_RANGE(object)->value);
+   edje_object_signal_callback_add(theme_object, "drag", "drag", 
_etk_scrollbar_drag_dragged_cb, object);
+   edje_object_signal_callback_add(theme_object, "scroll_*_start", "", 
_etk_scrollbar_scroll_start_cb, object);
+   edje_object_signal_callback_add(theme_object, "scroll_stop", "", 
_etk_scrollbar_scroll_stop_cb, object);
 }
 
-/* Called when the vscrollbar is realized */
-static void _etk_vscrollbar_realize_cb(Etk_Object *object, void *data)
+/* Called when the drag button of the scrollbar is dragged */
+static void _etk_scrollbar_drag_dragged_cb(void *data, Evas_Object *obj, const 
char *emission, const char *source)
 {
-   Etk_Scrollbar *scrollbar;
-   Etk_Widget *scrollbar_widget;
-   Evas *evas;
+   Etk_Range *range;
+   double percent;
 
-   if (!(scrollbar_widget = ETK_WIDGET(object)) || !(evas = 
etk_widget_toplevel_evas_get(scrollbar_widget)))
+   if (!(range = ETK_RANGE(data)))
       return;
-   scrollbar = ETK_SCROLLBAR(scrollbar_widget);
-
-   scrollbar->drag_button = edje_object_add(evas);
-   edje_object_file_set(scrollbar->drag_button, scrollbar_widget->theme_file, 
"vscrollbar_drag");
-   evas_object_show(scrollbar->drag_button);
-   etk_widget_member_object_add(scrollbar_widget, scrollbar->drag_button);
-
-   evas_object_event_callback_add(scrollbar->drag_button, 
EVAS_CALLBACK_MOUSE_DOWN, _etk_vscrollbar_drag_pressed_cb, scrollbar);
-   evas_object_event_callback_add(scrollbar->drag_button, 
EVAS_CALLBACK_MOUSE_UP, _etk_scrollbar_drag_released_cb, scrollbar);
-   evas_object_event_callback_add(scrollbar->drag_button, 
EVAS_CALLBACK_MOUSE_MOVE, _etk_vscrollbar_drag_moved_cb, scrollbar);
 
-   edje_object_signal_callback_add(scrollbar_widget->theme_object, 
"scroll_up_start", "", _etk_scrollbar_scroll_start_cb, scrollbar);
-   edje_object_signal_callback_add(scrollbar_widget->theme_object, 
"scroll_down_start", "", _etk_scrollbar_scroll_start_cb, scrollbar);
-   edje_object_signal_callback_add(scrollbar_widget->theme_object, 
"scroll_stop", "", _etk_scrollbar_scroll_stop_cb, scrollbar);
+   if (ETK_IS_HSCROLLBAR(range))
+      edje_object_part_drag_value_get(obj, "drag", &percent, NULL);
+   else
+      edje_object_part_drag_value_get(obj, "drag", NULL, &percent);
+   etk_range_value_set(range, range->lower + percent * (range->upper - 
range->lower - range->page_size));
 }
 
-/* Called when the value of the scrollbar is changed */
+/* Default handler for the "value_changed" signal of a scrollbar */
 static void _etk_scrollbar_value_changed_handler(Etk_Range *range, double 
value)
 {
-   if (!range)
-      return;
+   double percent;
 
-   etk_widget_redraw_queue(ETK_WIDGET(range));
-}
-
-/* Called when the user presses the drag button of a hscrollbar */
-static void _etk_hscrollbar_drag_pressed_cb(void *data, Evas *evas, 
Evas_Object *object, void *event_info)
-{
-   Evas_Event_Mouse_Down *event = event_info;
-   Etk_Scrollbar *scrollbar;
-
-   if (!(scrollbar = ETK_SCROLLBAR(data)))
+   if (!range || !ETK_WIDGET(range)->theme_object)
       return;
 
-   scrollbar->drag_orig_position = event->canvas.x;
-   scrollbar->drag_orig_value = ETK_RANGE(scrollbar)->value;
-}
-
-/* Called when the user presses the drag button of a vscrollbar */
-static void _etk_vscrollbar_drag_pressed_cb(void *data, Evas *evas, 
Evas_Object *object, void *event_info)
-{
-   Evas_Event_Mouse_Down *event = event_info;
-   Etk_Scrollbar *scrollbar;
-
-   if (!(scrollbar = ETK_SCROLLBAR(data)))
-      return;
-
-   scrollbar->drag_orig_position = event->canvas.y;
-   scrollbar->drag_orig_value = ETK_RANGE(scrollbar)->value;
-}
-
-/* Called when the user releases the drag button of a scrollbar */
-static void _etk_scrollbar_drag_released_cb(void *data, Evas *evas, 
Evas_Object *object, void *event_info)
-{
-   Etk_Scrollbar *scrollbar;
-
-   if (!(scrollbar = ETK_SCROLLBAR(data)))
-      return;
+   if (range->upper - range->page_size > range->lower)
+      percent = ETK_CLAMP(value / (range->upper - range->lower - 
range->page_size), 0.0, 1.0);
+   else
+      percent = 0.0;
 
-   scrollbar->drag_orig_position = -1;
+   if (ETK_IS_HSCROLLBAR(range))
+      edje_object_part_drag_value_set(ETK_WIDGET(range)->theme_object, "drag", 
percent, 0.0);
+   else
+      edje_object_part_drag_value_set(ETK_WIDGET(range)->theme_object, "drag", 
0.0, percent);
 }
 
-/* Called when the user moves the mouse above the drag button of a hscrollbar 
*/
-static void _etk_hscrollbar_drag_moved_cb(void *data, Evas *evas, Evas_Object 
*object, void *event_info)
+/* Called when the page size of the scrollbar is changed */
+static void _etk_scrollbar_page_size_changed_cb(Etk_Object *object, const char 
*property_name, void *data)
 {
-   Evas_Event_Mouse_Move *event = event_info;
-   Etk_Scrollbar *scrollbar;
-   double new_value;
+   Etk_Range *range;
+   Evas_Object *theme_object;
+   double new_drag_size;
 
-   if (!(scrollbar = ETK_SCROLLBAR(data)) || scrollbar->drag_orig_position < 0 
|| scrollbar->confine_size <= scrollbar->drag_size)
+   if (!(range = ETK_RANGE(object)) || !(theme_object = 
ETK_WIDGET(range)->theme_object))
       return;
-   
-   new_value = scrollbar->drag_orig_value + ((float)(event->cur.canvas.x - 
scrollbar->drag_orig_position) / (scrollbar->confine_size - 
scrollbar->drag_size)) *
-      (ETK_RANGE(scrollbar)->upper - ETK_RANGE(scrollbar)->lower);
-   etk_range_value_set(ETK_RANGE(scrollbar), new_value);
-}
-
-/* Called when the user moves the mouse above the drag button of a vscrollbar 
*/
-static void _etk_vscrollbar_drag_moved_cb(void *data, Evas *evas, Evas_Object 
*object, void *event_info)
-{
-   Evas_Event_Mouse_Move *event = event_info;
-   Etk_Scrollbar *scrollbar;
-   double new_value;
 
-   if (!(scrollbar = ETK_SCROLLBAR(data)) || scrollbar->drag_orig_position < 0 
|| scrollbar->confine_size <= scrollbar->drag_size)
-      return;
-   
-   new_value = scrollbar->drag_orig_value + ((float)(event->cur.canvas.y - 
scrollbar->drag_orig_position) / (scrollbar->confine_size - 
scrollbar->drag_size)) *
-      (ETK_RANGE(scrollbar)->upper - ETK_RANGE(scrollbar)->lower);
-   etk_range_value_set(ETK_RANGE(scrollbar), new_value);
+   new_drag_size = (double)range->page_size / (range->upper - range->lower);
+   if (ETK_IS_HSCROLLBAR(range))
+      edje_object_part_drag_size_set(theme_object, "drag", new_drag_size, 0.0);
+   else
+      edje_object_part_drag_size_set(theme_object, "drag", 0.0, new_drag_size);
 }
 
-/* TODO doc */
+/* Called when the user starts to press an arrow of the scrollbar */
 static void _etk_scrollbar_scroll_start_cb(void *data, Evas_Object *obj, const 
char *emission, const char *source)
 {
    Etk_Scrollbar *scrollbar;
@@ -481,7 +224,7 @@
    }
 }
 
-/* TODO doc */
+/* Called when the user stops pressing an arrow of the scrollbar */
 static void _etk_scrollbar_scroll_stop_cb(void *data, Evas_Object *obj, const 
char *emission, const char *source)
 {
    Etk_Scrollbar *scrollbar;
@@ -493,7 +236,7 @@
    scrollbar->scrolling_timer = NULL;
 }
 
-/* TODO doc */
+/* A timer callback that increment the value of the range with the step value 
*/
 static int _etk_scrollbar_step_decrement_cb(void *data)
 {
    Etk_Scrollbar *scrollbar;
@@ -512,7 +255,7 @@
    return 1;
 }
 
-/* TODO doc */
+/* A timer callback that decrement the value of the range with the step value 
*/
 static int _etk_scrollbar_step_increment_cb(void *data)
 {
    Etk_Scrollbar *scrollbar;
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_scrollbar.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -3 -r1.1 -r1.2
--- etk_scrollbar.h     23 Oct 2005 08:05:35 -0000      1.1
+++ etk_scrollbar.h     31 Oct 2005 21:36:40 -0000      1.2
@@ -2,7 +2,6 @@
 #ifndef _ETK_SCROLLBAR_H_
 #define _ETK_SCROLLBAR_H_
 
-#include <Evas.h>
 #include <Ecore.h>
 #include "etk_range.h"
 #include "etk_types.h"
@@ -35,7 +34,7 @@
 
 /**
  * @struct Etk_Scrollbar
- * @brief An Etk_Scrollbar is used mainly in Etk_Scrolled_Window
+ * @brief An Etk_Scrollbar is a widget with a cursor you can move to change a 
value
  */
 struct _Etk_Scrollbar
 {
@@ -43,14 +42,6 @@
    /* Inherit from Etk_Range */
    Etk_Range range;
 
-   int drag_size;
-   int confine_size;
-   double page_size;
-
-   Evas_Object *drag_button;
-   double drag_orig_value;
-   int drag_orig_position;
-
    Ecore_Timer *scrolling_timer;
    Etk_Bool first_scroll;
 };
@@ -85,9 +76,6 @@
 Etk_Type *etk_vscrollbar_type_get();
 Etk_Widget *etk_vscrollbar_new(double lower, double upper, double value, 
double step_increment, double page_increment, double page_size);
 
-void etk_scrollbar_page_size_set(Etk_Scrollbar *scrollbar, double page_size);
-double etk_scrollbar_page_size_get(Etk_Scrollbar *scrollbar);
-
 /** @} */
 
 #endif
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_types.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -3 -r1.8 -r1.9
--- etk_types.h 30 Oct 2005 10:25:25 -0000      1.8
+++ etk_types.h 31 Oct 2005 21:36:40 -0000      1.9
@@ -63,6 +63,8 @@
 typedef struct _Etk_Paned Etk_Paned;
 typedef struct _Etk_HPaned Etk_HPaned;
 typedef struct _Etk_VPaned Etk_VPaned;
+typedef struct _Etk_Scrolled_View Etk_Scrolled_View;
+typedef struct _Etk_Viewport Etk_Viewport;
 typedef struct _Etk_Window Etk_Window;
 typedef struct _Etk_Image Etk_Image;
 typedef struct _Etk_Label Etk_Label;
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -3 -r1.6 -r1.7
--- etk_widget.c        30 Oct 2005 11:56:05 -0000      1.6
+++ etk_widget.c        31 Oct 2005 21:36:40 -0000      1.7
@@ -112,6 +112,8 @@
 static void _etk_widget_smart_object_del(Evas_Object *object);
 static void _etk_widget_smart_object_move(Evas_Object *object, Evas_Coord x, 
Evas_Coord y);
 static void _etk_widget_smart_object_resize(Evas_Object *object, Evas_Coord w, 
Evas_Coord h);
+static void _etk_widget_smart_object_show(Evas_Object *object);
+static void _etk_widget_smart_object_hide(Evas_Object *object);
 static void _etk_widget_smart_object_clip_set(Evas_Object *object, Evas_Object 
*clip);
 static void _etk_widget_smart_object_clip_unset(Evas_Object *object);
 static void _etk_widget_swallowed_object_free(void *data);
@@ -339,6 +341,12 @@
    etk_widget_member_object_add(widget, widget->theme_object);
    evas_object_show(widget->theme_object);
 
+   if (widget->clip)
+   {
+      evas_object_show(widget->clip);
+      evas_object_clip_set(widget->smart_object, widget->clip);
+   }
+
    if (ETK_IS_CONTAINER(widget))
    {
       Evas_List *l;
@@ -354,7 +362,6 @@
 
    if (widget->parent && ETK_WIDGET(widget->parent)->smart_object && 
!widget->swallowed)
       etk_widget_member_object_add(ETK_WIDGET(widget->parent), 
widget->smart_object);
-      
 
    etk_widget_repeat_events_set(widget, widget->repeat_events);
    etk_widget_pass_events_set(widget, widget->pass_events);
@@ -395,6 +402,9 @@
    }
    evas_object_del(widget->smart_object);
 
+   if (widget->clip)
+      evas_object_hide(widget->clip);
+
    widget->left_inset = 0;
    widget->right_inset = 0;
    widget->top_inset = 0;
@@ -697,20 +707,31 @@
  */
 void etk_widget_size_request(Etk_Widget *widget, Etk_Size *size_requisition)
 {
+   etk_widget_size_request_full(widget, size_requisition, TRUE);
+}
+
+/**
+ * @brief Calculates the ideal size of the widget. Used mainly for container 
implementation
+ * @param widget a widget
+ * @param size_requisition the location where to set the result
+ * @param hidden_has_no_size if hidden_has_no_size is TRUE, then if the widget 
is hidden, the size requisition will be 0x0
+ */
+void etk_widget_size_request_full(Etk_Widget *widget, Etk_Size 
*size_requisition, Etk_Bool hidden_has_no_size)
+{
    if (!widget || !size_requisition)
       return;
 
    size_requisition->w = -1;
    size_requisition->h = -1;
 
-   if (!widget->visible)
+   if (!widget->visible && hidden_has_no_size)
       size_requisition->w = 0;
    else if (!widget->need_size_recalc && widget->last_size_requisition.w >= 0)
       size_requisition->w = widget->last_size_requisition.w;
    else if (widget->requested_size.w >= 0)
       size_requisition->w = widget->requested_size.w;
    
-   if (!widget->visible)
+   if (!widget->visible && hidden_has_no_size)
       size_requisition->h = 0;
    else if (!widget->need_size_recalc && widget->last_size_requisition.h >= 0)
       size_requisition->h = widget->last_size_requisition.h;
@@ -742,7 +763,8 @@
       }
    }
 
-   widget->last_size_requisition = *size_requisition;
+   if (widget->visible)
+      widget->last_size_requisition = *size_requisition;
    widget->need_size_recalc = FALSE;
 
    etk_signal_emit(_etk_widget_signals[ETK_WIDGET_SIZE_REQUEST_SIGNAL], 
ETK_OBJECT(widget), NULL, size_requisition);
@@ -1060,8 +1082,13 @@
       return TRUE;
    widget->member_objects = evas_list_append(widget->member_objects, object);
 
-   if (!etk_widget_object_is_swallowed(widget, object) && widget->smart_object)
-      evas_object_smart_member_add(object, widget->smart_object);
+   if (!etk_widget_object_is_swallowed(widget, object))
+   {
+      if (widget->smart_object)
+         evas_object_smart_member_add(object, widget->smart_object);
+      if (widget->clip)
+         evas_object_clip_set(object, widget->clip);
+   }
 
    return TRUE;
 }
@@ -1082,7 +1109,11 @@
    {
       widget->member_objects = evas_list_remove_list(widget->member_objects, 
l);
       if (!etk_widget_object_is_swallowed(widget, object))
+      {
          evas_object_smart_member_del(object);
+         if (widget->clip)
+            evas_object_clip_unset(object);
+      }
    }
 }
 
@@ -1144,6 +1175,59 @@
       evas_object_stack_below(object, below);
 }
 
+/**
+ * @brief Sets the clip object of the widget. Used mainly for widget 
implementations
+ * @param widget a widget
+ * @param clip the clip object to set
+ * @warning when the clip is destoyed, you have to call 
etk_widget_clip_unset() on the widget
+ */
+void etk_widget_clip_set(Etk_Widget *widget, Evas_Object *clip)
+{
+   if (!widget)
+      return;
+
+   if (widget->clip)
+      etk_widget_clip_unset(widget);
+   
+   if (widget->smart_object)
+   {
+      evas_object_show(clip);
+      evas_object_clip_set(widget->smart_object, clip);
+   }
+   else
+   {
+      widget->clip = clip;
+      evas_object_hide(widget->clip);
+   }
+}
+
+/**
+ * @brief Unsets the clip object of the widget. Used mainly for widget 
implementations
+ * @param widget a widget
+ */
+void etk_widget_clip_unset(Etk_Widget *widget)
+{
+   if (!widget || !widget->clip)
+      return;
+
+   if (widget->smart_object)
+      evas_object_clip_unset(widget->smart_object);
+   widget->clip = NULL;
+}
+
+/**
+ * @brief Gets the clip object of the widget
+ * @param widget a widget
+ * @return Returns the clip object of the widget
+ */
+Evas_Object *etk_widget_clip_get(Etk_Widget *widget)
+{
+   if (!widget)
+      return NULL;
+   return widget->clip;
+}
+
+
 /**************************
  *
  * Etk specific functions
@@ -1200,6 +1284,9 @@
    widget->last_size_requisition.w = 0;
    widget->last_size_requisition.h = 0;
 
+   widget->scroll_size_get = NULL;
+   widget->scroll = NULL;
+
    widget->realized = FALSE;
    widget->visible = FALSE;
    widget->focusable = FALSE;
@@ -1417,7 +1504,7 @@
    widget->visible = TRUE;
    if (widget->smart_object)
       evas_object_show(widget->smart_object);
-   etk_widget_redraw_queue(widget);
+   etk_widget_size_recalc_queue(widget);
    etk_object_notify(ETK_OBJECT(widget), "visible");
 }
 
@@ -1430,7 +1517,7 @@
    widget->visible = FALSE;
    if (widget->smart_object)
       evas_object_hide(widget->smart_object);
-   etk_widget_redraw_queue(widget);
+   etk_widget_size_recalc_queue(widget);
    etk_object_notify(ETK_OBJECT(widget), "visible");
 }
 
@@ -1822,11 +1909,11 @@
          NULL, //_etk_widget_smart_object_stack_below, /* stack_below */
          _etk_widget_smart_object_move, /* move */
          _etk_widget_smart_object_resize, /* resize */
-         NULL, /* show */
-         NULL, /* hide */
+         _etk_widget_smart_object_show, /* show */
+         _etk_widget_smart_object_hide, /* hide */
          NULL, /* color_set */
          _etk_widget_smart_object_clip_set, /* clip_set */
-         NULL, /* clip_unset */
+         _etk_widget_smart_object_clip_unset, /* clip_unset */
          NULL); /* data*/
    }
 
@@ -1930,26 +2017,71 @@
    }
 }
 
+/* Called when the smart object is shown */
+static void _etk_widget_smart_object_show(Evas_Object *object)
+{
+   Evas_List *l;
+   Etk_Widget_Smart_Data *smart_data;
+   Etk_Widget *widget, *child;
+   Evas_Object *o;
+
+   if (!object || !(smart_data = evas_object_smart_data_get(object)) || 
!(widget = smart_data->widget))
+      return;
+
+   for (l = widget->member_objects; l; l = l->data)
+   {
+      o = l->data;
+
+      if (!(child = ETK_WIDGET(evas_object_data_get(o, "etk_widget"))) || 
child->visible)
+         evas_object_show(o);
+   }
+}
+
+/* Called when the smart object is hidden */
+static void _etk_widget_smart_object_hide(Evas_Object *object)
+{
+   Evas_List *l;
+   Etk_Widget_Smart_Data *smart_data;
+   Etk_Widget *widget;
+
+   if (!object || !(smart_data = evas_object_smart_data_get(object)) || 
!(widget = smart_data->widget))
+      return;
+
+   for (l = widget->member_objects; l; l = l->data)
+      evas_object_hide(l->data);
+}
+
 /* Called when a clip is set to the smart object */
 static void _etk_widget_smart_object_clip_set(Evas_Object *object, Evas_Object 
*clip)
 {
    Evas_List *l;
    Etk_Widget_Smart_Data *smart_data;
-   Etk_Widget *widget;
+   Etk_Widget *widget, *child;
+   Evas_Object *object_to_clip;
 
    if (!object || !clip || !(smart_data = evas_object_smart_data_get(object)) 
|| !(widget = smart_data->widget))
       return;
-   if (widget->clip == clip)
-      return;
 
+   if (widget->clip)
+      etk_widget_clip_unset(widget);
    widget->clip = clip;
+
    for (l = widget->member_objects; l; l = l->next)
    {
-      Evas_Object *object_to_clip;
-
-      for (object_to_clip = l->data; evas_object_clip_get(object_to_clip); 
object_to_clip = evas_object_clip_get(object_to_clip));
-      if (object_to_clip && object_to_clip != clip)
-         evas_object_clip_set(object_to_clip, clip);
+      if (!(child = ETK_WIDGET(evas_object_data_get(l->data, "etk_widget"))) 
|| !child->clip)
+      {
+         object_to_clip = l->data;
+         while (evas_object_clip_get(object_to_clip))
+         {
+            if (object_to_clip == clip)
+               break;
+            object_to_clip = evas_object_clip_get(object_to_clip);
+         }
+         if (object_to_clip != clip)
+            evas_object_clip_set(object_to_clip, clip);
+      }
+      else
+         evas_object_clip_set(child->clip, clip);
    }
 }
 
@@ -1957,14 +2089,39 @@
 static void _etk_widget_smart_object_clip_unset(Evas_Object *object)
 {
    Evas_List *l;
-   Etk_Widget *widget;
+   Etk_Widget *widget, *child;
    Etk_Widget_Smart_Data *smart_data;
 
-   if (!object || !(smart_data = evas_object_smart_data_get(object)) || 
!(widget = smart_data->widget))
+   if (!object || !(smart_data = evas_object_smart_data_get(object)) || 
!(widget = smart_data->widget) || !widget->clip)
       return;
 
    for (l = widget->member_objects; l; l = l->next)
-      evas_object_clip_unset(l->data);
+   {
+      if (!(child = ETK_WIDGET(evas_object_data_get(l->data, "etk_widget"))))
+      {
+         if (evas_object_clip_get(l->data) == widget->clip)
+            evas_object_clip_unset(l->data);
+      }
+      else if (child->clip)
+      {
+         if (child->clip == widget->clip)
+            etk_widget_clip_unset(child);
+         else
+         {
+            Evas_Object *c;
+
+            for (c = child->clip; c; c = evas_object_clip_get(c))
+            {
+               if (evas_object_clip_get(c) == widget->clip)
+               {
+                  evas_object_clip_unset(c);
+                  break;
+               }
+            }
+         }
+      }
+   }
+   widget->clip = NULL;
 }
 
 /* Called when the swallowed objet is removed from the list of swallowed 
objects of the widget */
===================================================================
RCS file: /cvsroot/enlightenment/e17/proto/etk/src/lib/etk_widget.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -3 -r1.5 -r1.6
--- etk_widget.h        29 Oct 2005 19:57:21 -0000      1.5
+++ etk_widget.h        31 Oct 2005 21:36:40 -0000      1.6
@@ -165,6 +165,9 @@
    void (*size_allocate)(Etk_Widget *widget, Etk_Geometry geometry);
    void (*move_resize)(Etk_Widget *widget, int x, int y, int w, int h);
 
+   void (*scroll_size_get)(Etk_Widget *widget, Etk_Size *scroll_size);
+   void (*scroll)(Etk_Widget *widget, int x, int y);
+
    void (*show)(Etk_Widget *widget);
    void (*hide)(Etk_Widget *widget);
    void (*key_down)(Etk_Widget *widget, Etk_Event_Key_Up_Down *event);
@@ -219,6 +222,7 @@
 void etk_widget_redraw_queue(Etk_Widget *widget);
 void etk_widget_size_request_set(Etk_Widget *widget, int w, int h);
 void etk_widget_size_request(Etk_Widget *widget, Etk_Size *size_requisition);
+void etk_widget_size_request_full(Etk_Widget *widget, Etk_Size 
*size_requisition, Etk_Bool hidden_has_no_size);
 void etk_widget_size_allocate(Etk_Widget *widget, Etk_Geometry geometry);
 
 void etk_widget_enter(Etk_Widget *widget);
@@ -246,6 +250,10 @@
 void etk_widget_member_object_stack_above(Etk_Widget *widget, Evas_Object 
*object, Evas_Object *above);
 void etk_widget_member_object_stack_below(Etk_Widget *widget, Evas_Object 
*object, Evas_Object *below);
 
+void etk_widget_clip_set(Etk_Widget *widget, Evas_Object *clip);
+void etk_widget_clip_unset(Etk_Widget *widget);
+Evas_Object *etk_widget_clip_get(Etk_Widget *widget);
+
 /** @} */
 
 #endif




-------------------------------------------------------
This SF.Net email is sponsored by the JBoss Inc.
Get Certified Today * Register for a JBoss Training Course
Free Certification Exam for All Training Attendees Through End of 2005
Visit http://www.jboss.com/services/certification for more information
_______________________________________________
enlightenment-cvs mailing list
enlightenment-cvs@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to