ergtklistview.c File Reference

ereader gtk library - GtkTreeView object adapted for ereader system More...

#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <math.h>
#include <gdk/gdkkeysyms.h>
#include "gtk/gtkprivate.h"
#include "ergtk_log.h"
#include "ergtklistview.h"
Include dependency graph for ergtklistview.c:

Go to the source code of this file.

Functions

static void add_move_binding (GtkBindingSet *binding_set, guint keyval, GdkModifierType modmask, erGtkListViewKeyPress navigate)
static void on_realize (GtkWidget *widget)
static gboolean on_pre_move_cursor (erGtkListView *er_listview, erGtkListViewKeyPress navigate)
static void on_style_set (GtkWidget *widget, GtkStyle *previous_style)
static void on_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
static gboolean on_button_press_event (GtkWidget *widget, GdkEventButton *event)
static gboolean on_button_release_event (GtkWidget *widget, GdkEventButton *event)
static gboolean on_motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
static void on_column_notify_title (GObject *object, GParamSpec *arg1, gpointer user_data)
static gboolean on_focus_in (GtkWidget *widget, gpointer data)
static gboolean on_focus_out (GtkWidget *widget, gpointer data)
static void ergtk_list_view_class_init (erGtkListViewClass *klass)
static void ergtk_list_view_init (erGtkListView *er_listview)
GType ergtk_list_view_get_type (void)
GtkWidget * ergtk_list_view_new (void)
GtkWidget * ergtk_list_view_new_with_model (GtkTreeModel *model)
gint ergtk_list_view_append_column (erGtkListView *er_listview, GtkTreeViewColumn *column)
void ergtk_list_view_get_cursor (erGtkListView *er_listview, gint *row)
void ergtk_list_view_get_view_size (erGtkListView *er_listview, gint *num_rows, gint *num_items)
void ergtk_list_view_set_cursor (erGtkListView *er_listview, gint row)
void ergtk_list_view_set_focus_mode (erGtkListView *er_listview, gboolean focus_in, gboolean focus_out)
void ergtk_list_view_set_row_height (erGtkListView *er_listview, gint row_height)

Variables

static GtkTreeViewClass * g_parent_class = NULL
static guint pre_move_signal = 0
static guint navigate_cursor_signal = 0

Detailed Description

ereader gtk library - GtkTreeView object adapted for ereader system

Definition in file ergtklistview.c.


Function Documentation

static void add_move_binding ( GtkBindingSet *  binding_set,
guint  keyval,
GdkModifierType  modmask,
erGtkListViewKeyPress  navigate 
) [static]

Definition at line 857 of file ergtklistview.c.

Referenced by ergtk_list_view_class_init().

00861 {
00862     gtk_binding_entry_add_signal(binding_set, keyval, modmask,
00863                                  "pre-move-cursor", 1,
00864                                  G_TYPE_ENUM, navigate);
00865 
00866     gtk_binding_entry_add_signal(binding_set, keyval, GDK_SHIFT_MASK,
00867                                  "pre-move-cursor", 1,
00868                                  G_TYPE_ENUM, navigate);
00869 
00870     if ((modmask & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
00871     {
00872         return;
00873     }
00874 
00875     gtk_binding_entry_add_signal(binding_set, keyval, GDK_CONTROL_MASK | GDK_SHIFT_MASK,
00876                                  "pre-move-cursor", 1,
00877                                  G_TYPE_ENUM, navigate);
00878 
00879     gtk_binding_entry_add_signal(binding_set, keyval, GDK_CONTROL_MASK,
00880                                  "pre-move-cursor", 1,
00881                                  G_TYPE_ENUM, navigate);
00882 }

Here is the caller graph for this function:

gint ergtk_list_view_append_column ( erGtkListView er_listview,
GtkTreeViewColumn *  column 
)

Definition at line 233 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, label, LOGPRINTF, on_column_notify_title(), and widget.

Referenced by create_back_listview(), create_contentview(), create_listview(), and create_settingsview().

00235 {
00236     g_return_val_if_fail( ERGTK_IS_LIST_VIEW(er_listview), 0 );
00237     g_return_val_if_fail( GTK_IS_TREE_VIEW_COLUMN(column), 0 );
00238 
00239     const gchar *title    = gtk_tree_view_column_get_title(column);
00240     GtkTreeView *treeview = (GtkTreeView *) er_listview;
00241 
00242     gint              num_columns    = 0;     // return value
00243     GtkWidget         *widget        = NULL;
00244     GtkWidget         *label         = NULL;
00245     GtkWidget         *event_box     = NULL;
00246     GtkBox            *vbox          = NULL;
00247     const gchar       *listview_name = gtk_widget_get_name( (GtkWidget*)er_listview );
00248     gchar             *header_name   = g_strdup_printf("%s-header", listview_name);
00249 
00250     LOGPRINTF("entry: title [%s]", title);
00251 
00252     // insert filler column for spacing
00253     if ( gtk_tree_view_get_column(treeview, 0) != NULL )
00254     {
00255        GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
00256        g_object_set( G_OBJECT(renderer),
00257                      "xpad", 0,
00258                      "ypad", 0,
00259                      "text", "",
00260                      NULL );
00261        GtkTreeViewColumn *filler_column = gtk_tree_view_column_new_with_attributes( "", renderer, NULL );
00262        gtk_tree_view_column_set_sizing(filler_column, GTK_TREE_VIEW_COLUMN_FIXED);
00263        gtk_tree_view_append_column(treeview, filler_column);
00264     }
00265 
00266     // set custom header for column
00267     if (title)
00268     {
00269         widget = gtk_tree_view_column_get_widget(column);
00270         if (widget == NULL)
00271         {
00272             //   column
00273             //     |-- widget vbox
00274             //           |-- label
00275             //           |-- event_box
00276             //
00277             widget = gtk_vbox_new(FALSE, 0);
00278             vbox = GTK_BOX(widget);
00279             //
00280             label = gtk_label_new( title );
00281             gtk_widget_set_name(label, header_name);
00282             gtk_misc_set_alignment( GTK_MISC(label), 0.0, 0.0);
00283             gtk_box_pack_start(vbox, label, FALSE, FALSE, 0);
00284             //
00285             event_box = gtk_event_box_new();
00286             gtk_widget_set_name(event_box, header_name);
00287             // TODO: replace hardcoded event-box height with a new style property
00288             gtk_widget_set_size_request(event_box, -1, 15);
00289             GTK_WIDGET_UNSET_FLAGS(event_box, GTK_CAN_FOCUS);
00290             gtk_box_pack_start(vbox, event_box, FALSE, FALSE, 0);
00291             //
00292             gtk_widget_show_all(widget);
00293             gtk_tree_view_column_set_widget(column, widget);
00294 
00295             // tell me when column title changes
00296             g_signal_connect(column, "notify::title", G_CALLBACK(on_column_notify_title), label);
00297         }
00298     }
00299 
00300     // add column to tree view
00301     num_columns = gtk_tree_view_append_column(treeview, column);
00302 
00303     // clean up
00304     g_free(header_name);
00305 
00306     return num_columns;
00307 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void ergtk_list_view_class_init ( erGtkListViewClass klass  )  [static]

Definition at line 96 of file ergtklistview.c.

References add_move_binding(), ERGTK_LIST_VIEW_PRESS_ACTIVATE, ERGTK_LIST_VIEW_PRESS_LONG_DOWN, ERGTK_LIST_VIEW_PRESS_LONG_UP, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN, ERGTK_LIST_VIEW_PRESS_SHORT_UP, g_parent_class, navigate_cursor_signal, on_button_press_event(), on_button_release_event(), on_motion_notify_event(), on_pre_move_cursor(), on_realize(), on_size_allocate(), on_style_set(), P_, _erGtkListViewClass::pre_move_cursor, and pre_move_signal.

Referenced by ergtk_list_view_get_type().

00097 {
00098     GObjectClass    *object_class = (GObjectClass*  )klass;
00099     GtkWidgetClass  *widget_class = (GtkWidgetClass*)klass;
00100     
00101     GtkBindingSet   *binding_set = gtk_binding_set_by_class (klass);
00102 
00103     // remember parent class struct, needed for chaining up to parent class
00104     g_parent_class = g_type_class_peek_parent(klass);
00105 
00106     // overload virtual methods
00107     widget_class->realize              = on_realize;
00108     widget_class->style_set            = on_style_set;
00109     widget_class->size_allocate        = on_size_allocate;
00110     widget_class->button_press_event   = on_button_press_event;
00111     widget_class->button_release_event = on_button_release_event;
00112     widget_class->motion_notify_event  = on_motion_notify_event;
00113 
00114     // signal handlers
00115     klass->pre_move_cursor = on_pre_move_cursor;
00116 
00117     gtk_widget_class_install_style_property (widget_class,
00118                                              g_param_spec_int ("column-spacing",
00119                                                                P_("Column spacing"),
00120                                                                P_("Empty pixels between columns"),
00121                                                                0, G_MAXINT, 0,
00122                                                                GTK_PARAM_READABLE));
00123 
00124     pre_move_signal = g_signal_new ("pre-move-cursor",
00125                                     G_TYPE_FROM_CLASS (object_class),
00126                                     G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
00127                                     G_STRUCT_OFFSET (erGtkListViewClass, pre_move_cursor),
00128                                     NULL, NULL,
00129                                     gtk_marshal_VOID__ENUM,
00130                                     G_TYPE_NONE,  
00131                                     1,            
00132                                     G_TYPE_INT);
00133 
00134     navigate_cursor_signal = g_signal_new("navigate-cursor",
00135                                           G_TYPE_FROM_CLASS (object_class),
00136                                           G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
00137                                           0,
00138                                           NULL, NULL,
00139                                           gtk_marshal_VOID__ENUM,
00140                                           G_TYPE_NONE,  
00141                                           1,            
00142                                           G_TYPE_INT);
00143     
00144     add_move_binding(binding_set, GDK_Up,           0, ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00145     add_move_binding(binding_set, GDK_KP_Up,        0, ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00146 
00147     add_move_binding(binding_set, GDK_Down,         0, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00148     add_move_binding(binding_set, GDK_KP_Down,      0, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00149 
00150     add_move_binding(binding_set, GDK_Left,         0, ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00151     add_move_binding(binding_set, GDK_KP_Left,      0, ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00152 
00153     add_move_binding(binding_set, GDK_Right,        0, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00154     add_move_binding(binding_set, GDK_KP_Right,     0, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00155 
00156     add_move_binding(binding_set, GDK_Page_Up,      0, ERGTK_LIST_VIEW_PRESS_LONG_UP);
00157     add_move_binding(binding_set, GDK_KP_Page_Up,   0, ERGTK_LIST_VIEW_PRESS_LONG_UP);
00158     
00159     add_move_binding(binding_set, GDK_Page_Down,    0, ERGTK_LIST_VIEW_PRESS_LONG_DOWN);
00160     add_move_binding(binding_set, GDK_KP_Page_Down, 0, ERGTK_LIST_VIEW_PRESS_LONG_DOWN);
00161 
00162     add_move_binding(binding_set, GDK_Home,         0, ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00163     add_move_binding(binding_set, GDK_KP_Home,      0, ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00164 
00165     add_move_binding(binding_set, GDK_End,          0, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00166     add_move_binding(binding_set, GDK_KP_End,       0, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00167 
00168     add_move_binding(binding_set, GDK_space,        0, ERGTK_LIST_VIEW_PRESS_ACTIVATE);
00169     add_move_binding(binding_set, GDK_Return,       0, ERGTK_LIST_VIEW_PRESS_ACTIVATE);
00170     add_move_binding(binding_set, GDK_ISO_Enter,    0, ERGTK_LIST_VIEW_PRESS_ACTIVATE);
00171     add_move_binding(binding_set, GDK_KP_Enter,     0, ERGTK_LIST_VIEW_PRESS_ACTIVATE);
00172 }

Here is the call graph for this function:

Here is the caller graph for this function:

void ergtk_list_view_get_cursor ( erGtkListView er_listview,
gint *  row 
)

Definition at line 596 of file ergtklistview.c.

References ERGTK_LIST_VIEW, LOGPRINTF, and path.

Referenced by get_cursor(), on_listview_navigate_cursor(), and on_pre_move_cursor().

00597 {
00598     GtkTreeView     *treeview = (GtkTreeView*) er_listview;
00599     GtkTreePath     *path = NULL;
00600     gint            *pi;
00601     gint            currow = -1;        // cursor row, return value
00602 
00603     g_return_if_fail(ERGTK_LIST_VIEW(er_listview));
00604 
00605     if (row != NULL)
00606     {
00607         path = gtk_tree_path_new();
00608         gtk_tree_view_get_cursor(treeview, &path, NULL);
00609         if (path == NULL)
00610         {
00611             LOGPRINTF("no cursor set");
00612         }
00613         else
00614         {
00615             pi = gtk_tree_path_get_indices(path);
00616             if (pi)
00617             {
00618                 currow = *pi;
00619             }
00620         }
00621         gtk_tree_path_free(path);
00622 
00623         *row = currow;
00624     }
00625 }

Here is the caller graph for this function:

GType ergtk_list_view_get_type ( void   ) 

get type of erGtkListView widget

Returns:
type

Definition at line 194 of file ergtklistview.c.

References ergtk_list_view_class_init(), and ergtk_list_view_init().

00195 {
00196     static GType class_type = 0;
00197 
00198     if (class_type == 0)
00199     {
00200         static const GTypeInfo class_info =
00201         {
00202             sizeof(erGtkListViewClass),
00203             NULL,               /* base_init */
00204             NULL,               /* base_finalize */
00205             (GClassInitFunc) ergtk_list_view_class_init,
00206             NULL,               /* class_finalize */
00207             NULL,               /* class_data */
00208             sizeof(erGtkListView),
00209             0,                  /* n_preallocs */
00210             (GInstanceInitFunc) ergtk_list_view_init,
00211             NULL                /* *value_table */            
00212             
00213         };
00214         class_type = g_type_register_static(GTK_TYPE_TREE_VIEW, "erGtkListView", &class_info, 0);
00215     }
00216 
00217     return class_type;
00218 }

Here is the call graph for this function:

void ergtk_list_view_get_view_size ( erGtkListView er_listview,
gint *  num_rows,
gint *  num_items 
)

Definition at line 628 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, LOGPRINTF, path, and _erGtkListView::row_height.

Referenced by ergtk_list_view_set_cursor(), on_listview_navigate_cursor(), on_pre_move_cursor(), and update_view_size().

00629 {
00630     g_return_if_fail(ERGTK_IS_LIST_VIEW(er_listview));
00631 
00632     GtkTreeView             *treeview = (GtkTreeView*) er_listview;
00633     GdkRectangle            visible_rect;
00634     GtkTreePath             *path = NULL;
00635     gboolean                ok;
00636     gint                    *pi;
00637     gint                    vertical_separator = 0;
00638 
00639     LOGPRINTF("entry");
00640     
00641     // get style properties
00642     gtk_widget_style_get( GTK_WIDGET(er_listview),
00643                           "vertical-separator", &vertical_separator,
00644                           NULL );
00645 
00646     // get maximum number of rows visible
00647     if (num_rows != NULL)
00648     { 
00649         // calculate max. number of items in treeview
00650         gtk_tree_view_get_visible_rect(treeview, &visible_rect);
00651         if (   visible_rect.height     > 0
00652             && er_listview->row_height > 0 )
00653         {
00654             *num_rows = visible_rect.height / (er_listview->row_height + vertical_separator);
00655         }
00656         else
00657         {
00658             *num_rows = 1;
00659         }
00660         LOGPRINTF("num_rows [%d]", *num_rows);
00661     }
00662     
00663     // get current number of items
00664     if (num_items != NULL)
00665     { 
00666         pi   = NULL;
00667         ok   = gtk_tree_view_get_visible_range(treeview, NULL, &path);
00668         if (ok  &&  path)
00669         {
00670             pi = gtk_tree_path_get_indices(path);
00671         }
00672 
00673         if (pi)
00674         {
00675             *num_items = *pi + 1;
00676         }
00677         else
00678         {
00679             *num_items = 0;
00680         }
00681         LOGPRINTF("num_items [%d]", *num_items);
00682 
00683         // clean up
00684         if (path) { gtk_tree_path_free(path); }
00685         path = NULL;
00686     }
00687     LOGPRINTF("leave");
00688 }

Here is the caller graph for this function:

static void ergtk_list_view_init ( erGtkListView er_listview  )  [static]

Definition at line 176 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, _erGtkListView::is_button_down, _erGtkListView::is_forced_height, and _erGtkListView::row_height.

Referenced by ergtk_list_view_get_type().

00177 {
00178     g_return_if_fail(ERGTK_IS_LIST_VIEW(er_listview));
00179 
00180     GtkTreeView*  treeview = (GtkTreeView*) er_listview;
00181     //GtkWidget*    widget = (GtkWidget*) er_listview;
00182    
00183     // override defaults of GtkTreeView
00184     gtk_tree_view_set_headers_clickable(treeview, FALSE);
00185     gtk_tree_view_set_enable_search(treeview, FALSE);
00186 
00187     // initialise private data
00188     er_listview->row_height       = -1;
00189     er_listview->is_forced_height = FALSE;
00190     er_listview->is_button_down   = FALSE;
00191 }

Here is the caller graph for this function:

GtkWidget* ergtk_list_view_new ( void   ) 

Definition at line 221 of file ergtklistview.c.

References ERGTK_TYPE_LIST_VIEW.

00222 {
00223     return g_object_new (ERGTK_TYPE_LIST_VIEW, NULL);
00224 }

GtkWidget* ergtk_list_view_new_with_model ( GtkTreeModel *  model  ) 

Definition at line 227 of file ergtklistview.c.

References ERGTK_TYPE_LIST_VIEW.

Referenced by create_back_listview(), create_contentview(), create_listview(), and create_settingsview().

00228 {
00229     return g_object_new (ERGTK_TYPE_LIST_VIEW, "model", model, NULL);
00230 }

Here is the caller graph for this function:

void ergtk_list_view_set_cursor ( erGtkListView er_listview,
gint  row 
)

Definition at line 691 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, ergtk_list_view_get_view_size(), LOGPRINTF, path, and widget.

Referenced by on_button_press_event(), on_focus_in(), and on_idle_set_cursor().

00692 {
00693     g_return_if_fail(ERGTK_IS_LIST_VIEW(er_listview));
00694 
00695     GtkTreeView      *treeview  = (GtkTreeView*) er_listview;
00696     GtkWidget        *widget    = (GtkWidget  *) er_listview;
00697     GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
00698     
00699     GtkTreePath *path = NULL;  
00700     gint num_rows = 0;
00701     gint num_items = 0;
00702     
00703     LOGPRINTF("entry: row %d", row);
00704 
00705     ergtk_list_view_get_view_size(er_listview, &num_rows, &num_items); 
00706     LOGPRINTF("num_rows %d, num_items %d", num_rows, num_items);
00707 
00708     // force row within valid range
00709     if (row >= num_items)
00710     {
00711         row = num_items - 1;
00712     }
00713     if (row < 0)
00714     {
00715         row = -1;
00716     }
00717 
00718     // create path from index and set cursor
00719     if (num_items > 0)
00720     {
00721         path = gtk_tree_path_new_from_indices(row, -1);
00722         gtk_widget_grab_focus (widget);
00723         gtk_tree_selection_select_path(selection, path);  
00724         gtk_tree_view_set_cursor(treeview, path, NULL, FALSE);
00725     }
00726 
00727     // clean up
00728     if (path) { gtk_tree_path_free(path); }
00729 
00730     return;
00731 }

Here is the call graph for this function:

Here is the caller graph for this function:

void ergtk_list_view_set_focus_mode ( erGtkListView er_listview,
gboolean  focus_in,
gboolean  focus_out 
)

Definition at line 734 of file ergtklistview.c.

References LOGPRINTF, on_focus_in(), and on_focus_out().

Referenced by create_back_listview(), create_contentview(), create_listview(), and create_settingsview().

00737 {
00738     LOGPRINTF("entry");
00739 
00740     if (!focus_in)
00741     {
00742         // block focus-in events 
00743         g_signal_connect(G_OBJECT(er_listview), "focus-in-event", G_CALLBACK (on_focus_in), NULL);
00744     }
00745     if (!focus_out)
00746     {
00747         // block focus-out events 
00748         g_signal_connect(G_OBJECT(er_listview), "focus-out-event", G_CALLBACK (on_focus_out), NULL);
00749     }
00750 }

Here is the call graph for this function:

Here is the caller graph for this function:

void ergtk_list_view_set_row_height ( erGtkListView er_listview,
gint  row_height 
)

Definition at line 753 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, _erGtkListView::is_forced_height, LOGPRINTF, and _erGtkListView::row_height.

Referenced by create_listview().

00754 {
00755     g_return_if_fail(ERGTK_IS_LIST_VIEW(er_listview));
00756 
00757     gint        focus_line_width = 0;
00758 
00759     LOGPRINTF("entry");
00760 
00761     if (row_height > 0)
00762     {
00763         gtk_widget_style_get( GTK_WIDGET(er_listview),
00764                               "focus-line-width", &focus_line_width,
00765                               NULL );
00766         er_listview->row_height       = row_height + (2 * focus_line_width);
00767         er_listview->is_forced_height = TRUE;
00768     }
00769     else
00770     {
00771         er_listview->row_height       = -1;
00772         er_listview->is_forced_height = FALSE;
00773     }
00774 }

Here is the caller graph for this function:

static gboolean on_button_press_event ( GtkWidget *  widget,
GdkEventButton *  event 
) [static]

Definition at line 470 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, ergtk_list_view_set_cursor(), _erGtkListView::is_button_down, LOGPRINTF, path, _erGtkListView::press_event_button, _erGtkListView::press_event_state, _erGtkListView::press_event_x, _erGtkListView::press_event_y, and _erGtkListView::press_item_idx.

Referenced by ergtk_list_view_class_init().

00472 {
00473     g_return_val_if_fail(ERGTK_IS_LIST_VIEW(widget), FALSE);
00474 
00475     GtkTreeView     *treeview    = (GtkTreeView  *) widget;
00476     erGtkListView   *er_listview = (erGtkListView*) widget;
00477     GtkTreePath     *path = NULL;
00478     gint            *pi;
00479     gint            item_idx = 0;
00480     gboolean        ok;
00481 
00482     LOGPRINTF("entry: x y [%lf %lf] button [%d]", event->x, event->y, event->button);
00483     
00484     // find treeview item with this event
00485     ok = gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, &path, NULL, NULL, NULL);
00486     if (ok  &&  path)
00487     {
00488         pi = gtk_tree_path_get_indices(path);
00489         if (pi)
00490         {
00491             item_idx = *pi;
00492         }
00493     }
00494     LOGPRINTF("item_idx [%d]", item_idx);
00495 
00496     // act only on left-button single-click 
00497     if (   ok
00498         && path
00499         && event->button == 1
00500         && event->type   == GDK_BUTTON_PRESS )
00501     {
00502         // store button-press info
00503         er_listview->is_button_down     = TRUE;
00504         er_listview->press_event_button = event->button;
00505         er_listview->press_event_state  = event->state;
00506         er_listview->press_event_x      = event->x;
00507         er_listview->press_event_y      = event->y;
00508 
00509         // remember treeview item with this event
00510         er_listview->press_item_idx = item_idx;
00511 
00512         // move cursor to selected item
00513         ergtk_list_view_set_cursor(er_listview, item_idx);
00514     }
00515     else
00516     {
00517         er_listview->is_button_down = FALSE;
00518     }
00519     LOGPRINTF("is_down [%d] item_idx [%d]", er_listview->is_button_down, item_idx);
00520     
00521     // clean up
00522     if (path) { gtk_tree_path_free(path); }
00523 
00524     return TRUE;  // stop event handling right now, no calls to other handlers
00525 }

Here is the call graph for this function:

Here is the caller graph for this function:

static gboolean on_button_release_event ( GtkWidget *  widget,
GdkEventButton *  event 
) [static]

Definition at line 528 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, _erGtkListView::is_button_down, LOGPRINTF, path, _erGtkListView::press_event_button, and _erGtkListView::press_item_idx.

Referenced by ergtk_list_view_class_init().

00530 {
00531     g_return_val_if_fail(ERGTK_IS_LIST_VIEW(widget), FALSE);
00532 
00533     GtkTreeView     *treeview    = (GtkTreeView  *) widget;
00534     erGtkListView   *er_listview = (erGtkListView*) widget;
00535     GtkTreePath     *path = NULL;
00536     gint            *pi;
00537     gint            item_idx = 0;
00538     gboolean        ok;
00539     
00540     // find treeview item with this event
00541     ok = gtk_tree_view_get_path_at_pos(treeview, event->x, event->y, &path, NULL, NULL, NULL);
00542     if (ok && path)
00543     {
00544         // find item index
00545         pi = gtk_tree_path_get_indices(path);
00546         if (pi)
00547         {
00548             item_idx = *pi;
00549         }
00550 
00551         // act only on item that has received the left-button-down event
00552         if (   event->button == 1
00553             && er_listview->is_button_down
00554             && er_listview->press_event_button == event->button
00555             && er_listview->press_item_idx     == item_idx     )
00556         {
00557             LOGPRINTF("activate row [%d]", item_idx);
00558             gtk_tree_view_row_activated(treeview, path, NULL);
00559         }
00560     }
00561 
00562     // remember button not down
00563     er_listview->is_button_down = FALSE;
00564     
00565     // clean up
00566     if (path) { gtk_tree_path_free(path); }
00567 
00568     return TRUE;  // stop event handling right now, no calls to other handlers
00569 }

Here is the caller graph for this function:

static void on_column_notify_title ( GObject *  object,
GParamSpec *  arg1,
gpointer  user_data 
) [static]

Definition at line 311 of file ergtklistview.c.

References label, and LOGPRINTF.

Referenced by ergtk_list_view_append_column().

00314 {
00315     LOGPRINTF("entry");
00316     g_return_if_fail(GTK_IS_TREE_VIEW_COLUMN(object));
00317     g_return_if_fail(GTK_IS_LABEL(user_data));
00318 
00319     GtkTreeViewColumn   *column = GTK_TREE_VIEW_COLUMN(object);
00320     GtkLabel            *label  = GTK_LABEL(user_data);
00321 
00322     if (column && label)
00323     {
00324         gtk_label_set_text(label, gtk_tree_view_column_get_title(column));
00325     }
00326 }

Here is the caller graph for this function:

static gboolean on_focus_in ( GtkWidget *  widget,
gpointer  data 
) [static]

Definition at line 885 of file ergtklistview.c.

References LOGPRINTF.

Referenced by ergtk_list_view_set_focus_mode().

00886 {
00887     LOGPRINTF("entry");
00888 
00889     // Return TRUE to stop other handlers from being invoked for the event 
00890     return  TRUE;
00891 }

Here is the caller graph for this function:

static gboolean on_focus_out ( GtkWidget *  widget,
gpointer  data 
) [static]

Definition at line 894 of file ergtklistview.c.

References LOGPRINTF.

Referenced by ergtk_list_view_set_focus_mode().

00895 {
00896     LOGPRINTF("entry");
00897 
00898     // Return TRUE to stop other handlers from being invoked for the event 
00899     return  TRUE;
00900 }

Here is the caller graph for this function:

static gboolean on_motion_notify_event ( GtkWidget *  widget,
GdkEventMotion *  event 
) [static]

Definition at line 572 of file ergtklistview.c.

Referenced by ergtk_list_view_class_init().

00574 {
00575     // ignore drag-and-drop and rubberbanding
00576     return TRUE;
00577 }

Here is the caller graph for this function:

static gboolean on_pre_move_cursor ( erGtkListView er_listview,
erGtkListViewKeyPress  navigate 
) [static]

Definition at line 781 of file ergtklistview.c.

References ERGTK_LIST_VIEW, ergtk_list_view_get_cursor(), ergtk_list_view_get_view_size(), ERGTK_LIST_VIEW_PRESS_ACTIVATE, ERGTK_LIST_VIEW_PRESS_LONG_DOWN, ERGTK_LIST_VIEW_PRESS_LONG_UP, ERGTK_LIST_VIEW_PRESS_SHORT_DOWN, ERGTK_LIST_VIEW_PRESS_SHORT_UP, LOGPRINTF, path, and WARNPRINTF.

Referenced by ergtk_list_view_class_init().

00783 {
00784     GtkTreeView     *treeview = (GtkTreeView *) er_listview;
00785 
00786     gboolean        rc;  
00787     GtkTreePath     *path = NULL;
00788     gint            currow   = 0;       // cursor row
00789     gint            num_rows = 0;       // number of rows
00790     gint            num_items = 0;      // number of items currently displayed
00791 
00792     g_return_val_if_fail (ERGTK_LIST_VIEW (er_listview), FALSE);
00793 
00794     if (!GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (er_listview)))
00795     {
00796         WARNPRINTF("widget has no focus");
00797         return FALSE;
00798     }
00799 
00800     ergtk_list_view_get_cursor(er_listview, &currow);
00801     ergtk_list_view_get_view_size(er_listview, &num_rows, &num_items); 
00802 
00803     LOGPRINTF("navigate [%d] currow [%d] num_rows [%d] num_items [%d]",
00804                navigate,     currow,     num_rows,     num_items       );
00805 
00806     switch (navigate)
00807     {
00808     case ERGTK_LIST_VIEW_PRESS_SHORT_UP:
00809         if (currow > 0)
00810         {
00811             // move up line in view
00812             g_signal_emit_by_name(er_listview, "move-cursor", GTK_MOVEMENT_DISPLAY_LINES, -1, &rc);
00813         }
00814         else 
00815         {      
00816             // emit signal
00817             g_signal_emit_by_name(er_listview, "navigate-cursor", ERGTK_LIST_VIEW_PRESS_SHORT_UP);
00818         }
00819         break;
00820         
00821     case ERGTK_LIST_VIEW_PRESS_SHORT_DOWN:
00822         if (currow + 1 < num_items)
00823         {
00824             g_signal_emit_by_name (er_listview, "move-cursor", GTK_MOVEMENT_DISPLAY_LINES, 1, &rc);
00825         }
00826         else
00827         {
00828             g_signal_emit_by_name(er_listview, "navigate-cursor", ERGTK_LIST_VIEW_PRESS_SHORT_DOWN);
00829         }
00830         break;
00831         
00832     case ERGTK_LIST_VIEW_PRESS_LONG_UP:
00833         g_signal_emit_by_name(er_listview, "navigate-cursor", ERGTK_LIST_VIEW_PRESS_LONG_UP);
00834         break;
00835         
00836     case ERGTK_LIST_VIEW_PRESS_LONG_DOWN:
00837         g_signal_emit_by_name(er_listview, "navigate-cursor", ERGTK_LIST_VIEW_PRESS_LONG_DOWN);
00838         break;
00839         
00840     case ERGTK_LIST_VIEW_PRESS_ACTIVATE:
00841         gtk_tree_view_row_activated(treeview, path, NULL);
00842         break;
00843 
00844     default:
00845         g_assert_not_reached();
00846         break;
00847     }
00848 
00849     // clean up
00850     if (path) { gtk_tree_path_free(path); }
00851 
00852     return TRUE;
00853 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void on_realize ( GtkWidget *  widget  )  [static]

Definition at line 580 of file ergtklistview.c.

References g_parent_class.

Referenced by ergtk_list_view_class_init().

00581 {
00582     GtkWidgetClass  *parent_widget_class = GTK_WIDGET_CLASS(g_parent_class);
00583 
00584     // call parent first
00585     if (parent_widget_class->realize)
00586     {
00587         parent_widget_class->realize(widget);
00588     }
00589     
00590     // disable pointer motion events
00591     GdkEventMask mask = gdk_window_get_events(widget->window);
00592     gdk_window_set_events(widget->window, mask & ~(GDK_POINTER_MOTION_MASK));
00593 }

Here is the caller graph for this function:

static void on_size_allocate ( GtkWidget *  widget,
GtkAllocation *  allocation 
) [static]

Definition at line 347 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, g_parent_class, _erGtkListView::is_forced_height, LOGPRINTF, and _erGtkListView::row_height.

Referenced by ergtk_list_view_class_init().

00348 {
00349     g_return_if_fail(ERGTK_IS_LIST_VIEW(widget));
00350 
00351     GtkWidgetClass      *parent_widget_class = GTK_WIDGET_CLASS(g_parent_class);
00352     GtkTreeView         *treeview    = (GtkTreeView  *) widget;
00353     erGtkListView       *er_listview = (erGtkListView*) widget;
00354 
00355     GList               *columns = NULL;
00356     GList               *p_col;
00357     GtkTreeViewColumn   *col;
00358     gint                col_idx;
00359     GList               *renderers = NULL;
00360     GList               *p_rend;
00361     GtkCellRenderer     *rend;
00362     GtkWidget           *child = NULL;
00363     GtkAllocation       child_allocation;
00364     gint                focus_line_width = 0;
00365     gint                column_spacing   = 0;
00366     gint                filler_width     = 0;
00367     gint                row_height       = 1;
00368     gboolean            is_forced_height = er_listview->is_forced_height;
00369     gint                height;
00370 
00371     LOGPRINTF("entry");
00372     
00373     // chain to parent class
00374     if (parent_widget_class->size_allocate)
00375     {
00376         parent_widget_class->size_allocate(widget, allocation);
00377     }
00378 
00379     // get style properties
00380     gtk_widget_style_get( widget,
00381                           "column-spacing",   &column_spacing,
00382                           "focus-line-width", &focus_line_width,
00383                           NULL );
00384     filler_width = column_spacing - (2 * focus_line_width);
00385     if (filler_width < 0)
00386     {
00387         filler_width = 0;
00388     }
00389 
00390     // adjust width of column headers
00391     // get max. current column height
00392     columns = gtk_tree_view_get_columns(treeview);
00393     for ( p_col = columns, col_idx = 0 ;
00394           p_col ;
00395           p_col = p_col->next, col_idx++ )
00396     {
00397         col = GTK_TREE_VIEW_COLUMN(p_col->data);
00398 
00399         if (col_idx % 2 == 0)
00400         {
00401             // data column
00402             //   set header width
00403             child = gtk_tree_view_column_get_widget(col);
00404             if (child)
00405             {
00406                 child_allocation       = child->allocation;
00407                 child_allocation.width = gtk_tree_view_column_get_width(col);
00408                 child_allocation.width -= 2 * focus_line_width;
00409                 gtk_widget_size_allocate(child, &child_allocation);
00410             }
00411 
00412             // adjust max. column height, if needed
00413             // note: this (probably) reflects the height of the first row only
00414             if ( !is_forced_height )
00415             {
00416                 gtk_tree_view_column_cell_get_size(col, NULL, NULL, NULL, NULL, &height );
00417                 LOGPRINTF("height [%d]", height);
00418                 if (height > row_height)
00419                 {
00420                     row_height = height;
00421                 }
00422             }
00423         }
00424         else
00425         {
00426             // filler column
00427             //   set column width
00428             gtk_tree_view_column_set_min_width(col, filler_width);
00429         }
00430     }
00431 
00432     // force height of first row to all rows
00433     if (is_forced_height)
00434     {
00435         row_height = er_listview->row_height;
00436     }
00437     else
00438     {
00439         er_listview->row_height = row_height;
00440     }
00441     row_height -= 2 * focus_line_width;
00442     for ( p_col = columns, col_idx = 0 ;
00443           p_col ;
00444           p_col = p_col->next, col_idx++ )
00445     {
00446         col = GTK_TREE_VIEW_COLUMN(p_col->data);
00447 
00448         if (col_idx % 2 == 0)
00449         {
00450             // data column
00451             //   get cell renderers
00452             //   set fixed height on each renderer
00453             renderers = gtk_tree_view_column_get_cell_renderers(col);
00454             for ( p_rend = renderers ; p_rend ; p_rend = p_rend->next )
00455             {
00456                 rend = GTK_CELL_RENDERER(p_rend->data);
00457                 gtk_cell_renderer_set_fixed_size(rend, -1, row_height);
00458             }
00459             g_list_free(renderers);
00460             renderers = NULL;
00461         }
00462     }
00463 
00464     // clean up
00465     g_list_free(columns);
00466     columns = NULL;
00467 }

Here is the caller graph for this function:

static void on_style_set ( GtkWidget *  widget,
GtkStyle *  previous_style 
) [static]

Definition at line 333 of file ergtklistview.c.

References ERGTK_IS_LIST_VIEW, and g_parent_class.

Referenced by ergtk_list_view_class_init().

00334 {
00335     g_return_if_fail(ERGTK_IS_LIST_VIEW(widget));
00336 
00337     GtkWidgetClass* parent_widget_class = GTK_WIDGET_CLASS(g_parent_class);
00338         
00339     // chain to parent class
00340     if (parent_widget_class->style_set)
00341     {
00342         parent_widget_class->style_set(widget, previous_style);
00343     }
00344 }

Here is the caller graph for this function:


Variable Documentation

GtkTreeViewClass* g_parent_class = NULL [static]

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

Definition at line 46 of file ergtklistview.c.

Referenced by ergtk_list_view_class_init(), on_realize(), on_size_allocate(), and on_style_set().

guint navigate_cursor_signal = 0 [static]

Definition at line 48 of file ergtklistview.c.

Referenced by ergtk_list_view_class_init().

guint pre_move_signal = 0 [static]

Definition at line 47 of file ergtklistview.c.

Referenced by ergtk_list_view_class_init().

Generated by  doxygen 1.6.2-20100208