2 * irreco - Ir Remote Control
3 * Copyright (C) 2007 Arto Karppinen (arto.karppinen@iki.fi)
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "irreco_listbox.h"
23 * @addtogroup IrrecoListbox
26 * A base class for Irreco listbox classes.
28 * The basic structure is to have a GtkTreview widget inside a
29 * GtkScrolledWindow, and provide convenience frappers for so you dont have
30 * to deal with GtkTreview directly.
32 * That is, IrrecoListbox classes provide a simple listboxes, without all
35 * Subclasses must set these variables, or this class will not work:
36 * IRRECO_LISTBOX(self)->list_store
37 * IRRECO_LISTBOX(self)->tree_view
38 * IRRECO_LISTBOX(self)->tree_selection
39 * IRRECO_LISTBOX(self)->data_col_id
40 * IRRECO_LISTBOX(self)->text_col_id
43 * Source file of @ref IrrecoListbox.
48 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
50 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
52 static void irreco_listbox_scrolled_size_request(GtkWidget
*widget
,
53 GtkRequisition
*requisition
,
58 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
59 /* Construction & Destruction */
60 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
63 * @name Construction & Destruction
67 G_DEFINE_TYPE(IrrecoListbox
, irreco_listbox
, GTK_TYPE_HBOX
)
69 static void irreco_listbox_class_init(IrrecoListboxClass
*klass
)
73 static void irreco_listbox_init(IrrecoListbox
*self
)
77 self
->select_new_rows
= TRUE
;
78 gtk_box_set_spacing(GTK_BOX(self
), 1);
80 /* Connect signals. */
81 g_signal_connect(G_OBJECT(self
), "size-request",
82 G_CALLBACK(irreco_listbox_scrolled_size_request
),
92 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
93 /* Public Functions */
94 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
97 * @name Public Functions
102 * Set if new rows added to the listbox will automatically be selected.
104 void irreco_listbox_set_select_new_rows(IrrecoListbox
*self
,
105 gboolean select_new_rows
)
108 self
->select_new_rows
= select_new_rows
;
112 void irreco_listbox_set_autosize(IrrecoListbox
*self
,
119 if ((self
->min_width
= min_width
) < 0) self
->min_width
= 0;
120 if ((self
->max_width
= max_width
) < 0) self
->max_width
= 0;
121 if ((self
->min_height
= min_height
) < 0) self
->min_height
= 0;
122 if ((self
->max_height
= max_height
) < 0) self
->max_height
= 0;
126 void irreco_listbox_clear(IrrecoListbox
*self
)
129 gtk_list_store_clear(self
->list_store
);
134 * Get GtkTreeIter for some index in the listbox.
136 gboolean
irreco_listbox_get_iter(IrrecoListbox
*self
,
137 gint index
, GtkTreeIter
* iter
)
144 IRRECO_DEBUG("Index \"%i\".\n", index
);
145 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(
147 path
= gtk_tree_path_new_from_indices(index
, -1);
148 rvalue
= gtk_tree_model_get_iter(model
, iter
, path
);
149 gtk_tree_path_free(path
);
150 IRRECO_RETURN_INT(rvalue
);
156 gboolean
irreco_listbox_set_selection(IrrecoListbox
*self
, gint index
)
161 IRRECO_DEBUG("Selecting row \"%i\".\n", index
);
162 if (irreco_listbox_get_iter(self
, index
, &iter
)) {
163 gtk_tree_selection_select_iter(self
->tree_selection
, &iter
);
164 IRRECO_RETURN_BOOL(TRUE
);
166 IRRECO_RETURN_BOOL(FALSE
);
170 * Get currect selection of listbox.
174 * gint sel_index = -1;
175 * gchar *sel_label = NULL;
176 * gpointer sel_user_data = NULL;
177 * irreco_listbox_get_selection(IRRECO_LISTBOX(listbox),
178 * &sel_index, &sel_label, &sel_user_data);
181 gboolean
irreco_listbox_get_selection(IrrecoListbox
*self
,
186 gboolean rvalue
= FALSE
;
188 GtkTreeModel
*model
= NULL
;
189 GtkTreePath
*path
= NULL
;
190 gint
*path_indices
= NULL
;
191 GtkTreeSelection
*selection
= NULL
;
193 gchar
*sel_label
= NULL
;
194 gpointer sel_user_data
= NULL
;
197 /* Get currect selection, if set. */
198 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(self
->tree_view
));
199 if (gtk_tree_selection_get_selected(self
->tree_selection
,
201 path
= gtk_tree_model_get_path(model
, &iter
);
202 path_indices
= gtk_tree_path_get_indices(path
);
203 sel_index
= path_indices
[0];
204 gtk_tree_path_free(path
);
205 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
,
206 self
->text_col_id
, &sel_label
,
207 self
->data_col_id
, &sel_user_data
,
212 IRRECO_DEBUG("Selection \"%i\" \"%s\" \"%p\"\n",
213 sel_index
, sel_label
, sel_user_data
);
215 /* Store values to pointers. */
216 if (index
) *index
= sel_index
;
217 if (user_data
) *user_data
= sel_user_data
;
224 IRRECO_RETURN_BOOL(rvalue
);
227 gint
irreco_listbox_get_selection_index(IrrecoListbox
*self
)
232 irreco_listbox_get_selection(self
, &sel_index
, NULL
, NULL
);
233 IRRECO_RETURN_INT(sel_index
);
236 gchar
*irreco_listbox_get_selection_label(IrrecoListbox
*self
)
238 gchar
*sel_label
= NULL
;
241 irreco_listbox_get_selection(self
, NULL
, &sel_label
, NULL
);
242 IRRECO_RETURN_STR(sel_label
);
245 gpointer
irreco_listbox_get_selection_data(IrrecoListbox
*self
)
247 gpointer sel_user_data
= NULL
;
250 irreco_listbox_get_selection(self
, NULL
, NULL
, &sel_user_data
);
251 IRRECO_RETURN_PTR(sel_user_data
);
255 * Move the currently selected row upwards.
257 gboolean
irreco_listbox_move_selected_up(IrrecoListbox
*self
)
262 sel_index
= irreco_listbox_get_selection_index(self
);
263 if (sel_index
== -1) IRRECO_RETURN_BOOL(FALSE
);
264 IRRECO_RETURN_BOOL(irreco_listbox_move(
265 self
, sel_index
, sel_index
- 1));
269 * Move the currently selected row downwards.
271 gboolean
irreco_listbox_move_selected_down(IrrecoListbox
*self
)
276 sel_index
= irreco_listbox_get_selection_index(self
);
277 if (sel_index
== -1) IRRECO_RETURN_BOOL(FALSE
);
278 IRRECO_RETURN_BOOL(irreco_listbox_move(
279 self
, sel_index
, sel_index
+ 1));
282 gboolean
irreco_listbox_move(IrrecoListbox
*self
,
286 GtkTreeIter from_iter
;
290 /* Check indices. We assume that below zero means first,
291 and above list lenght means last. */
292 if (from_index
< 0) {
294 } else if (from_index
> self
->list_store
->length
) {
295 IRRECO_RETURN_BOOL(FALSE
);
298 if (to_index
> self
->list_store
->length
) {
299 to_index
= self
->list_store
->length
;
300 } else if (to_index
< 0) {
301 IRRECO_RETURN_BOOL(FALSE
);
304 IRRECO_DEBUG("Moving item from index \"%i\" to index \"%i\".\n",
305 from_index
, to_index
);
307 if (irreco_listbox_get_iter(self
, from_index
, &from_iter
)
308 && irreco_listbox_get_iter(self
, to_index
, &to_iter
)) {
309 if (from_index
> to_index
) {
310 IRRECO_DEBUG("Moving up.\n");
311 gtk_list_store_move_before(self
->list_store
,
312 &from_iter
, &to_iter
);
314 IRRECO_DEBUG("Moving down.\n");
315 gtk_list_store_move_after(self
->list_store
,
316 &from_iter
, &to_iter
);
319 /* Set selection to the moved row. */
320 if (gtk_tree_selection_iter_is_selected(
321 self
->tree_selection
, &from_iter
)) {
323 gtk_tree_selection_select_iter(self
->tree_selection
,
327 IRRECO_RETURN_BOOL(TRUE
);
330 IRRECO_RETURN_BOOL(FALSE
);
333 gboolean
irreco_listbox_remove_selected(IrrecoListbox
*self
)
340 sel_index
= irreco_listbox_get_selection_index(self
);
341 if ((index
= sel_index
) == -1
342 || irreco_listbox_get_iter(self
, index
, &iter
) == FALSE
) {
343 IRRECO_RETURN_BOOL(FALSE
);
346 /* Attemt to select another row before we destroy the current one.
347 This helps to prevent double selection changed events being sent,
348 when the old row is destroyed (and thus unselected) and selecting
349 another row afterwards. */
350 irreco_listbox_set_selection(self
, index
- 1)
351 || irreco_listbox_set_selection(self
, index
+ 1);
353 gtk_list_store_remove(self
->list_store
, &iter
);
354 IRRECO_RETURN_BOOL(TRUE
);
357 gboolean
irreco_listbox_remove(IrrecoListbox
*self
, gint index
)
362 if (irreco_listbox_get_iter(self
, index
, &iter
) == FALSE
) {
363 IRRECO_RETURN_BOOL(FALSE
);
365 gtk_list_store_remove(self
->list_store
, &iter
);
366 IRRECO_RETURN_BOOL(TRUE
);
373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
374 /* Events and Callbacks */
375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
378 * @name Events and Callbacks
382 static void irreco_listbox_scrolled_size_request(GtkWidget
*widget
,
383 GtkRequisition
*requisition
,
388 if (requisition
->width
< self
->min_width
) {
389 requisition
->width
= self
->min_width
;
390 } else if (requisition
->width
> self
->max_width
) {
391 requisition
->width
= self
->max_width
;
394 if (requisition
->height
< self
->min_height
) {
395 requisition
->height
= self
->min_height
;
396 } else if (requisition
->height
> self
->max_height
) {
397 requisition
->height
= self
->max_height
;