Author: rpmcruz Date: Thu Oct 11 19:04:48 2007 New Revision: 41393 URL: http://svn.opensuse.org/viewcvs/yast?rev=41393&view=rev Log: * src/YGPackageSelector.cc: speed up Patterns view. * src/ygtkratioboxh.h/c: bug fix #326144: the layout algorithm should be the same as yast-core. It was ignoring the insane yast some policies, including the layout-stretch (also called rubber-band) variable. * src/YGTable.cc: bug fix: Comunity Repos tool was showing descriptions on single click. Moved the event hooks to the different Table-like implementations, as they differ in subtlety. * src/YGWidget.h: added getDebugLabel() which is our replacement for YWidget::debugLabel() which is of little use for most widgets. * src/YGLayout.cc (YGAlignment): added align info to YGAlignment's getDebugLabel(). * src/YGUI.cc: improved YWidget Tree dialog (ctrl+alt+shift+T). * src/YGWidget.cc: added delay flag to emitEvent() (waits 250 ms then tries to send it if nothing is pending). * testcases: * tests/Layout-AlignStretch.ycp: the #326144 bug. * tests/MultiSelectionBox.ycp: the other bug mentioned. Added: trunk/gtk/tests/Layout-AlignStretch.ycp trunk/gtk/tests/MultiSelectionBox.ycp Modified: trunk/gtk/ChangeLog trunk/gtk/src/YGLayout.cc trunk/gtk/src/YGPackageSelector.cc trunk/gtk/src/YGProgressBar.cc trunk/gtk/src/YGTable.cc trunk/gtk/src/YGUI.cc trunk/gtk/src/YGWidget.cc trunk/gtk/src/YGWidget.h trunk/gtk/src/ygtkbargraph.c trunk/gtk/src/ygtkratiobox.c trunk/gtk/src/ygtkratiobox.h Modified: trunk/gtk/ChangeLog URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/ChangeLog?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/ChangeLog (original) +++ trunk/gtk/ChangeLog Thu Oct 11 19:04:48 2007 @@ -1,3 +1,29 @@ +2007-10-11 Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> + + * src/YGPackageSelector.cc: speed up Patterns view. + + * src/ygtkratioboxh.h/c: bug fix #326144: the layout algorithm + should be the same as yast-core. It was ignoring the insane yast + some policies, including the layout-stretch (also called rubber-band) + variable. + + * src/YGTable.cc: bug fix: Comunity Repos tool was showing descriptions + on single click. Moved the event hooks to the different Table-like + implementations, as they differ in subtlety. + + * src/YGWidget.h: added getDebugLabel() which is our replacement for + YWidget::debugLabel() which is of little use for most widgets. + * src/YGLayout.cc (YGAlignment): added align info to YGAlignment's + getDebugLabel(). + * src/YGUI.cc: improved YWidget Tree dialog (ctrl+alt+shift+T). + + * src/YGWidget.cc: added delay flag to emitEvent() (waits 250 ms + then tries to send it if nothing is pending). + + * testcases: + * tests/Layout-AlignStretch.ycp: the #326144 bug. + * tests/MultiSelectionBox.ycp: the other bug mentioned. + 2007-10-10 Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> * src/YGPackageSelector.cc: fixed bug #330467. Do a full match to Modified: trunk/gtk/src/YGLayout.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGLayout.cc?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGLayout.cc (original) +++ trunk/gtk/src/YGLayout.cc Thu Oct 11 19:04:48 2007 @@ -91,7 +91,8 @@ ygtk_ratio_box_set_child_packing (box, child->getLayout(), ychild->weight (dim), horiz_fill, vert_fill, 0); ygtk_ratio_box_set_child_expand (box, child->getLayout(), - child->isStretchable (dim)); + child->isStretchable (dim), + ychild->isLayoutStretch (dim)); YGWidget::sync_stretchable(); } @@ -226,6 +227,33 @@ virtual void moveChild (YWidget *, long, long) {}; // ignore + virtual string getDebugLabel() const + { + struct inner { + static const char *alignLabel (YAlignmentType align) + { + switch (align) { + case YAlignUnchanged: + return "unchanged"; + case YAlignBegin: + return "begin"; + case YAlignEnd: + return "end"; + case YAlignCenter: + return "center"; + } + return ""; /*not run*/ + } + }; + + string str; + str += inner::alignLabel (align [YD_HORIZ]); + str += " x "; + str += inner::alignLabel (align [YD_VERT]); + return str; + } + +private: // helper -- converts YWidget YAlignmentType to Gtk's align float static float yToGtkAlign (YAlignmentType align) { Modified: trunk/gtk/src/YGPackageSelector.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGPackageSelector.cc?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGPackageSelector.cc (original) +++ trunk/gtk/src/YGPackageSelector.cc Thu Oct 11 19:04:48 2007 @@ -1366,7 +1366,7 @@ GtkTreeModel *model = GTK_TREE_MODEL (store); g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (1)); - SET_PROGRESS (zyppPool().size <zypp::Package>(), 50) + SET_PROGRESS (zyppPool().size <zypp::Package>(), 200) GtkTreeIter iter; for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Package>(); it != zyppPool().byKindEnd <zypp::Package>(); it++) @@ -1390,7 +1390,7 @@ // we need to create the categories tree as we iterate packages map <string, GtkTreePath *> tree; - SET_PROGRESS (zyppPool().size <zypp::Package>(), 50) + SET_PROGRESS (zyppPool().size <zypp::Package>(), 80) GtkTreeIter iter, parent_iter; for (ZyppPool::const_iterator it = zyppPool().byKindBegin <zypp::Package>(); it != zyppPool().byKindEnd <zypp::Package>(); it++) @@ -1497,16 +1497,16 @@ // adding children packages const set <string> &packages = pattern->install_packages(); - for (set <string>::iterator pt1 = packages.begin(); - pt1 != packages.end(); pt1++) { - for (ZyppPool::const_iterator pt2 = - zyppPool().byKindBegin <zypp::Package>(); - pt2 != zyppPool().byKindEnd <zypp::Package>(); pt2++) { - ZyppSelectable sel = *pt2; - if (sel->name() == *pt1) { - gtk_tree_store_append (store, &package_iter, &pattern_iter); - loadPackageRow (model, &package_iter, sel); - } + for (ZyppPool::const_iterator pt2 = + zyppPool().byKindBegin <zypp::Package>(); + pt2 != zyppPool().byKindEnd <zypp::Package>(); pt2++) { + ZyppSelectable sel = *pt2; + for (set <string>::iterator pt1 = packages.begin(); + pt1 != packages.end(); pt1++) { + if (sel->name() == *pt1) { + gtk_tree_store_append (store, &package_iter, &pattern_iter); + loadPackageRow (model, &package_iter, sel); + } } } } Modified: trunk/gtk/src/YGProgressBar.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGProgressBar.cc?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGProgressBar.cc (original) +++ trunk/gtk/src/YGProgressBar.cc Thu Oct 11 19:04:48 2007 @@ -118,7 +118,7 @@ , YGWidget (this, parent, true, horizontal ? YGTK_TYPE_RATIO_HBOX : YGTK_TYPE_RATIO_VBOX, NULL) { - ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (getWidget()), TRUE); +// ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (getWidget()), TRUE); ygtk_ratio_box_set_spacing (YGTK_RATIO_BOX (getWidget()), 2); for (int i = 0; i < segments(); i++) { Modified: trunk/gtk/src/YGTable.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGTable.cc?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGTable.cc (original) +++ trunk/gtk/src/YGTable.cc Thu Oct 11 19:04:48 2007 @@ -29,13 +29,7 @@ gtk_tree_selection_set_mode (gtk_tree_view_get_selection ( GTK_TREE_VIEW (getWidget())), GTK_SELECTION_BROWSE); - if (opt.notifyMode.value()) { - g_signal_connect (G_OBJECT (getWidget()), "row-activated", - G_CALLBACK (activated_cb), y_widget); - if (opt.immediateMode.value()) - g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", - G_CALLBACK (selected_cb), y_widget); - } + // let the derivates do the event hooks. They have subtile differences. } void initModel (const vector <GType> &types, bool show_headers) @@ -82,12 +76,13 @@ } else if (type == G_TYPE_BOOLEAN) { // toggle button GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new(); + g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (col_nb)); g_object_set (renderer, "xalign", xalign, NULL); column = gtk_tree_view_column_new_with_attributes (header.c_str(), renderer, "active", col_nb, NULL); g_signal_connect (G_OBJECT (renderer), "toggled", - G_CALLBACK (toggled_cb), YGWidget::get (m_y_widget)); + G_CALLBACK (toggled_cb), this); } else if (type == GDK_TYPE_PIXBUF) { GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new(); @@ -226,38 +221,48 @@ } } - static void selected_cb (GtkTreeView *tree_view, YWidget* pThis) + // toggled by user (through clicking on the renderer or some other action) + void toggle (GtkTreePath *path, gint column) + { + IMPL + GtkTreeIter iter; + if (!gtk_tree_model_get_iter (getModel(), &iter, path)) + return; + gboolean state; + + gtk_tree_model_get (getModel(), &iter, column, &state, -1); + gtk_list_store_set (getStore(), &iter, column, !state, -1); + + emitEvent (YEvent::ValueChanged); + } + + static void selected_cb (GtkTreeView *tree_view, YGTableView* pThis) + { + IMPL + pThis->emitEvent (YEvent::SelectionChanged);//, true, true, true); + } + + static void selected_delayed_cb (GtkTreeView *tree_view, YGTableView* pThis) { IMPL - if (pThis->getNotify() && !YGUI::ui()->eventPendingFor(pThis)) - YGUI::ui()->sendEvent (new YWidgetEvent (pThis, YEvent::SelectionChanged)); + pThis->emitEvent (YEvent::SelectionChanged, true, true, false); } static void activated_cb (GtkTreeView *tree_view, GtkTreePath *path, - GtkTreeViewColumn *column, YWidget* pThis) + GtkTreeViewColumn *column, YGTableView* pThis) { IMPL - if (pThis->getNotify()) - YGUI::ui()->sendEvent (new YWidgetEvent (pThis, YEvent::Activated)); + pThis->emitEvent (YEvent::Activated); } static void toggled_cb (GtkCellRendererToggle *renderer, gchar *path_str, - YGWidget *pThis) + YGTableView *pThis) { IMPL - // Toggle the box - GtkTreeModel* model = ((YGTableView*) pThis)->getModel(); GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - gint *column = (gint*) g_object_get_data (G_OBJECT (renderer), "column"); - GtkTreeIter iter; - gtk_tree_model_get_iter (model, &iter, path); + gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), "column")); + pThis->toggle (path, column); gtk_tree_path_free (path); - - gboolean state; - gtk_tree_model_get (model, &iter, column, &state, -1); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, !state, -1); - - pThis->emitEvent (YEvent::ValueChanged); } }; @@ -284,6 +289,12 @@ YGUtils::tree_view_set_sortable (GTK_TREE_VIEW (getWidget()), 0); if (numCols() >= 3) gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (getWidget()), TRUE); + + g_signal_connect (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (activated_cb), (YGTableView*) this); + if (opt.immediateMode.value()) + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), (YGTableView*) this); } virtual void itemAdded (vector<string> elements, int index) @@ -335,6 +346,15 @@ insertColumn (1, "", G_TYPE_STRING); setSearchCol (1); // pixbuf column will be added later, if needed + + g_signal_connect (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (activated_cb), (YGTableView*) this); + if (opt.immediateMode.value()) + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), (YGTableView*) this); + else + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_delayed_cb), (YGTableView*) this); } // YSelectionBox @@ -381,7 +401,7 @@ { public: YGMultiSelectionBox (const YWidgetOpt &opt, YGWidget *parent, - const YCPString &label) + const YCPString &label) : YMultiSelectionBox (opt, label), YGTableView (this, parent, opt, label) { @@ -396,11 +416,11 @@ setSearchCol (2); // pixbuf column will be added later, if needed - // Besides the Toggle buttons, allow the user to also use space/enter - // and double click. - if (!getNotify()) - g_signal_connect_after (G_OBJECT (getWidget()), "row-activated", - G_CALLBACK (multi_activated_cb), this); + g_signal_connect (G_OBJECT (getWidget()), "cursor-changed", + G_CALLBACK (selected_cb), (YGTableView*) this); + // Let the user toggle, using space/enter or double click (not an event). + g_signal_connect_after (G_OBJECT (getWidget()), "row-activated", + G_CALLBACK (multi_activated_cb), this); } // YMultiSelectionBox @@ -470,16 +490,10 @@ } static void multi_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, - GtkTreeViewColumn *column, YGMultiSelectionBox* pThis) + GtkTreeViewColumn *column, YGMultiSelectionBox* pThis) { IMPL - GtkTreeIter iter; - if (!gtk_tree_model_get_iter (pThis->getModel(), &iter, path)) - return; - - gboolean state; - gtk_tree_model_get (pThis->getModel(), &iter, 0, &state, -1); - gtk_list_store_set (pThis->getStore(), &iter, 0, !state, -1); + pThis->toggle (path, 0); } YGWIDGET_IMPL_COMMON Modified: trunk/gtk/src/YGUI.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUI.cc?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGUI.cc (original) +++ trunk/gtk/src/YGUI.cc Thu Oct 11 19:04:48 2007 @@ -200,13 +200,14 @@ gtk_tree_store_append (store, &iter, parent_node); YContainerWidget *container = dynamic_cast <YContainerWidget *> (widget); - gchar *props = g_strdup_printf ("stretch: %d x %d - weight: %ld x %ld", - ygwidget->isStretchable (YD_HORIZ), - ygwidget->isStretchable (YD_VERT), widget->weight (YD_HORIZ), - widget->weight (YD_VERT)); + gchar *stretch = g_strdup_printf ("%d x %d", + ygwidget->isStretchable (YD_HORIZ), ygwidget->isStretchable (YD_VERT)); + gchar *weight = g_strdup_printf ("%ld x %ld", + widget->weight (YD_HORIZ), widget->weight (YD_VERT)); gtk_tree_store_set (store, &iter, 0, widget->widgetClass(), - 1, container ? "" : widget->debugLabel().c_str(), 2, props, -1); - g_free (props); + 1, ygwidget->getDebugLabel().c_str(), 2, stretch, 3, weight, -1); + g_free (stretch); + g_free (weight); if (container) for (int i = 0; i < container->numChildren(); i++) @@ -219,15 +220,15 @@ void dumpYastTree (YWidget *widget, GtkWindow *parent_window) { IMPL - GtkTreeStore *store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_STRING, - G_TYPE_STRING); + GtkTreeStore *store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING); dumpYastTree (widget, store, NULL); GtkWidget *dialog = gtk_dialog_new_with_buttons ("YWidgets Tree", parent_window, GtkDialogFlags (GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); - gtk_window_set_default_size (GTK_WINDOW (dialog), 400, 300); + gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 400); GtkWidget *view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); gtk_tree_view_append_column (GTK_TREE_VIEW (view), @@ -237,15 +238,19 @@ gtk_tree_view_column_new_with_attributes ("Label", gtk_cell_renderer_text_new(), "text", 1, NULL)); gtk_tree_view_append_column (GTK_TREE_VIEW (view), - gtk_tree_view_column_new_with_attributes ("Properties", + gtk_tree_view_column_new_with_attributes ("Stretch", gtk_cell_renderer_text_new(), "text", 2, NULL)); + gtk_tree_view_append_column (GTK_TREE_VIEW (view), + gtk_tree_view_column_new_with_attributes ("Weight", + gtk_cell_renderer_text_new(), "text", 3, NULL)); gtk_tree_view_expand_all (GTK_TREE_VIEW (view)); + gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (view), TRUE); GtkWidget *scroll_win = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll_win), GTK_SHADOW_OUT); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_win), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (scroll_win), view); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll_win); Modified: trunk/gtk/src/YGWidget.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGWidget.cc?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGWidget.cc (original) +++ trunk/gtk/src/YGWidget.cc Thu Oct 11 19:04:48 2007 @@ -92,12 +92,30 @@ gtk_widget_set_sensitive (getWidget(), enabled); } -void YGWidget::emitEvent (YEvent::EventReason reason, bool if_notify, - bool if_not_pending) +void YGWidget::emitEvent(YEvent::EventReason reason, bool if_notify, + bool if_not_pending, bool immediate) { - if ((!if_notify || m_y_widget->getNotify()) && - (!if_not_pending || !YGUI::ui()->eventPendingFor(m_y_widget))) - YGUI::ui()->sendEvent (new YWidgetEvent (m_y_widget, reason)); + struct inner + { + static gboolean dispatchEvent (gpointer data) + { + YWidgetEvent *event = (YWidgetEvent *) data; + if (!YGUI::ui()->eventPendingFor (event->widget())) + YGUI::ui()->sendEvent (event); + return FALSE; + } + }; + + if (!if_notify || m_y_widget->getNotify()) + { + if (!immediate) + g_timeout_add (250, inner::dispatchEvent, new YWidgetEvent (m_y_widget, reason)); + else if (!if_not_pending || !YGUI::ui()->eventPendingFor (m_y_widget)) + { + if (immediate) + YGUI::ui()->sendEvent (new YWidgetEvent (m_y_widget, reason)); + } + } } void YGWidget::setBorder (unsigned int border) @@ -134,6 +152,8 @@ YGWidget::get (parent)->sync_stretchable (m_y_widget); } +// JEEZ. WHEN the hell will yast-ui code fix their damn code. +#if 1 /* Checks everywhere in a container to see if there are children (so he is completely initialized) so that we may ask him for stretchable() because some YContainerWidgets crash when they don't have children. */ @@ -158,6 +178,12 @@ } return true; } +#else +static bool safe_stretchable (YWidget *widget) +{ + return true; +} +#endif bool YGWidget::isStretchable (YUIDimension dim) { Modified: trunk/gtk/src/YGWidget.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGWidget.h?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/YGWidget.h (original) +++ trunk/gtk/src/YGWidget.h Thu Oct 11 19:04:48 2007 @@ -20,6 +20,11 @@ virtual GtkWidget *getWidget() { return m_widget; } const char *getWidgetName() const { return const_cast <YWidget *> (m_y_widget)->widgetClass(); } + // YWidget::debugLabel() sucks for most widgets -- let's allow it to be overload + virtual string getDebugLabel() const + { // container debug labels are worse than useless + if (dynamic_cast <YContainerWidget *> (m_y_widget) == NULL) + return const_cast <YWidget *> (m_y_widget)->debugLabel(); return string(); } void show(); // containers should use this call rather than getWidget() @@ -34,7 +39,7 @@ // Event handling void emitEvent(YEvent::EventReason reason, bool if_notify = true, - bool if_not_pending = false); + bool if_not_pending = false, bool immediate = true); // Aesthicts void setBorder (unsigned int border); // in pixels Modified: trunk/gtk/src/ygtkbargraph.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkbargraph.c?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/ygtkbargraph.c (original) +++ trunk/gtk/src/ygtkbargraph.c Thu Oct 11 19:04:48 2007 @@ -15,7 +15,7 @@ static void ygtk_bar_graph_init (YGtkBarGraph *bar) { - ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (bar), TRUE); +// ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (bar), TRUE); bar->m_tooltips = gtk_tooltips_new(); gtk_container_set_border_width (GTK_CONTAINER (bar), 12); @@ -94,6 +94,7 @@ } // Set proportion + gtk_widget_set_size_request (box, 10, -1); // for homogeneous... ygtk_ratio_box_set_child_packing (YGTK_RATIO_BOX (bar), box, MAX (value, 1), TRUE, TRUE, 0); Modified: trunk/gtk/src/ygtkratiobox.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkratiobox.c?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/ygtkratiobox.c (original) +++ trunk/gtk/src/ygtkratiobox.c Thu Oct 11 19:04:48 2007 @@ -30,7 +30,7 @@ child_info->padding = padding; child_info->xfill = xfill; child_info->yfill = yfill; - child_info->fully_expandable = 0; + child_info->expand = 0; box->children = g_list_append (box->children, child_info); @@ -103,32 +103,34 @@ GtkRequisition *requisition, GtkOrientation orientation) { - gfloat ratios_sum = 0, max_ratio = 1; - GList* child; YGtkRatioBox* box = YGTK_RATIO_BOX (widget); + guint ratios_num = 0; + gfloat max_ratio = 0; + box->has_must_expand = FALSE; + GList* child; for (child = box->children; child; child = child->next) { YGtkRatioBoxChild* box_child = (YGtkRatioBoxChild*) child->data; if (!GTK_WIDGET_VISIBLE (box_child->widget)) continue; - if (box_child->ratio) { - ratios_sum += box_child->ratio; + if (box_child->ratio) + { max_ratio = MAX (max_ratio, box_child->ratio); + ratios_num++; } + if (box_child->must_expand) + box->has_must_expand = TRUE; } // If we want to calculate horizontal size, primary_req would be horizontal // length, while secondary the height. Idem for the inverse. guint primary_req = 0, secondary_req = 0; - gfloat pixels_per_percent = 0; + box->ratio_width = 0; for (child = box->children; child; child = child->next) { YGtkRatioBoxChild* box_child = (YGtkRatioBoxChild*) child->data; if (!GTK_WIDGET_VISIBLE (box_child->widget)) continue; - if (box_child->fully_expandable) - box_child->ratio = max_ratio; - GtkRequisition child_req; gtk_widget_size_request (box_child->widget, &child_req); @@ -142,17 +144,15 @@ sec_length = child_req.width; } - if (box->homogeneous && box_child->ratio) { - gfloat percent_of_whole = box_child->ratio / ratios_sum * 100; - pixels_per_percent = MAX (pixels_per_percent, prim_length / percent_of_whole); - } + if (box_child->ratio) + box->ratio_width = MAX (box->ratio_width, (prim_length * max_ratio) / box_child->ratio); else primary_req += prim_length; primary_req += box_child->padding + box->spacing; secondary_req = MAX (secondary_req, sec_length); } - primary_req += (guint) (pixels_per_percent * 100); + primary_req += box->ratio_width * ratios_num; guint border = GTK_CONTAINER (widget)->border_width * 2; primary_req += border*2; secondary_req += border*2; @@ -175,6 +175,7 @@ // a first loop to get some data for expansibles (ie. childs with weight) gfloat ratios_sum = 0; + guint expand_num = 0, max_ratio = 0; gint expansable_length; if (orientation == GTK_ORIENTATION_HORIZONTAL) expansable_length = allocation->width - border*2; @@ -188,15 +189,23 @@ if (!GTK_WIDGET_VISIBLE (box_child->widget)) continue; + if (box_child->expand) + expand_num++; if (box_child->ratio) + { ratios_sum += box_child->ratio; + max_ratio = MAX (max_ratio, box_child->ratio); + } - GtkRequisition child_req; - gtk_widget_get_child_requisition (box_child->widget, &child_req); - - if (box->homogeneous && box_child->ratio) - ; - else { + if (box_child->ratio) + { + if (box->has_must_expand) + expansable_length -= (box->ratio_width * box_child->ratio) / max_ratio; + } + else + { + GtkRequisition child_req; + gtk_widget_get_child_requisition (box_child->widget, &child_req); if (orientation == GTK_ORIENTATION_HORIZONTAL) expansable_length -= child_req.width; else @@ -223,17 +232,26 @@ GtkRequisition child_req; gtk_widget_get_child_requisition (box_child->widget, &child_req); - if (box->homogeneous && box_child->ratio) - length = 0; - else { + if (box_child->ratio) + length = box->ratio_width; + else + { if (orientation == GTK_ORIENTATION_HORIZONTAL) length = child_req.width; else length = child_req.height; } + // give extra size (honor stretch order) if (box_child->ratio) - length += ((box_child->ratio / ratios_sum) * expansable_length); + { + if (box->has_must_expand) + length = (box->ratio_width * box_child->ratio) / max_ratio; + else + length = (box_child->ratio * expansable_length) / ratios_sum; + } + else if (box_child->expand && (ratios_sum == 0 || box_child->must_expand)) + length += expansable_length / expand_num; if (orientation == GTK_ORIENTATION_HORIZONTAL) { child_alloc.x = child_pos; @@ -282,7 +300,8 @@ child_info->xfill = xfill; child_info->yfill = yfill; child_info->padding = padding; - child_info->fully_expandable = 0; + child_info->expand = 0; + child_info->must_expand = 0; if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box)) gtk_widget_queue_resize (child); @@ -306,17 +325,21 @@ if (xfill) *xfill = child_info->xfill; if (yfill) *yfill = child_info->yfill; if (padding) *padding = child_info->padding; - if (expand) *expand = child_info->fully_expandable; + if (expand) *expand = child_info->expand; } } void ygtk_ratio_box_set_child_expand (YGtkRatioBox *box, GtkWidget *child, - gboolean expand) + gboolean expand, gboolean must_expand) { YGtkRatioBoxChild *child_info; child_info = ygtk_ratio_get_child_info (box, child); if (child_info) - child_info->fully_expandable = expand; + { + child_info->expand = expand; + if (expand) + child_info->must_expand = must_expand; + } } void ygtk_ratio_box_set_child_ratio (YGtkRatioBox *box, GtkWidget *child, @@ -328,11 +351,6 @@ child_info->ratio = ratio; } -void ygtk_ratio_box_set_homogeneous (YGtkRatioBox *box, gboolean homogeneous) -{ - box->homogeneous = homogeneous; -} - void ygtk_ratio_box_set_spacing (YGtkRatioBox *box, gint spacing) { box->spacing = spacing; @@ -369,10 +387,9 @@ ygtk_ratio_box_size_allocate (widget, allocation, GTK_ORIENTATION_HORIZONTAL); } -GtkWidget* ygtk_ratio_hbox_new (gboolean homogeneous, gint spacing) +GtkWidget* ygtk_ratio_hbox_new (gint spacing) { YGtkRatioBox* box = (YGtkRatioBox*) g_object_new (YGTK_TYPE_RATIO_HBOX, NULL); - box->homogeneous = homogeneous; box->spacing = spacing; return GTK_WIDGET (box); } @@ -406,10 +423,9 @@ ygtk_ratio_box_size_allocate (widget, allocation, GTK_ORIENTATION_VERTICAL); } -GtkWidget* ygtk_ratio_vbox_new (gboolean homogeneous, gint spacing) +GtkWidget* ygtk_ratio_vbox_new (gint spacing) { YGtkRatioBox* box = (YGtkRatioBox*) g_object_new (YGTK_TYPE_RATIO_VBOX, NULL); - box->homogeneous = homogeneous; box->spacing = spacing; return GTK_WIDGET (box); } Modified: trunk/gtk/src/ygtkratiobox.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkratiobox.h?rev=41393&r1=41392&r2=41393&view=diff ============================================================================== --- trunk/gtk/src/ygtkratiobox.h (original) +++ trunk/gtk/src/ygtkratiobox.h Thu Oct 11 19:04:48 2007 @@ -10,6 +10,20 @@ behave just the same as a GtkBox if you give 0 for not expand and 1 to. */ +/* + Quirks (cause of yast-core): + if one of the children has certain special properties, then only widgets with + the same properties will be expanded. These are, by order: + both stretch and rubber-band + both stretch and weight + weight + stretch + + We use different naming: + stretch = expand + rubber-band or layout-stretch = must expand + weight = ratio +*/ #ifndef YGTK_RATIO_BOX_H #define YGTK_RATIO_BOX_H @@ -37,7 +51,8 @@ // private (read-only): GList *children; gint16 spacing; - gboolean homogeneous; + guint ratio_width; // the width of ratio widgets + gboolean has_must_expand; // cache } YGtkRatioBox; typedef struct _YGtkRatioBoxClass @@ -53,23 +68,22 @@ gfloat ratio; guint xfill : 1; guint yfill : 1; - guint fully_expandable : 1; + guint expand : 1; // twilight zone flag; use ratio + guint must_expand : 1; // higher order expand } YGtkRatioBoxChild; GType ygtk_ratio_box_get_type (void) G_GNUC_CONST; -void ygtk_ratio_box_set_homogeneous (YGtkRatioBox *box, gboolean homogeneous); void ygtk_ratio_box_set_spacing (YGtkRatioBox *box, gint spacing); void ygtk_ratio_box_pack (YGtkRatioBox *box, GtkWidget *child, gfloat ratio, gboolean xfill, gboolean yfill, guint padding); -// Since ratio may be of any value, this function is provided to let programmers -// specify this child to be fully expandable (avoid its use; stick to some fixed range) -// NOTE: when disabling expand, you should call child_packing to define a ratio -// since it is lost. +// If you don't want to use ratios, you can use the ordinary expand flag. NOTE: +// If some other child has ratio > 0, this one won't expand. +// All this mess is so we can conform with yast-core. void ygtk_ratio_box_set_child_expand (YGtkRatioBox *box, GtkWidget *child, - gboolean expand); + gboolean expand, gboolean must_expand); void ygtk_ratio_box_set_child_ratio (YGtkRatioBox *box, GtkWidget *child, gfloat ratio); @@ -80,7 +94,7 @@ void ygtk_ratio_box_get_child_packing (YGtkRatioBox *box, GtkWidget *child, gfloat *ratio, gboolean *xfill, gboolean *yfill, guint *padding, - gboolean *fully_expandable); + gboolean *expandable); /* RatioHBox */ @@ -106,7 +120,7 @@ YGtkRatioBoxClass parent_class; } YGtkRatioHBoxClass; -GtkWidget* ygtk_ratio_hbox_new (gboolean homogeneous, gint spacing); +GtkWidget* ygtk_ratio_hbox_new (gint spacing); GType ygtk_ratio_hbox_get_type (void) G_GNUC_CONST; /* RatioVBox */ @@ -133,7 +147,7 @@ YGtkRatioBoxClass parent_class; } YGtkRatioVBoxClass; -GtkWidget* ygtk_ratio_vbox_new (gboolean homogeneous, gint spacing); +GtkWidget* ygtk_ratio_vbox_new (gint spacing); GType ygtk_ratio_vbox_get_type (void) G_GNUC_CONST; G_END_DECLS Added: trunk/gtk/tests/Layout-AlignStretch.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/tests/Layout-AlignStretch.ycp?rev=41393&view=auto ============================================================================== --- trunk/gtk/tests/Layout-AlignStretch.ycp (added) +++ trunk/gtk/tests/Layout-AlignStretch.ycp Thu Oct 11 19:04:48 2007 @@ -0,0 +1,15 @@ +// alignment (test case for inst_productsources bug) +{ +UI::OpenDialog( + `VBox( + `HBox( + `PushButton ("Fixed"), + `Bottom (`PushButton ("Test")) + ), + `VWeight( 1, `MultiLineEdit("Description", "bla bla") ) + ) +); +UI::UserInput(); +UI::CloseDialog(); +} + Added: trunk/gtk/tests/MultiSelectionBox.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/tests/MultiSelectionBox.ycp?rev=41393&view=auto ============================================================================== --- trunk/gtk/tests/MultiSelectionBox.ycp (added) +++ trunk/gtk/tests/MultiSelectionBox.ycp Thu Oct 11 19:04:48 2007 @@ -0,0 +1,16 @@ +// MultiSelectionBox -- test notify flag +{ +list items = + [ "Spaghetti", "Steak Sandwich", "Chili", "Salami Baguette" ]; + +UI::OpenDialog ( + `MinSize (30, 10, + `MultiSelectionBox (`id(`list), `opt (`notify), + "Plates", items) + ) + ); + +UI::UserInput(); +UI::CloseDialog(); +} + -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org