libergtk/src/erGtkSelectionList.c File Reference

ereader gtk library - control a group of GtkToggleButton objects, similar to a radiobutton. More...

#include <gtk/gtk.h>
#include "ergtklog.h"
#include "erGtkSelectionGroup.h"
#include "erGtkSelectionList.h"
#include "erGtkToggleButton.h"

Go to the source code of this file.

Functions

static void ergtk_selection_list_class_init (erGtkSelectionListClass *klass)
static void ergtk_selection_list_init (erGtkSelectionList *selection)
static GtkToggleButton * create_button (const erGtkSelectionList_displayAs_e display_as, const gchar *label_text)
static guint button_height_from_display_as (const erGtkSelectionList_displayAs_e display_as)
static void add_buttons_to_screen_layout (erGtkSelectionList *item, GtkVBox *parent_vbox, const GSList *buttons, const guint first_item, const guint max_height, guint *allocated_buttons, guint *allocated_height)
GtkWidget * ergtk_selection_list_new (const erGtkSelectionList_displayAs_e display_as, const gchar *title, const gchar *instruction, const gchar **item_names, const guint max_height, guint *allocated_items, guint *allocated_height)
GtkWidget * ergtk_selection_list_new_from_master (const erGtkSelectionList *master, const guint first_item, const guint max_height, guint *allocated_items, guint *allocated_height)
void ergtk_selection_list_show_titlebar (const erGtkSelectionList *item, const gboolean show)
GType ergtk_selection_list_get_type (void)

Variables

static erGtkSelectionGroupClassg_parent_class = NULL


Detailed Description

ereader gtk library - control a group of GtkToggleButton objects, similar to a radiobutton.

Ensure only the allowed number of buttons is selected at any time. Note: no relation with the standard GTK class GtkSelection.

Copyright (C) 2007 iRex Technologies B.V. All rights reserved.

Definition in file erGtkSelectionList.c.


Function Documentation

static void add_buttons_to_screen_layout ( erGtkSelectionList item,
GtkVBox *  parent_vbox,
const GSList *  buttons,
const guint  first_item,
const guint  max_height,
guint *  allocated_buttons,
guint *  allocated_height 
) [static]

Definition at line 355 of file erGtkSelectionList.c.

00362 {
00363     guint         item_height = 0;
00364     guint         buttons_added = 0;
00365     GtkWidget*    hbox = NULL;
00366 
00367     GtkWidget*    widget;
00368     GtkWidget*    button;
00369     const GSList* button_node;
00370 
00371     const guint   num_buttons      = g_slist_length((GSList*)buttons);
00372     const guint   buttons_per_line = (item->display_as == esl_TextButton) ? 4 : 1;
00373     guint         button_height    = button_height_from_display_as(item->display_as);
00374 
00375     guint lines_needed;
00376     guint lines_available;
00377     guint lines_used;
00378     guint line;
00379 
00380     if (first_button > 0)
00381     {
00382         // continuation_before
00383         widget = gtk_label_new(ERGTK_SELECTION_LIST_CONTINUATION_TEXT);
00384         gtk_widget_show(widget);
00385         gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_CONTINUATION_STYLE);
00386         gtk_widget_set_size_request(widget, -1, button_height);
00387         gtk_misc_set_padding(GTK_MISC(widget), ERGTK_SELECTION_LIST_CONTINUATION_H_PADDING, 0);
00388         gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.0);
00389         gtk_box_pack_start(GTK_BOX(parent_vbox), widget, FALSE, FALSE, 0);
00390         item_height += button_height;
00391     }
00392 
00393     // calculate how many lines with buttons to show
00394     lines_available = (max_height - item_height + ERGTK_SELECTION_LIST_BUTTON_V_SPACING) / (button_height + ERGTK_SELECTION_LIST_BUTTON_V_SPACING);
00395     lines_needed    = ((num_buttons - first_button) + (buttons_per_line - 1)) / buttons_per_line;
00396     if (lines_needed <= lines_available)
00397     {
00398         // use the only the lines we need
00399         lines_used = lines_needed;
00400     }
00401     else
00402     {
00403         // use all available lines but one, last one used for continuaton_after
00404         lines_used = lines_available - 1;
00405 
00406         // continuation_after
00407         widget = gtk_label_new(ERGTK_SELECTION_LIST_CONTINUATION_TEXT);
00408         gtk_widget_show(widget);
00409         gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_CONTINUATION_STYLE);
00410         gtk_widget_set_size_request(widget, -1, button_height);
00411         gtk_misc_set_padding(GTK_MISC(widget), ERGTK_SELECTION_LIST_CONTINUATION_H_PADDING, 0);
00412         gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.0);
00413         gtk_box_pack_end(GTK_BOX(parent_vbox), widget, FALSE, FALSE, 0);
00414         item_height += button_height;
00415     }
00416 
00417     // add buttons
00418     line = 0;
00419     for ( button_node  = g_slist_nth((GSList*)buttons, first_button) ;
00420           button_node != NULL ;
00421           button_node  = g_slist_next(button_node) )
00422     {
00423         // we have another button
00424         button = GTK_WIDGET(button_node->data);
00425         gtk_widget_show(button);
00426 
00427         if (buttons_added % buttons_per_line == 0)
00428         {
00429             // need a new line to show this button
00430             if (line < lines_used)
00431             {
00432                 // add a new line
00433                 line++;
00434                 if (buttons_per_line == 1)
00435                 {
00436                     // add button directly
00437                     gtk_box_pack_start(GTK_BOX(parent_vbox), button, FALSE, FALSE, 0);
00438                     item_height += button_height;
00439                     buttons_added++;
00440                 }
00441                 else
00442                 {
00443                     // create a new hbox to pack these buttons
00444                     hbox = gtk_hbox_new(FALSE, ERGTK_SELECTION_LIST_BUTTON_H_SPACING);
00445                     gtk_widget_show(hbox);
00446                     gtk_box_pack_start(GTK_BOX(parent_vbox), hbox, FALSE, FALSE, 0);
00447                     item_height += button_height;
00448 
00449                     // add button to hbox
00450                     gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
00451                     buttons_added++;
00452                 }
00453             }
00454         }
00455         else
00456         {
00457             // append button to current line
00458             gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
00459             buttons_added++;
00460         }
00461     }
00462 
00463     // correct for no spacing before the first widget added to parent_vbox
00464     if (item_height >= ERGTK_SELECTION_LIST_BUTTON_V_SPACING)
00465     {
00466         item_height -= ERGTK_SELECTION_LIST_BUTTON_V_SPACING;
00467     }
00468 
00469     // report what we've done
00470     *allocated_buttons = buttons_added;
00471     *allocated_height  = item_height;
00472 }

Here is the call graph for this function:

static guint button_height_from_display_as ( const erGtkSelectionList_displayAs_e  display_as  )  [static]

Definition at line 315 of file erGtkSelectionList.c.

00316 {
00317     guint height = 0;
00318 
00319     switch (display_as)
00320     {
00321         case esl_Checklist:
00322             height = ERGTK_SELECTION_LIST_CHECKBUTTON_HEIGHT;
00323             break;
00324 
00325         case esl_RadioButton:
00326             height = ERGTK_SELECTION_LIST_RADIOBUTTON_HEIGHT;
00327             break;
00328 
00329         case esl_TextButton:
00330             height = ERGTK_SELECTION_LIST_TEXTBUTTON_HEIGHT;
00331             break;
00332             
00333         default:
00334             ;  // ignore
00335     }
00336     
00337     return height;
00338 }

static GtkToggleButton * create_button ( const erGtkSelectionList_displayAs_e  display_as,
const gchar *  label_text 
) [static]

Definition at line 283 of file erGtkSelectionList.c.

00284 {
00285     GtkWidget*  widget = NULL;
00286     const guint button_height = button_height_from_display_as(display_as);
00287 
00288     switch (display_as)
00289     {
00290         case esl_Checklist:
00291             widget = gtk_check_button_new_with_label(label_text);
00292             gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_CHECKBUTTON_STYLE);
00293             gtk_widget_set_size_request(widget, -1, button_height);
00294             break;
00295 
00296         case esl_RadioButton:
00297             widget = gtk_check_button_new_with_label(label_text);
00298             gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_RADIOBUTTON_STYLE);
00299             gtk_widget_set_size_request(widget, -1, button_height);
00300             break;
00301 
00302         case esl_TextButton:
00303         default:
00304             widget = ergtk_toggle_button_new_with_label(label_text);
00305             gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_TEXTBUTTON_STYLE);
00306             gtk_widget_set_size_request(widget, ERGTK_SELECTION_LIST_TEXTBUTTON_WIDTH, button_height);
00307     }
00308 
00309     GtkToggleButton* button = GTK_TOGGLE_BUTTON(widget);
00310     gtk_toggle_button_set_active(button, FALSE);
00311 
00312     return button;
00313 }

Here is the call graph for this function:

static void ergtk_selection_list_class_init ( erGtkSelectionListClass klass  )  [static]

Definition at line 515 of file erGtkSelectionList.c.

00516 {
00517     // remember parent class struct, needed for chaining up to parent class
00518     g_parent_class = g_type_class_peek_parent(klass);
00519 
00520     // overload some virtual methods
00521 }

GType ergtk_selection_list_get_type ( void   ) 

Definition at line 490 of file erGtkSelectionList.c.

00491 {
00492     static GType class_type = 0;
00493 
00494     if (class_type == 0)
00495     {
00496         static const GTypeInfo class_info =
00497         {
00498             sizeof(erGtkSelectionListClass),
00499             NULL,               /* base_init */
00500             NULL,               /* base_finalize */
00501             (GClassInitFunc) ergtk_selection_list_class_init,
00502             NULL,               /* class_finalize */
00503             NULL,               /* class_data */
00504             sizeof(erGtkSelectionList),
00505             0,                  /* n_preallocs */
00506             (GInstanceInitFunc) ergtk_selection_list_init,
00507         };
00508 
00509         class_type = g_type_register_static(ERGTK_SELECTION_GROUP_TYPE, "erGtkSelectionList", &class_info, 0);
00510     }
00511     return class_type;
00512 }

Here is the call graph for this function:

static void ergtk_selection_list_init ( erGtkSelectionList selection  )  [static]

Definition at line 524 of file erGtkSelectionList.c.

00525 {
00526     g_return_if_fail(ERGTK_IS_SELECTION_LIST(item));
00527 
00528     // set object defaults
00529     item->dispose_has_run = FALSE;
00530     item->display_as      = esl_TextButton;
00531     item->titlebar        = NULL;
00532 }

GtkWidget* ergtk_selection_list_new ( const erGtkSelectionList_displayAs_e  display_as,
const gchar *  title,
const gchar *  instruction,
const gchar **  item_names,
const guint  max_height,
guint *  allocated_items,
guint *  allocated_height 
)

Create a new erGtkSelectionList object

Parameters:
in display_as: layout of selection list object
in title: text to be displayed in the object's title bar
in instruction: text to be displayed above the selection items
in item_names: NULL-terminated array of strings to be displayed on the selection items
in max_height: maximum height of the object, measured in pixels
out allocated_items: number of selection items displayed in the new list
out allocated_height: number of pixels required to display the new list
Returns:
reference to created widget

Definition at line 69 of file erGtkSelectionList.c.

00076 {
00077     int               i;
00078     const gchar**     cpp;
00079     guint             height;
00080     guint             num_items = 0;
00081     guint             item_height = 0;
00082     GtkToggleButton** button_tbl = NULL;
00083     guint             items_allocated = 0;
00084     gboolean          instruction_added = FALSE;
00085 
00086     GtkWidget*        widget;
00087     GtkWidget*        alignment;
00088     GtkWidget*        background;
00089     GtkWidget*        vbox;
00090 
00091     LOGPRINTF("entry: title [%s]", title);
00092 
00093     // create new object
00094     erGtkSelectionList* item = (erGtkSelectionList*) g_object_new(ERGTK_SELECTION_LIST_TYPE, NULL);
00095     gtk_widget_show(GTK_WIDGET(item));
00096     item->display_as = display_as;
00097 
00098     // create buttons for all selection items (including the items that will not be displayed)
00099     for (cpp = item_names ; *cpp != NULL ; cpp++)
00100     {
00101         num_items++;
00102     }
00103     button_tbl = g_new0(GtkToggleButton*, num_items + 1);
00104     g_assert(button_tbl != NULL);
00105     for (i = 0 ; i < num_items ; i++)
00106     {
00107         button_tbl[i] = create_button(display_as, item_names[i]);
00108     }
00109     button_tbl[i] = NULL;
00110 
00111     // append buttons to selection group (parent class)
00112     g_parent_class->add_buttons(&(item->parent), button_tbl);
00113 
00114     // create screen objects
00115     //
00116     // widget hierarchy:
00117     //   item (erGtkSelectionList inherits from GtkEventBox)
00118     //     |-- vbox
00119     //           |
00120     widget = gtk_vbox_new(FALSE, ERGTK_SELECTION_LIST_TITLE_SPACING);
00121     gtk_widget_show(widget);
00122     gtk_container_add(GTK_CONTAINER(item), widget);
00123     vbox = widget;
00124     //           |
00125     //           |   #  title
00126     //           |-- titlebar
00127     //           |     |-- label
00128     //           |
00129     widget = gtk_event_box_new();
00130     gtk_widget_show(widget);
00131     gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_TITLE_BACKGROUND_STYLE);
00132     gtk_widget_set_size_request(widget, -1, ERGTK_SELECTION_LIST_TITLE_HEIGHT);
00133     gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
00134     item_height += ERGTK_SELECTION_LIST_TITLE_HEIGHT;
00135     item->titlebar = widget;
00136     //
00137     widget = gtk_label_new(title);
00138     gtk_widget_show(widget);
00139     gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_TITLE_TEXT_STYLE);
00140     gtk_misc_set_padding(GTK_MISC(widget), ERGTK_SELECTION_LIST_H_PADDING, 0);
00141     gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
00142     gtk_container_add(GTK_CONTAINER(item->titlebar), widget);
00143     //           |
00144     //           |   #  selection list
00145     //           |-- background
00146     //                 |-- alignment
00147     //                       |-- vbox
00148     //                             |
00149     widget = gtk_event_box_new();
00150     gtk_widget_show(widget);
00151     gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_BACKGROUND_STYLE);
00152     gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
00153     item_height += ERGTK_SELECTION_LIST_TITLE_SPACING;
00154     background = widget;
00155     //
00156     widget = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
00157     gtk_widget_show(widget);
00158     gtk_alignment_set_padding(GTK_ALIGNMENT(widget),
00159                               ERGTK_SELECTION_LIST_V_PADDING, ERGTK_SELECTION_LIST_V_PADDING,
00160                               ERGTK_SELECTION_LIST_H_PADDING, ERGTK_SELECTION_LIST_H_PADDING);
00161     gtk_container_add(GTK_CONTAINER(background), widget);
00162     item_height += 2 * ERGTK_SELECTION_LIST_V_PADDING;
00163     alignment = widget;
00164     //
00165     widget = gtk_vbox_new(FALSE, ERGTK_SELECTION_LIST_BUTTON_V_SPACING);
00166     gtk_widget_show(widget);
00167     gtk_container_add(GTK_CONTAINER(alignment), widget);
00168     vbox = widget;
00169     //                             |-- [instruction]
00170     //                             |
00171     if (instruction  &&  instruction[0] != '\0')
00172     {
00173         instruction_added = TRUE;
00174         widget = gtk_label_new(instruction);
00175         gtk_widget_show(widget);
00176         gtk_widget_set_name(widget, ERGTK_SELECTION_LIST_INSTRUCTION_STYLE);
00177         gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
00178         gtk_box_pack_start(GTK_BOX(vbox), widget, FALSE, FALSE, 0);
00179         item_height += ERGTK_SELECTION_LIST_INSTRUCTION_HEIGHT;
00180     }
00181     //                             |-- buttons (0 ..)
00182     add_buttons_to_screen_layout( item,
00183                                   GTK_VBOX(vbox),
00184                                   item->parent.buttons,
00185                                   0,
00186                                   max_height - item_height,
00187                                   &items_allocated,
00188                                   &height );
00189     item_height += height;
00190     //
00191     if (instruction_added  &&  items_allocated > 0)
00192     {
00193         item_height += ERGTK_SELECTION_LIST_BUTTON_V_SPACING;
00194     }
00195 
00196     // that's all folks ..
00197     *allocated_items  = items_allocated;
00198     *allocated_height = item_height;
00199     g_free(button_tbl);
00200     if (item_height <= max_height)
00201     {
00202         return GTK_WIDGET(item);
00203     }
00204     else
00205     {
00206         gtk_widget_destroy(GTK_WIDGET(item));
00207         return NULL;
00208     }
00209 }

Here is the call graph for this function:

GtkWidget* ergtk_selection_list_new_from_master ( const erGtkSelectionList master,
const guint  first_item,
const guint  max_height,
guint *  allocated_items,
guint *  allocated_height 
)

Create a new erGtkSelectionList object as extension from another (master) object

Parameters:
in master: the master erGtkSelectionList object
in first_item: index (0 ..) of first item displayed
in max_height: maximum height of the object, measured in pixels
out allocated_items: number of selection items displayed in the new list
out allocated_height: number of pixels required to display the new list
Returns:
reference to created widget

Definition at line 212 of file erGtkSelectionList.c.

00217 {
00218     g_return_val_if_fail(ERGTK_IS_SELECTION_LIST(master), FALSE);
00219 
00220     guint      height;
00221     guint      item_height = 0;
00222     guint      items_allocated = 0;
00223     
00224     GtkWidget* widget;
00225     GtkWidget* alignment;
00226     GtkWidget* vbox;
00227 
00228     // create new object
00229     erGtkSelectionList* item = (erGtkSelectionList*) g_object_new(ERGTK_SELECTION_LIST_TYPE, NULL);
00230     item->display_as = master->display_as;
00231     gtk_widget_show(GTK_WIDGET(item));
00232 
00233     // create screen objects
00234     //
00235     // widget hierarchy:
00236     //   item (erGtkSelectionList inherits from GtkEventBox)
00237     //     |
00238     gtk_widget_set_name(GTK_WIDGET(item), ERGTK_SELECTION_LIST_BACKGROUND_STYLE);
00239     //     |
00240     //     |   #  selection list
00241     //     |-- alignment
00242     //           |-- vbox
00243     //                 |
00244     widget = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
00245     gtk_widget_show(widget);
00246     gtk_alignment_set_padding(GTK_ALIGNMENT(widget),
00247                               ERGTK_SELECTION_LIST_V_PADDING, ERGTK_SELECTION_LIST_V_PADDING,
00248                               ERGTK_SELECTION_LIST_H_PADDING, ERGTK_SELECTION_LIST_H_PADDING);
00249     gtk_container_add(GTK_CONTAINER(item), widget);
00250     item_height += 2 * ERGTK_SELECTION_LIST_V_PADDING;
00251     alignment = widget;
00252     //
00253     widget = gtk_vbox_new(FALSE, ERGTK_SELECTION_LIST_BUTTON_V_SPACING);
00254     gtk_widget_show(widget);
00255     gtk_container_add(GTK_CONTAINER(alignment), widget);
00256     vbox = widget;
00257     //                 |
00258     //                 |-- buttons (0 ..)
00259     add_buttons_to_screen_layout( item,
00260                                   GTK_VBOX(vbox),
00261                                   master->parent.buttons,
00262                                   first_item,
00263                                   max_height,
00264                                   &items_allocated,
00265                                   &height);
00266     item_height += height;
00267 
00268     // that's all folks ..
00269     *allocated_items  = items_allocated;
00270     *allocated_height = item_height;
00271     if (item_height <= max_height)
00272     {
00273         return GTK_WIDGET(item);
00274     }
00275     else
00276     {
00277         gtk_widget_destroy(GTK_WIDGET(item));
00278         return NULL;
00279     }
00280 }

Here is the call graph for this function:

void ergtk_selection_list_show_titlebar ( const erGtkSelectionList item,
const gboolean  show 
)

Show or hide the title bar

Parameters:
in item: the erGtkSelectionList object
in show: TRUE/FALSE = show/hide title bar
Returns:
--

Definition at line 474 of file erGtkSelectionList.c.

00475 {
00476     g_return_if_fail(item != NULL);
00477     g_return_if_fail(ERGTK_IS_SELECTION_LIST(item));
00478 
00479     if (show)
00480     {
00481         gtk_widget_show(item->titlebar);
00482     }
00483     else
00484     {
00485         gtk_widget_hide(item->titlebar);
00486     }
00487 }


Variable Documentation

Definition at line 42 of file erGtkSelectionList.c.


Generated on Sun Dec 14 17:12:36 2008 by  doxygen 1.5.6