File: | ctk/ctktreeview.c |
Warning: | line 4079, column 4 Value stored to 'height' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* ctktreeview.c |
2 | * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com> |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Library General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | * Library General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU Library General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | |
19 | #include "config.h" |
20 | |
21 | #include <math.h> |
22 | #include <string.h> |
23 | |
24 | #include "ctktreeview.h" |
25 | |
26 | #include "ctkadjustmentprivate.h" |
27 | #include "ctkcssnumbervalueprivate.h" |
28 | #include "ctkrbtree.h" |
29 | #include "ctktreednd.h" |
30 | #include "ctktreeprivate.h" |
31 | #include "ctkcellrenderer.h" |
32 | #include "ctkmarshalers.h" |
33 | #include "ctkbuildable.h" |
34 | #include "ctkbutton.h" |
35 | #include "ctklabel.h" |
36 | #include "ctkbox.h" |
37 | #include "ctkintl.h" |
38 | #include "ctkbindings.h" |
39 | #include "ctkcontainer.h" |
40 | #include "ctkentry.h" |
41 | #include "ctkframe.h" |
42 | #include "ctkmain.h" |
43 | #include "ctktreemodelsort.h" |
44 | #include "ctktooltip.h" |
45 | #include "ctkscrollable.h" |
46 | #include "ctkcelllayout.h" |
47 | #include "ctkprivate.h" |
48 | #include "ctkwidgetprivate.h" |
49 | #include "ctkentryprivate.h" |
50 | #include "ctkstylecontextprivate.h" |
51 | #include "ctkcssstylepropertyprivate.h" |
52 | #include "ctkcssrgbavalueprivate.h" |
53 | #include "ctktypebuiltins.h" |
54 | #include "ctkmain.h" |
55 | #include "ctksettingsprivate.h" |
56 | #include "ctkwidgetpath.h" |
57 | #include "ctkpixelcacheprivate.h" |
58 | #include "a11y/ctktreeviewaccessibleprivate.h" |
59 | |
60 | |
61 | /** |
62 | * SECTION:ctktreeview |
63 | * @Short_description: A widget for displaying both trees and lists |
64 | * @Title: CtkTreeView |
65 | * @See_also: #CtkTreeViewColumn, #CtkTreeSelection, #CtkTreeModel, |
66 | * [CtkTreeView drag-and-drop][ctk3-CtkTreeView-drag-and-drop], |
67 | * #CtkTreeSortable, #CtkTreeModelSort, #CtkListStore, #CtkTreeStore, |
68 | * #CtkCellRenderer, #CtkCellEditable, #CtkCellRendererPixbuf, |
69 | * #CtkCellRendererText, #CtkCellRendererToggle |
70 | * |
71 | * Widget that displays any object that implements the #CtkTreeModel interface. |
72 | * |
73 | * Please refer to the |
74 | * [tree widget conceptual overview][TreeWidget] |
75 | * for an overview of all the objects and data types related |
76 | * to the tree widget and how they work together. |
77 | * |
78 | * Several different coordinate systems are exposed in the CtkTreeView API. |
79 | * These are: |
80 | * |
81 | * ![](tree-view-coordinates.png) |
82 | * |
83 | * Coordinate systems in CtkTreeView API: |
84 | * |
85 | * - Widget coordinates: Coordinates relative to the widget (usually `widget->window`). |
86 | * |
87 | * - Bin window coordinates: Coordinates relative to the window that CtkTreeView renders to. |
88 | * |
89 | * - Tree coordinates: Coordinates relative to the entire scrollable area of CtkTreeView. These |
90 | * coordinates start at (0, 0) for row 0 of the tree. |
91 | * |
92 | * Several functions are available for converting between the different |
93 | * coordinate systems. The most common translations are between widget and bin |
94 | * window coordinates and between bin window and tree coordinates. For the |
95 | * former you can use ctk_tree_view_convert_widget_to_bin_window_coords() |
96 | * (and vice versa), for the latter ctk_tree_view_convert_bin_window_to_tree_coords() |
97 | * (and vice versa). |
98 | * |
99 | * # CtkTreeView as CtkBuildable |
100 | * |
101 | * The CtkTreeView implementation of the CtkBuildable interface accepts |
102 | * #CtkTreeViewColumn objects as <child> elements and exposes the internal |
103 | * #CtkTreeSelection in UI definitions. |
104 | * |
105 | * An example of a UI definition fragment with CtkTreeView: |
106 | * |[ |
107 | * <object class="CtkTreeView" id="treeview"> |
108 | * <property name="model">liststore1</property> |
109 | * <child> |
110 | * <object class="CtkTreeViewColumn" id="test-column"> |
111 | * <property name="title">Test</property> |
112 | * <child> |
113 | * <object class="CtkCellRendererText" id="test-renderer"/> |
114 | * <attributes> |
115 | * <attribute name="text">1</attribute> |
116 | * </attributes> |
117 | * </child> |
118 | * </object> |
119 | * </child> |
120 | * <child internal-child="selection"> |
121 | * <object class="CtkTreeSelection" id="selection"> |
122 | * <signal name="changed" handler="on_treeview_selection_changed"/> |
123 | * </object> |
124 | * </child> |
125 | * </object> |
126 | * ]| |
127 | * |
128 | * # CSS nodes |
129 | * |
130 | * |[<!-- language="plain" --> |
131 | * treeview.view |
132 | * ├── header |
133 | * │ ├── <column header> |
134 | * ┊ ┊ |
135 | * │ ╰── <column header> |
136 | * │ |
137 | * ╰── [rubberband] |
138 | * ]| |
139 | * |
140 | * CtkTreeView has a main CSS node with name treeview and style class .view. |
141 | * It has a subnode with name header, which is the parent for all the column |
142 | * header widgets' CSS nodes. |
143 | * For rubberband selection, a subnode with name rubberband is used. |
144 | */ |
145 | |
146 | enum |
147 | { |
148 | DRAG_COLUMN_WINDOW_STATE_UNSET = 0, |
149 | DRAG_COLUMN_WINDOW_STATE_ORIGINAL = 1, |
150 | DRAG_COLUMN_WINDOW_STATE_ARROW = 2, |
151 | DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT = 3, |
152 | DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT = 4 |
153 | }; |
154 | |
155 | enum |
156 | { |
157 | RUBBER_BAND_OFF = 0, |
158 | RUBBER_BAND_MAYBE_START = 1, |
159 | RUBBER_BAND_ACTIVE = 2 |
160 | }; |
161 | |
162 | typedef enum { |
163 | CLEAR_AND_SELECT = (1 << 0), |
164 | CLAMP_NODE = (1 << 1), |
165 | CURSOR_INVALID = (1 << 2) |
166 | } SetCursorFlags; |
167 | |
168 | /* This lovely little value is used to determine how far away from the title bar |
169 | * you can move the mouse and still have a column drag work. |
170 | */ |
171 | #define TREE_VIEW_COLUMN_DRAG_DEAD_MULTIPLIER(tree_view)(10*ctk_tree_view_get_effective_header_height(tree_view)) (10*ctk_tree_view_get_effective_header_height(tree_view)) |
172 | |
173 | #ifdef __GNUC__4 |
174 | |
175 | #define TREE_VIEW_INTERNAL_ASSERT(expr, ret)do{ if (!(expr)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "175", ((const char*) (__func__)), "expr"); return ret; }; }while (0) G_STMT_STARTdo{ \ |
176 | if (!(expr)) \ |
177 | { \ |
178 | g_log (G_LOG_DOMAIN"Ctk", \ |
179 | G_LOG_LEVEL_CRITICAL, \ |
180 | "%s (%s): assertion `%s' failed.\n" \ |
181 | "There is a disparity between the internal view of the CtkTreeView,\n" \ |
182 | "and the CtkTreeModel. This generally means that the model has changed\n"\ |
183 | "without letting the view know. Any display from now on is likely to\n" \ |
184 | "be incorrect.\n", \ |
185 | G_STRLOC"ctktreeview.c" ":" "185", \ |
186 | G_STRFUNC((const char*) (__func__)), \ |
187 | #expr); \ |
188 | return ret; \ |
189 | }; }G_STMT_ENDwhile (0) |
190 | |
191 | #define TREE_VIEW_INTERNAL_ASSERT_VOID(expr)do{ if (!(expr)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "191", ((const char*) (__func__)), "expr"); return; }; }while (0) G_STMT_STARTdo{ \ |
192 | if (!(expr)) \ |
193 | { \ |
194 | g_log (G_LOG_DOMAIN"Ctk", \ |
195 | G_LOG_LEVEL_CRITICAL, \ |
196 | "%s (%s): assertion `%s' failed.\n" \ |
197 | "There is a disparity between the internal view of the CtkTreeView,\n" \ |
198 | "and the CtkTreeModel. This generally means that the model has changed\n"\ |
199 | "without letting the view know. Any display from now on is likely to\n" \ |
200 | "be incorrect.\n", \ |
201 | G_STRLOC"ctktreeview.c" ":" "201", \ |
202 | G_STRFUNC((const char*) (__func__)), \ |
203 | #expr); \ |
204 | return; \ |
205 | }; }G_STMT_ENDwhile (0) |
206 | |
207 | #else |
208 | |
209 | #define TREE_VIEW_INTERNAL_ASSERT(expr, ret)do{ if (!(expr)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "209", ((const char*) (__func__)), "expr"); return ret; }; }while (0) G_STMT_STARTdo{ \ |
210 | if (!(expr)) \ |
211 | { \ |
212 | g_log (G_LOG_DOMAIN"Ctk", \ |
213 | G_LOG_LEVEL_CRITICAL, \ |
214 | "file %s: line %d: assertion `%s' failed.\n" \ |
215 | "There is a disparity between the internal view of the CtkTreeView,\n" \ |
216 | "and the CtkTreeModel. This generally means that the model has changed\n"\ |
217 | "without letting the view know. Any display from now on is likely to\n" \ |
218 | "be incorrect.\n", \ |
219 | __FILE__"ctktreeview.c", \ |
220 | __LINE__220, \ |
221 | #expr); \ |
222 | return ret; \ |
223 | }; }G_STMT_ENDwhile (0) |
224 | |
225 | #define TREE_VIEW_INTERNAL_ASSERT_VOID(expr)do{ if (!(expr)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "225", ((const char*) (__func__)), "expr"); return; }; }while (0) G_STMT_STARTdo{ \ |
226 | if (!(expr)) \ |
227 | { \ |
228 | g_log (G_LOG_DOMAIN"Ctk", \ |
229 | G_LOG_LEVEL_CRITICAL, \ |
230 | "file %s: line %d: assertion '%s' failed.\n" \ |
231 | "There is a disparity between the internal view of the CtkTreeView,\n" \ |
232 | "and the CtkTreeModel. This generally means that the model has changed\n"\ |
233 | "without letting the view know. Any display from now on is likely to\n" \ |
234 | "be incorrect.\n", \ |
235 | __FILE__"ctktreeview.c", \ |
236 | __LINE__236, \ |
237 | #expr); \ |
238 | return; \ |
239 | }; }G_STMT_ENDwhile (0) |
240 | #endif |
241 | |
242 | #define CTK_TREE_VIEW_PRIORITY_VALIDATE((100 + 20) + 5) (CDK_PRIORITY_REDRAW(100 + 20) + 5) |
243 | #define CTK_TREE_VIEW_PRIORITY_SCROLL_SYNC(((100 + 20) + 5) + 2) (CTK_TREE_VIEW_PRIORITY_VALIDATE((100 + 20) + 5) + 2) |
244 | /* 3/5 of cdkframeclockidle.c's FRAME_INTERVAL (16667 microsecs) */ |
245 | #define CTK_TREE_VIEW_TIME_MS_PER_IDLE10 10 |
246 | #define SCROLL_EDGE_SIZE15 15 |
247 | #define CTK_TREE_VIEW_SEARCH_DIALOG_TIMEOUT5000 5000 |
248 | #define AUTO_EXPAND_TIMEOUT500 500 |
249 | |
250 | /* Translate from bin_window coordinates to rbtree (tree coordinates) and |
251 | * vice versa. |
252 | */ |
253 | #define TREE_WINDOW_Y_TO_RBTREE_Y(tree_view,y)((y) + tree_view->priv->dy) ((y) + tree_view->priv->dy) |
254 | #define RBTREE_Y_TO_TREE_WINDOW_Y(tree_view,y)((y) - tree_view->priv->dy) ((y) - tree_view->priv->dy) |
255 | |
256 | typedef struct _CtkTreeViewColumnReorder CtkTreeViewColumnReorder; |
257 | struct _CtkTreeViewColumnReorder |
258 | { |
259 | gint left_align; |
260 | gint right_align; |
261 | CtkTreeViewColumn *left_column; |
262 | CtkTreeViewColumn *right_column; |
263 | }; |
264 | |
265 | typedef struct _CtkTreeViewChild CtkTreeViewChild; |
266 | struct _CtkTreeViewChild |
267 | { |
268 | CtkWidget *widget; |
269 | CtkRBNode *node; |
270 | CtkRBTree *tree; |
271 | CtkTreeViewColumn *column; |
272 | CtkBorder border; |
273 | }; |
274 | |
275 | |
276 | typedef struct _TreeViewDragInfo TreeViewDragInfo; |
277 | struct _TreeViewDragInfo |
278 | { |
279 | CdkModifierType start_button_mask; |
280 | CtkTargetList *_unused_source_target_list; |
281 | CdkDragAction source_actions; |
282 | |
283 | CtkTargetList *_unused_dest_target_list; |
284 | |
285 | guint source_set : 1; |
286 | guint dest_set : 1; |
287 | }; |
288 | |
289 | |
290 | struct _CtkTreeViewPrivate |
291 | { |
292 | CtkTreeModel *model; |
293 | |
294 | /* tree information */ |
295 | CtkRBTree *tree; |
296 | |
297 | /* Container info */ |
298 | GList *children; |
299 | gint width; |
300 | |
301 | guint presize_handler_tick_cb; |
302 | |
303 | /* Adjustments */ |
304 | CtkAdjustment *hadjustment; |
305 | CtkAdjustment *vadjustment; |
306 | gint min_display_width; |
307 | gint min_display_height; |
308 | |
309 | /* Sub windows */ |
310 | CdkWindow *bin_window; |
311 | CdkWindow *header_window; |
312 | |
313 | CtkPixelCache *pixel_cache; |
314 | |
315 | /* CSS nodes */ |
316 | CtkCssNode *header_node; |
317 | |
318 | /* Scroll position state keeping */ |
319 | CtkTreeRowReference *top_row; |
320 | gint top_row_dy; |
321 | /* dy == y pos of top_row + top_row_dy */ |
322 | /* we cache it for simplicity of the code */ |
323 | gint dy; |
324 | |
325 | guint validate_rows_timer; |
326 | guint scroll_sync_timer; |
327 | |
328 | /* Indentation and expander layout */ |
329 | CtkTreeViewColumn *expander_column; |
330 | |
331 | gint level_indentation; |
332 | |
333 | /* Key navigation (focus), selection */ |
334 | gint cursor_offset; |
335 | |
336 | CtkTreeRowReference *anchor; |
337 | CtkRBNode *cursor_node; |
338 | CtkRBTree *cursor_tree; |
339 | |
340 | CtkTreeViewColumn *focus_column; |
341 | |
342 | /* Current pressed node, previously pressed, prelight */ |
343 | CtkRBNode *button_pressed_node; |
344 | CtkRBTree *button_pressed_tree; |
345 | |
346 | gint press_start_x; |
347 | gint press_start_y; |
348 | |
349 | gint event_last_x; |
350 | gint event_last_y; |
351 | |
352 | CtkRBNode *prelight_node; |
353 | CtkRBTree *prelight_tree; |
354 | |
355 | /* Cell Editing */ |
356 | CtkTreeViewColumn *edited_column; |
357 | |
358 | /* Auto expand/collapse timeout in hover mode */ |
359 | guint auto_expand_timeout; |
360 | |
361 | /* Selection information */ |
362 | CtkTreeSelection *selection; |
363 | |
364 | /* Header information */ |
365 | gint header_height; |
366 | gint n_columns; |
367 | GList *columns; |
368 | |
369 | CtkTreeViewColumnDropFunc column_drop_func; |
370 | gpointer column_drop_func_data; |
371 | GDestroyNotify column_drop_func_data_destroy; |
372 | GList *column_drag_info; |
373 | CtkTreeViewColumnReorder *cur_reorder; |
374 | |
375 | gint prev_width_before_expander; |
376 | |
377 | /* Scroll timeout (e.g. during dnd, rubber banding) */ |
378 | guint scroll_timeout; |
379 | |
380 | /* Interactive Header reordering */ |
381 | CdkWindow *drag_window; |
382 | CdkWindow *drag_highlight_window; |
383 | CtkTreeViewColumn *drag_column; |
384 | gint drag_column_x; |
385 | |
386 | /* Interactive Header Resizing */ |
387 | gint drag_pos; |
388 | gint x_drag; |
389 | |
390 | /* Non-interactive Header Resizing, expand flag support */ |
391 | gint last_extra_space; |
392 | gint last_extra_space_per_column; |
393 | gint last_number_of_expand_columns; |
394 | |
395 | /* ATK Hack */ |
396 | CtkTreeDestroyCountFunc destroy_count_func; |
397 | gpointer destroy_count_data; |
398 | GDestroyNotify destroy_count_destroy; |
399 | |
400 | /* Row drag-and-drop */ |
401 | CtkTreeRowReference *drag_dest_row; |
402 | CtkTreeViewDropPosition drag_dest_pos; |
403 | guint open_dest_timeout; |
404 | |
405 | /* Rubber banding */ |
406 | gint rubber_band_status; |
407 | gint rubber_band_x; |
408 | gint rubber_band_y; |
409 | gint rubber_band_extend; |
410 | gint rubber_band_modify; |
411 | |
412 | /* fixed height */ |
413 | gint fixed_height; |
414 | |
415 | CtkRBNode *rubber_band_start_node; |
416 | CtkRBTree *rubber_band_start_tree; |
417 | |
418 | CtkRBNode *rubber_band_end_node; |
419 | CtkRBTree *rubber_band_end_tree; |
420 | CtkCssNode *rubber_band_cssnode; |
421 | |
422 | /* Scroll-to functionality when unrealized */ |
423 | CtkTreeRowReference *scroll_to_path; |
424 | CtkTreeViewColumn *scroll_to_column; |
425 | gfloat scroll_to_row_align; |
426 | gfloat scroll_to_col_align; |
427 | |
428 | /* Interactive search */ |
429 | gint selected_iter; |
430 | gint search_column; |
431 | CtkTreeViewSearchPositionFunc search_position_func; |
432 | CtkTreeViewSearchEqualFunc search_equal_func; |
433 | gpointer search_user_data; |
434 | GDestroyNotify search_destroy; |
435 | gpointer search_position_user_data; |
436 | GDestroyNotify search_position_destroy; |
437 | CtkWidget *search_window; |
438 | CtkWidget *search_entry; |
439 | gulong search_entry_changed_id; |
440 | guint typeselect_flush_timeout; |
441 | |
442 | /* Grid and tree lines */ |
443 | CtkTreeViewGridLines grid_lines; |
444 | double grid_line_dashes[2]; |
445 | int grid_line_width; |
446 | |
447 | gboolean tree_lines_enabled; |
448 | double tree_line_dashes[2]; |
449 | int tree_line_width; |
450 | |
451 | /* Row separators */ |
452 | CtkTreeViewRowSeparatorFunc row_separator_func; |
453 | gpointer row_separator_data; |
454 | GDestroyNotify row_separator_destroy; |
455 | |
456 | /* Gestures */ |
457 | CtkGesture *multipress_gesture; |
458 | CtkGesture *column_multipress_gesture; |
459 | CtkGesture *drag_gesture; /* Rubberbanding, row DnD */ |
460 | CtkGesture *column_drag_gesture; /* Column reordering, resizing */ |
461 | |
462 | /* Tooltip support */ |
463 | gint tooltip_column; |
464 | |
465 | /* Here comes the bitfield */ |
466 | guint scroll_to_use_align : 1; |
467 | |
468 | guint fixed_height_mode : 1; |
469 | guint fixed_height_check : 1; |
470 | |
471 | guint activate_on_single_click : 1; |
472 | guint reorderable : 1; |
473 | guint header_has_focus : 1; |
474 | guint drag_column_window_state : 3; |
475 | /* hint to display rows in alternating colors */ |
476 | guint has_rules : 1; |
477 | guint mark_rows_col_dirty : 1; |
478 | |
479 | /* for DnD */ |
480 | guint empty_view_drop : 1; |
481 | |
482 | guint modify_selection_pressed : 1; |
483 | guint extend_selection_pressed : 1; |
484 | |
485 | guint init_hadjust_value : 1; |
486 | |
487 | guint in_top_row_to_dy : 1; |
488 | |
489 | /* interactive search */ |
490 | guint enable_search : 1; |
491 | guint disable_popdown : 1; |
492 | guint search_custom_entry_set : 1; |
493 | |
494 | guint hover_selection : 1; |
495 | guint hover_expand : 1; |
496 | guint imcontext_changed : 1; |
497 | |
498 | guint rubber_banding_enable : 1; |
499 | |
500 | guint in_grab : 1; |
501 | |
502 | guint post_validation_flag : 1; |
503 | |
504 | /* Whether our key press handler is to avoid sending an unhandled binding to the search entry */ |
505 | guint search_entry_avoid_unhandled_binding : 1; |
506 | |
507 | /* CtkScrollablePolicy needs to be checked when |
508 | * driving the scrollable adjustment values */ |
509 | guint hscroll_policy : 1; |
510 | guint vscroll_policy : 1; |
511 | |
512 | /* CtkTreeView flags */ |
513 | guint is_list : 1; |
514 | guint show_expanders : 1; |
515 | guint in_column_resize : 1; |
516 | guint arrow_prelit : 1; |
517 | guint headers_visible : 1; |
518 | guint draw_keyfocus : 1; |
519 | guint model_setup : 1; |
520 | guint in_column_drag : 1; |
521 | }; |
522 | |
523 | |
524 | /* Signals */ |
525 | enum |
526 | { |
527 | ROW_ACTIVATED, |
528 | TEST_EXPAND_ROW, |
529 | TEST_COLLAPSE_ROW, |
530 | ROW_EXPANDED, |
531 | ROW_COLLAPSED, |
532 | COLUMNS_CHANGED, |
533 | CURSOR_CHANGED, |
534 | MOVE_CURSOR, |
535 | SELECT_ALL, |
536 | UNSELECT_ALL, |
537 | SELECT_CURSOR_ROW, |
538 | TOGGLE_CURSOR_ROW, |
539 | EXPAND_COLLAPSE_CURSOR_ROW, |
540 | SELECT_CURSOR_PARENT, |
541 | START_INTERACTIVE_SEARCH, |
542 | LAST_SIGNAL |
543 | }; |
544 | |
545 | /* Properties */ |
546 | enum { |
547 | PROP_0, |
548 | PROP_MODEL, |
549 | PROP_HEADERS_VISIBLE, |
550 | PROP_HEADERS_CLICKABLE, |
551 | PROP_EXPANDER_COLUMN, |
552 | PROP_REORDERABLE, |
553 | PROP_RULES_HINT, |
554 | PROP_ENABLE_SEARCH, |
555 | PROP_SEARCH_COLUMN, |
556 | PROP_FIXED_HEIGHT_MODE, |
557 | PROP_HOVER_SELECTION, |
558 | PROP_HOVER_EXPAND, |
559 | PROP_SHOW_EXPANDERS, |
560 | PROP_LEVEL_INDENTATION, |
561 | PROP_RUBBER_BANDING, |
562 | PROP_ENABLE_GRID_LINES, |
563 | PROP_ENABLE_TREE_LINES, |
564 | PROP_TOOLTIP_COLUMN, |
565 | PROP_ACTIVATE_ON_SINGLE_CLICK, |
566 | LAST_PROP, |
567 | /* overridden */ |
568 | PROP_HADJUSTMENT = LAST_PROP, |
569 | PROP_VADJUSTMENT, |
570 | PROP_HSCROLL_POLICY, |
571 | PROP_VSCROLL_POLICY, |
572 | }; |
573 | |
574 | /* object signals */ |
575 | static void ctk_tree_view_finalize (GObject *object); |
576 | static void ctk_tree_view_set_property (GObject *object, |
577 | guint prop_id, |
578 | const GValue *value, |
579 | GParamSpec *pspec); |
580 | static void ctk_tree_view_get_property (GObject *object, |
581 | guint prop_id, |
582 | GValue *value, |
583 | GParamSpec *pspec); |
584 | |
585 | /* ctkwidget signals */ |
586 | static void ctk_tree_view_destroy (CtkWidget *widget); |
587 | static void ctk_tree_view_realize (CtkWidget *widget); |
588 | static void ctk_tree_view_unrealize (CtkWidget *widget); |
589 | static void ctk_tree_view_map (CtkWidget *widget); |
590 | static void ctk_tree_view_unmap (CtkWidget *widget); |
591 | static void ctk_tree_view_get_preferred_width (CtkWidget *widget, |
592 | gint *minimum, |
593 | gint *natural); |
594 | static void ctk_tree_view_get_preferred_height (CtkWidget *widget, |
595 | gint *minimum, |
596 | gint *natural); |
597 | static void ctk_tree_view_size_allocate (CtkWidget *widget, |
598 | CtkAllocation *allocation); |
599 | static gboolean ctk_tree_view_draw (CtkWidget *widget, |
600 | cairo_t *cr); |
601 | static gboolean ctk_tree_view_key_press (CtkWidget *widget, |
602 | CdkEventKey *event); |
603 | static gboolean ctk_tree_view_key_release (CtkWidget *widget, |
604 | CdkEventKey *event); |
605 | static gboolean ctk_tree_view_motion (CtkWidget *widget, |
606 | CdkEventMotion *event); |
607 | static gboolean ctk_tree_view_enter_notify (CtkWidget *widget, |
608 | CdkEventCrossing *event); |
609 | static gboolean ctk_tree_view_leave_notify (CtkWidget *widget, |
610 | CdkEventCrossing *event); |
611 | |
612 | static void ctk_tree_view_set_focus_child (CtkContainer *container, |
613 | CtkWidget *child); |
614 | static gint ctk_tree_view_focus_out (CtkWidget *widget, |
615 | CdkEventFocus *event); |
616 | static gint ctk_tree_view_focus (CtkWidget *widget, |
617 | CtkDirectionType direction); |
618 | static void ctk_tree_view_grab_focus (CtkWidget *widget); |
619 | static void ctk_tree_view_style_updated (CtkWidget *widget); |
620 | |
621 | /* container signals */ |
622 | static void ctk_tree_view_remove (CtkContainer *container, |
623 | CtkWidget *widget); |
624 | static void ctk_tree_view_forall (CtkContainer *container, |
625 | gboolean include_internals, |
626 | CtkCallback callback, |
627 | gpointer callback_data); |
628 | |
629 | /* Source side drag signals */ |
630 | static void ctk_tree_view_drag_begin (CtkWidget *widget, |
631 | CdkDragContext *context); |
632 | static void ctk_tree_view_drag_end (CtkWidget *widget, |
633 | CdkDragContext *context); |
634 | static void ctk_tree_view_drag_data_get (CtkWidget *widget, |
635 | CdkDragContext *context, |
636 | CtkSelectionData *selection_data, |
637 | guint info, |
638 | guint time); |
639 | static void ctk_tree_view_drag_data_delete (CtkWidget *widget, |
640 | CdkDragContext *context); |
641 | |
642 | /* Target side drag signals */ |
643 | static void ctk_tree_view_drag_leave (CtkWidget *widget, |
644 | CdkDragContext *context, |
645 | guint time); |
646 | static gboolean ctk_tree_view_drag_motion (CtkWidget *widget, |
647 | CdkDragContext *context, |
648 | gint x, |
649 | gint y, |
650 | guint time); |
651 | static gboolean ctk_tree_view_drag_drop (CtkWidget *widget, |
652 | CdkDragContext *context, |
653 | gint x, |
654 | gint y, |
655 | guint time); |
656 | static void ctk_tree_view_drag_data_received (CtkWidget *widget, |
657 | CdkDragContext *context, |
658 | gint x, |
659 | gint y, |
660 | CtkSelectionData *selection_data, |
661 | guint info, |
662 | guint time); |
663 | |
664 | /* tree_model signals */ |
665 | static gboolean ctk_tree_view_real_move_cursor (CtkTreeView *tree_view, |
666 | CtkMovementStep step, |
667 | gint count); |
668 | static gboolean ctk_tree_view_real_select_all (CtkTreeView *tree_view); |
669 | static gboolean ctk_tree_view_real_unselect_all (CtkTreeView *tree_view); |
670 | static gboolean ctk_tree_view_real_select_cursor_row (CtkTreeView *tree_view, |
671 | gboolean start_editing); |
672 | static gboolean ctk_tree_view_real_toggle_cursor_row (CtkTreeView *tree_view); |
673 | static gboolean ctk_tree_view_real_expand_collapse_cursor_row (CtkTreeView *tree_view, |
674 | gboolean logical, |
675 | gboolean expand, |
676 | gboolean open_all); |
677 | static gboolean ctk_tree_view_real_select_cursor_parent (CtkTreeView *tree_view); |
678 | static void ctk_tree_view_row_changed (CtkTreeModel *model, |
679 | CtkTreePath *path, |
680 | CtkTreeIter *iter, |
681 | gpointer data); |
682 | static void ctk_tree_view_row_inserted (CtkTreeModel *model, |
683 | CtkTreePath *path, |
684 | CtkTreeIter *iter, |
685 | gpointer data); |
686 | static void ctk_tree_view_row_has_child_toggled (CtkTreeModel *model, |
687 | CtkTreePath *path, |
688 | CtkTreeIter *iter, |
689 | gpointer data); |
690 | static void ctk_tree_view_row_deleted (CtkTreeModel *model, |
691 | CtkTreePath *path, |
692 | gpointer data); |
693 | static void ctk_tree_view_rows_reordered (CtkTreeModel *model, |
694 | CtkTreePath *parent, |
695 | CtkTreeIter *iter, |
696 | gint *new_order, |
697 | gpointer data); |
698 | |
699 | /* Incremental reflow */ |
700 | static gboolean validate_row (CtkTreeView *tree_view, |
701 | CtkRBTree *tree, |
702 | CtkRBNode *node, |
703 | CtkTreeIter *iter, |
704 | CtkTreePath *path); |
705 | static void validate_visible_area (CtkTreeView *tree_view); |
706 | static gboolean do_validate_rows (CtkTreeView *tree_view, |
707 | gboolean queue_resize); |
708 | static gboolean validate_rows (CtkTreeView *tree_view); |
709 | static void install_presize_handler (CtkTreeView *tree_view); |
710 | static void install_scroll_sync_handler (CtkTreeView *tree_view); |
711 | static void ctk_tree_view_set_top_row (CtkTreeView *tree_view, |
712 | CtkTreePath *path, |
713 | gint offset); |
714 | static void ctk_tree_view_dy_to_top_row (CtkTreeView *tree_view); |
715 | static void ctk_tree_view_top_row_to_dy (CtkTreeView *tree_view); |
716 | static void invalidate_empty_focus (CtkTreeView *tree_view); |
717 | |
718 | /* Internal functions */ |
719 | static gboolean ctk_tree_view_is_expander_column (CtkTreeView *tree_view, |
720 | CtkTreeViewColumn *column); |
721 | static inline gboolean ctk_tree_view_draw_expanders (CtkTreeView *tree_view); |
722 | static void ctk_tree_view_add_move_binding (CtkBindingSet *binding_set, |
723 | guint keyval, |
724 | guint modmask, |
725 | gboolean add_shifted_binding, |
726 | CtkMovementStep step, |
727 | gint count); |
728 | static gint ctk_tree_view_unref_and_check_selection_tree (CtkTreeView *tree_view, |
729 | CtkRBTree *tree); |
730 | static void ctk_tree_view_queue_draw_path (CtkTreeView *tree_view, |
731 | CtkTreePath *path, |
732 | const CdkRectangle *clip_rect); |
733 | static void ctk_tree_view_queue_draw_arrow (CtkTreeView *tree_view, |
734 | CtkRBTree *tree, |
735 | CtkRBNode *node); |
736 | static void ctk_tree_view_draw_arrow (CtkTreeView *tree_view, |
737 | cairo_t *cr, |
738 | CtkRBTree *tree, |
739 | CtkRBNode *node); |
740 | static void ctk_tree_view_get_arrow_xrange (CtkTreeView *tree_view, |
741 | CtkRBTree *tree, |
742 | gint *x1, |
743 | gint *x2); |
744 | static void ctk_tree_view_adjustment_changed (CtkAdjustment *adjustment, |
745 | CtkTreeView *tree_view); |
746 | static void ctk_tree_view_build_tree (CtkTreeView *tree_view, |
747 | CtkRBTree *tree, |
748 | CtkTreeIter *iter, |
749 | gint depth, |
750 | gboolean recurse); |
751 | static void ctk_tree_view_clamp_node_visible (CtkTreeView *tree_view, |
752 | CtkRBTree *tree, |
753 | CtkRBNode *node); |
754 | static void ctk_tree_view_clamp_column_visible (CtkTreeView *tree_view, |
755 | CtkTreeViewColumn *column, |
756 | gboolean focus_to_cell); |
757 | static gboolean ctk_tree_view_maybe_begin_dragging_row (CtkTreeView *tree_view); |
758 | static void ctk_tree_view_focus_to_cursor (CtkTreeView *tree_view); |
759 | static void ctk_tree_view_move_cursor_up_down (CtkTreeView *tree_view, |
760 | gint count); |
761 | static void ctk_tree_view_move_cursor_page_up_down (CtkTreeView *tree_view, |
762 | gint count); |
763 | static void ctk_tree_view_move_cursor_left_right (CtkTreeView *tree_view, |
764 | gint count); |
765 | static void ctk_tree_view_move_cursor_start_end (CtkTreeView *tree_view, |
766 | gint count); |
767 | static gboolean ctk_tree_view_real_collapse_row (CtkTreeView *tree_view, |
768 | CtkTreePath *path, |
769 | CtkRBTree *tree, |
770 | CtkRBNode *node, |
771 | gboolean animate); |
772 | static gboolean ctk_tree_view_real_expand_row (CtkTreeView *tree_view, |
773 | CtkTreePath *path, |
774 | CtkRBTree *tree, |
775 | CtkRBNode *node, |
776 | gboolean open_all, |
777 | gboolean animate); |
778 | static void ctk_tree_view_real_set_cursor (CtkTreeView *tree_view, |
779 | CtkTreePath *path, |
780 | SetCursorFlags flags); |
781 | static gboolean ctk_tree_view_has_can_focus_cell (CtkTreeView *tree_view); |
782 | static void column_sizing_notify (GObject *object, |
783 | GParamSpec *pspec, |
784 | gpointer data); |
785 | static void ctk_tree_view_stop_rubber_band (CtkTreeView *tree_view); |
786 | static void update_prelight (CtkTreeView *tree_view, |
787 | int x, |
788 | int y); |
789 | static void ctk_tree_view_queue_draw_region (CtkWidget *widget, |
790 | const cairo_region_t *region); |
791 | |
792 | static inline gint ctk_tree_view_get_effective_header_height (CtkTreeView *tree_view); |
793 | |
794 | static inline gint ctk_tree_view_get_cell_area_y_offset (CtkTreeView *tree_view, |
795 | CtkRBTree *tree, |
796 | CtkRBNode *node, |
797 | gint vertical_separator); |
798 | static inline gint ctk_tree_view_get_cell_area_height (CtkTreeView *tree_view, |
799 | CtkRBNode *node, |
800 | gint vertical_separator); |
801 | |
802 | static inline gint ctk_tree_view_get_row_y_offset (CtkTreeView *tree_view, |
803 | CtkRBTree *tree, |
804 | CtkRBNode *node); |
805 | static inline gint ctk_tree_view_get_row_height (CtkTreeView *tree_view, |
806 | CtkRBNode *node); |
807 | |
808 | /* interactive search */ |
809 | static void ctk_tree_view_ensure_interactive_directory (CtkTreeView *tree_view); |
810 | static void ctk_tree_view_search_window_hide (CtkWidget *search_window, |
811 | CtkTreeView *tree_view, |
812 | CdkDevice *device); |
813 | static void ctk_tree_view_search_position_func (CtkTreeView *tree_view, |
814 | CtkWidget *search_window, |
815 | gpointer user_data); |
816 | static void ctk_tree_view_search_disable_popdown (CtkEntry *entry, |
817 | CtkMenu *menu, |
818 | gpointer data); |
819 | static void ctk_tree_view_search_preedit_changed (CtkIMContext *im_context, |
820 | CtkTreeView *tree_view); |
821 | static void ctk_tree_view_search_commit (CtkIMContext *im_context, |
822 | gchar *buf, |
823 | CtkTreeView *tree_view); |
824 | static void ctk_tree_view_search_activate (CtkEntry *entry, |
825 | CtkTreeView *tree_view); |
826 | static gboolean ctk_tree_view_real_search_enable_popdown(gpointer data); |
827 | static void ctk_tree_view_search_enable_popdown (CtkWidget *widget, |
828 | gpointer data); |
829 | static gboolean ctk_tree_view_search_delete_event (CtkWidget *widget, |
830 | CdkEventAny *event, |
831 | CtkTreeView *tree_view); |
832 | static gboolean ctk_tree_view_search_button_press_event (CtkWidget *widget, |
833 | CdkEventButton *event, |
834 | CtkTreeView *tree_view); |
835 | static gboolean ctk_tree_view_search_scroll_event (CtkWidget *entry, |
836 | CdkEventScroll *event, |
837 | CtkTreeView *tree_view); |
838 | static gboolean ctk_tree_view_search_key_press_event (CtkWidget *entry, |
839 | CdkEventKey *event, |
840 | CtkTreeView *tree_view); |
841 | static gboolean ctk_tree_view_search_move (CtkWidget *window, |
842 | CtkTreeView *tree_view, |
843 | gboolean up); |
844 | static gboolean ctk_tree_view_search_equal_func (CtkTreeModel *model, |
845 | gint column, |
846 | const gchar *key, |
847 | CtkTreeIter *iter, |
848 | gpointer search_data); |
849 | static gboolean ctk_tree_view_search_iter (CtkTreeModel *model, |
850 | CtkTreeSelection *selection, |
851 | CtkTreeIter *iter, |
852 | const gchar *text, |
853 | gint *count, |
854 | gint n); |
855 | static void ctk_tree_view_search_init (CtkWidget *entry, |
856 | CtkTreeView *tree_view); |
857 | static void ctk_tree_view_put (CtkTreeView *tree_view, |
858 | CtkWidget *child_widget, |
859 | CtkTreePath *path, |
860 | CtkTreeViewColumn*column, |
861 | const CtkBorder *border); |
862 | static gboolean ctk_tree_view_start_editing (CtkTreeView *tree_view, |
863 | CtkTreePath *cursor_path, |
864 | gboolean edit_only); |
865 | static void ctk_tree_view_stop_editing (CtkTreeView *tree_view, |
866 | gboolean cancel_editing); |
867 | static gboolean ctk_tree_view_real_start_interactive_search (CtkTreeView *tree_view, |
868 | CdkDevice *device, |
869 | gboolean keybinding); |
870 | static gboolean ctk_tree_view_start_interactive_search (CtkTreeView *tree_view); |
871 | static CtkTreeViewColumn *ctk_tree_view_get_drop_column (CtkTreeView *tree_view, |
872 | CtkTreeViewColumn *column, |
873 | gint drop_position); |
874 | |
875 | /* CtkBuildable */ |
876 | static void ctk_tree_view_buildable_add_child (CtkBuildable *tree_view, |
877 | CtkBuilder *builder, |
878 | GObject *child, |
879 | const gchar *type); |
880 | static GObject *ctk_tree_view_buildable_get_internal_child (CtkBuildable *buildable, |
881 | CtkBuilder *builder, |
882 | const gchar *childname); |
883 | static void ctk_tree_view_buildable_init (CtkBuildableIface *iface); |
884 | |
885 | /* CtkScrollable */ |
886 | static void ctk_tree_view_scrollable_init (CtkScrollableInterface *iface); |
887 | |
888 | static CtkAdjustment *ctk_tree_view_do_get_hadjustment (CtkTreeView *tree_view); |
889 | static void ctk_tree_view_do_set_hadjustment (CtkTreeView *tree_view, |
890 | CtkAdjustment *adjustment); |
891 | static CtkAdjustment *ctk_tree_view_do_get_vadjustment (CtkTreeView *tree_view); |
892 | static void ctk_tree_view_do_set_vadjustment (CtkTreeView *tree_view, |
893 | CtkAdjustment *adjustment); |
894 | |
895 | static gboolean scroll_row_timeout (gpointer data); |
896 | static void add_scroll_timeout (CtkTreeView *tree_view); |
897 | static void remove_scroll_timeout (CtkTreeView *tree_view); |
898 | |
899 | static void grab_focus_and_unset_draw_keyfocus (CtkTreeView *tree_view); |
900 | |
901 | /* Gestures */ |
902 | static void ctk_tree_view_column_multipress_gesture_pressed (CtkGestureMultiPress *gesture, |
903 | gint n_press, |
904 | gdouble x, |
905 | gdouble y, |
906 | CtkTreeView *tree_view); |
907 | |
908 | static void ctk_tree_view_multipress_gesture_pressed (CtkGestureMultiPress *gesture, |
909 | gint n_press, |
910 | gdouble x, |
911 | gdouble y, |
912 | CtkTreeView *tree_view); |
913 | static void ctk_tree_view_multipress_gesture_released (CtkGestureMultiPress *gesture, |
914 | gint n_press, |
915 | gdouble x, |
916 | gdouble y, |
917 | CtkTreeView *tree_view); |
918 | |
919 | static void ctk_tree_view_column_drag_gesture_begin (CtkGestureDrag *gesture, |
920 | gdouble start_x, |
921 | gdouble start_y, |
922 | CtkTreeView *tree_view); |
923 | static void ctk_tree_view_column_drag_gesture_update (CtkGestureDrag *gesture, |
924 | gdouble offset_x, |
925 | gdouble offset_y, |
926 | CtkTreeView *tree_view); |
927 | static void ctk_tree_view_column_drag_gesture_end (CtkGestureDrag *gesture, |
928 | gdouble offset_x, |
929 | gdouble offset_y, |
930 | CtkTreeView *tree_view); |
931 | |
932 | static void ctk_tree_view_drag_gesture_begin (CtkGestureDrag *gesture, |
933 | gdouble start_x, |
934 | gdouble start_y, |
935 | CtkTreeView *tree_view); |
936 | static void ctk_tree_view_drag_gesture_update (CtkGestureDrag *gesture, |
937 | gdouble offset_x, |
938 | gdouble offset_y, |
939 | CtkTreeView *tree_view); |
940 | static void ctk_tree_view_drag_gesture_end (CtkGestureDrag *gesture, |
941 | gdouble offset_x, |
942 | gdouble offset_y, |
943 | CtkTreeView *tree_view); |
944 | |
945 | static guint tree_view_signals [LAST_SIGNAL] = { 0 }; |
946 | static GParamSpec *tree_view_props [LAST_PROP] = { NULL((void*)0) }; |
947 | |
948 | |
949 | |
950 | /* GType Methods |
951 | */ |
952 | |
953 | G_DEFINE_TYPE_WITH_CODE (CtkTreeView, ctk_tree_view, CTK_TYPE_CONTAINER,static void ctk_tree_view_init (CtkTreeView *self); static void ctk_tree_view_class_init (CtkTreeViewClass *klass); static GType ctk_tree_view_get_type_once (void); static gpointer ctk_tree_view_parent_class = ((void*)0); static gint CtkTreeView_private_offset; static void ctk_tree_view_class_intern_init (gpointer klass) { ctk_tree_view_parent_class = g_type_class_peek_parent (klass); if (CtkTreeView_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeView_private_offset ); ctk_tree_view_class_init ((CtkTreeViewClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_view_get_instance_private (CtkTreeView *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkTreeView_private_offset)))); } GType ctk_tree_view_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_tree_view_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_tree_view_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkTreeView" ), sizeof (CtkTreeViewClass), (GClassInitFunc)(void (*)(void) ) ctk_tree_view_class_intern_init, sizeof (CtkTreeView), (GInstanceInitFunc )(void (*)(void)) ctk_tree_view_init, (GTypeFlags) 0); { {{ CtkTreeView_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeViewPrivate )); } { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc)(void (*)(void)) ctk_tree_view_buildable_init , ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_view_scrollable_init, ((void*)0), ( (void*)0) }; g_type_add_interface_static (g_define_type_id, ( ctk_scrollable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
954 | G_ADD_PRIVATE (CtkTreeView)static void ctk_tree_view_init (CtkTreeView *self); static void ctk_tree_view_class_init (CtkTreeViewClass *klass); static GType ctk_tree_view_get_type_once (void); static gpointer ctk_tree_view_parent_class = ((void*)0); static gint CtkTreeView_private_offset; static void ctk_tree_view_class_intern_init (gpointer klass) { ctk_tree_view_parent_class = g_type_class_peek_parent (klass); if (CtkTreeView_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeView_private_offset ); ctk_tree_view_class_init ((CtkTreeViewClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_view_get_instance_private (CtkTreeView *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkTreeView_private_offset)))); } GType ctk_tree_view_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_tree_view_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_tree_view_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkTreeView" ), sizeof (CtkTreeViewClass), (GClassInitFunc)(void (*)(void) ) ctk_tree_view_class_intern_init, sizeof (CtkTreeView), (GInstanceInitFunc )(void (*)(void)) ctk_tree_view_init, (GTypeFlags) 0); { {{ CtkTreeView_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeViewPrivate )); } { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc)(void (*)(void)) ctk_tree_view_buildable_init , ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_view_scrollable_init, ((void*)0), ( (void*)0) }; g_type_add_interface_static (g_define_type_id, ( ctk_scrollable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
955 | G_IMPLEMENT_INTERFACE (CTK_TYPE_BUILDABLE,static void ctk_tree_view_init (CtkTreeView *self); static void ctk_tree_view_class_init (CtkTreeViewClass *klass); static GType ctk_tree_view_get_type_once (void); static gpointer ctk_tree_view_parent_class = ((void*)0); static gint CtkTreeView_private_offset; static void ctk_tree_view_class_intern_init (gpointer klass) { ctk_tree_view_parent_class = g_type_class_peek_parent (klass); if (CtkTreeView_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeView_private_offset ); ctk_tree_view_class_init ((CtkTreeViewClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_view_get_instance_private (CtkTreeView *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkTreeView_private_offset)))); } GType ctk_tree_view_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_tree_view_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_tree_view_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkTreeView" ), sizeof (CtkTreeViewClass), (GClassInitFunc)(void (*)(void) ) ctk_tree_view_class_intern_init, sizeof (CtkTreeView), (GInstanceInitFunc )(void (*)(void)) ctk_tree_view_init, (GTypeFlags) 0); { {{ CtkTreeView_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeViewPrivate )); } { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc)(void (*)(void)) ctk_tree_view_buildable_init , ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_view_scrollable_init, ((void*)0), ( (void*)0) }; g_type_add_interface_static (g_define_type_id, ( ctk_scrollable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
956 | ctk_tree_view_buildable_init)static void ctk_tree_view_init (CtkTreeView *self); static void ctk_tree_view_class_init (CtkTreeViewClass *klass); static GType ctk_tree_view_get_type_once (void); static gpointer ctk_tree_view_parent_class = ((void*)0); static gint CtkTreeView_private_offset; static void ctk_tree_view_class_intern_init (gpointer klass) { ctk_tree_view_parent_class = g_type_class_peek_parent (klass); if (CtkTreeView_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeView_private_offset ); ctk_tree_view_class_init ((CtkTreeViewClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_view_get_instance_private (CtkTreeView *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkTreeView_private_offset)))); } GType ctk_tree_view_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_tree_view_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_tree_view_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkTreeView" ), sizeof (CtkTreeViewClass), (GClassInitFunc)(void (*)(void) ) ctk_tree_view_class_intern_init, sizeof (CtkTreeView), (GInstanceInitFunc )(void (*)(void)) ctk_tree_view_init, (GTypeFlags) 0); { {{ CtkTreeView_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeViewPrivate )); } { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc)(void (*)(void)) ctk_tree_view_buildable_init , ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_view_scrollable_init, ((void*)0), ( (void*)0) }; g_type_add_interface_static (g_define_type_id, ( ctk_scrollable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
957 | G_IMPLEMENT_INTERFACE (CTK_TYPE_SCROLLABLE,static void ctk_tree_view_init (CtkTreeView *self); static void ctk_tree_view_class_init (CtkTreeViewClass *klass); static GType ctk_tree_view_get_type_once (void); static gpointer ctk_tree_view_parent_class = ((void*)0); static gint CtkTreeView_private_offset; static void ctk_tree_view_class_intern_init (gpointer klass) { ctk_tree_view_parent_class = g_type_class_peek_parent (klass); if (CtkTreeView_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeView_private_offset ); ctk_tree_view_class_init ((CtkTreeViewClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_view_get_instance_private (CtkTreeView *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkTreeView_private_offset)))); } GType ctk_tree_view_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_tree_view_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_tree_view_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkTreeView" ), sizeof (CtkTreeViewClass), (GClassInitFunc)(void (*)(void) ) ctk_tree_view_class_intern_init, sizeof (CtkTreeView), (GInstanceInitFunc )(void (*)(void)) ctk_tree_view_init, (GTypeFlags) 0); { {{ CtkTreeView_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeViewPrivate )); } { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc)(void (*)(void)) ctk_tree_view_buildable_init , ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_view_scrollable_init, ((void*)0), ( (void*)0) }; g_type_add_interface_static (g_define_type_id, ( ctk_scrollable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
958 | ctk_tree_view_scrollable_init))static void ctk_tree_view_init (CtkTreeView *self); static void ctk_tree_view_class_init (CtkTreeViewClass *klass); static GType ctk_tree_view_get_type_once (void); static gpointer ctk_tree_view_parent_class = ((void*)0); static gint CtkTreeView_private_offset; static void ctk_tree_view_class_intern_init (gpointer klass) { ctk_tree_view_parent_class = g_type_class_peek_parent (klass); if (CtkTreeView_private_offset != 0) g_type_class_adjust_private_offset (klass, &CtkTreeView_private_offset ); ctk_tree_view_class_init ((CtkTreeViewClass*) klass); } __attribute__ ((__unused__)) static inline gpointer ctk_tree_view_get_instance_private (CtkTreeView *self) { return (((gpointer) ((guint8*) (self) + (glong) (CtkTreeView_private_offset)))); } GType ctk_tree_view_get_type (void) { static GType static_g_define_type_id = 0; if ((__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer), "Expression evaluates to false"); (void) ( 0 ? (gpointer) * (&static_g_define_type_id) : ((void*)0)) ; (!(__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id ) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (*(&static_g_define_type_id)) gapg_temp_newval; __typeof__ ((&static_g_define_type_id)) gapg_temp_atomic = (&static_g_define_type_id ); __atomic_load (gapg_temp_atomic, &gapg_temp_newval, 5) ; gapg_temp_newval; })) && g_once_init_enter_pointer ( &static_g_define_type_id)); })) ) { GType g_define_type_id = ctk_tree_view_get_type_once (); (__extension__ ({ _Static_assert (sizeof *(&static_g_define_type_id) == sizeof (gpointer) , "Expression evaluates to false"); 0 ? (void) (*(&static_g_define_type_id ) = (g_define_type_id)) : (void) 0; g_once_init_leave_pointer ((&static_g_define_type_id), (gpointer) (guintptr) (g_define_type_id )); })) ; } return static_g_define_type_id; } __attribute__ ( (__noinline__)) static GType ctk_tree_view_get_type_once (void ) { GType g_define_type_id = g_type_register_static_simple (( ctk_container_get_type ()), g_intern_static_string ("CtkTreeView" ), sizeof (CtkTreeViewClass), (GClassInitFunc)(void (*)(void) ) ctk_tree_view_class_intern_init, sizeof (CtkTreeView), (GInstanceInitFunc )(void (*)(void)) ctk_tree_view_init, (GTypeFlags) 0); { {{ CtkTreeView_private_offset = g_type_add_instance_private (g_define_type_id, sizeof (CtkTreeViewPrivate )); } { const GInterfaceInfo g_implement_interface_info = { ( GInterfaceInitFunc)(void (*)(void)) ctk_tree_view_buildable_init , ((void*)0), ((void*)0) }; g_type_add_interface_static (g_define_type_id , (ctk_buildable_get_type ()), &g_implement_interface_info ); } { const GInterfaceInfo g_implement_interface_info = { (GInterfaceInitFunc )(void (*)(void)) ctk_tree_view_scrollable_init, ((void*)0), ( (void*)0) }; g_type_add_interface_static (g_define_type_id, ( ctk_scrollable_get_type ()), &g_implement_interface_info) ; };} } return g_define_type_id; } |
959 | |
960 | static void |
961 | ctk_tree_view_class_init (CtkTreeViewClass *class) |
962 | { |
963 | GObjectClass *o_class; |
964 | CtkWidgetClass *widget_class; |
965 | CtkContainerClass *container_class; |
966 | CtkBindingSet *binding_set; |
967 | |
968 | binding_set = ctk_binding_set_by_class (class); |
969 | |
970 | o_class = (GObjectClass *) class; |
971 | widget_class = (CtkWidgetClass *) class; |
972 | container_class = (CtkContainerClass *) class; |
973 | |
974 | /* GObject signals */ |
975 | o_class->set_property = ctk_tree_view_set_property; |
976 | o_class->get_property = ctk_tree_view_get_property; |
977 | o_class->finalize = ctk_tree_view_finalize; |
978 | |
979 | /* CtkWidget signals */ |
980 | widget_class->destroy = ctk_tree_view_destroy; |
981 | widget_class->map = ctk_tree_view_map; |
982 | widget_class->unmap = ctk_tree_view_unmap; |
983 | widget_class->realize = ctk_tree_view_realize; |
984 | widget_class->unrealize = ctk_tree_view_unrealize; |
985 | widget_class->get_preferred_width = ctk_tree_view_get_preferred_width; |
986 | widget_class->get_preferred_height = ctk_tree_view_get_preferred_height; |
987 | widget_class->size_allocate = ctk_tree_view_size_allocate; |
988 | widget_class->motion_notify_event = ctk_tree_view_motion; |
989 | widget_class->draw = ctk_tree_view_draw; |
990 | widget_class->key_press_event = ctk_tree_view_key_press; |
991 | widget_class->key_release_event = ctk_tree_view_key_release; |
992 | widget_class->enter_notify_event = ctk_tree_view_enter_notify; |
993 | widget_class->leave_notify_event = ctk_tree_view_leave_notify; |
994 | widget_class->focus_out_event = ctk_tree_view_focus_out; |
995 | widget_class->drag_begin = ctk_tree_view_drag_begin; |
996 | widget_class->drag_end = ctk_tree_view_drag_end; |
997 | widget_class->drag_data_get = ctk_tree_view_drag_data_get; |
998 | widget_class->drag_data_delete = ctk_tree_view_drag_data_delete; |
999 | widget_class->drag_leave = ctk_tree_view_drag_leave; |
1000 | widget_class->drag_motion = ctk_tree_view_drag_motion; |
1001 | widget_class->drag_drop = ctk_tree_view_drag_drop; |
1002 | widget_class->drag_data_received = ctk_tree_view_drag_data_received; |
1003 | widget_class->focus = ctk_tree_view_focus; |
1004 | widget_class->grab_focus = ctk_tree_view_grab_focus; |
1005 | widget_class->style_updated = ctk_tree_view_style_updated; |
1006 | widget_class->queue_draw_region = ctk_tree_view_queue_draw_region; |
1007 | |
1008 | /* CtkContainer signals */ |
1009 | container_class->remove = ctk_tree_view_remove; |
1010 | container_class->forall = ctk_tree_view_forall; |
1011 | container_class->set_focus_child = ctk_tree_view_set_focus_child; |
1012 | |
1013 | class->move_cursor = ctk_tree_view_real_move_cursor; |
1014 | class->select_all = ctk_tree_view_real_select_all; |
1015 | class->unselect_all = ctk_tree_view_real_unselect_all; |
1016 | class->select_cursor_row = ctk_tree_view_real_select_cursor_row; |
1017 | class->toggle_cursor_row = ctk_tree_view_real_toggle_cursor_row; |
1018 | class->expand_collapse_cursor_row = ctk_tree_view_real_expand_collapse_cursor_row; |
1019 | class->select_cursor_parent = ctk_tree_view_real_select_cursor_parent; |
1020 | class->start_interactive_search = ctk_tree_view_start_interactive_search; |
1021 | |
1022 | /* Properties */ |
1023 | |
1024 | g_object_class_override_property (o_class, PROP_HADJUSTMENT, "hadjustment"); |
1025 | g_object_class_override_property (o_class, PROP_VADJUSTMENT, "vadjustment"); |
1026 | g_object_class_override_property (o_class, PROP_HSCROLL_POLICY, "hscroll-policy"); |
1027 | g_object_class_override_property (o_class, PROP_VSCROLL_POLICY, "vscroll-policy"); |
1028 | |
1029 | tree_view_props[PROP_MODEL] = |
1030 | g_param_spec_object ("model", |
1031 | P_("TreeView Model")g_dgettext("ctk30" "-properties","TreeView Model"), |
1032 | P_("The model for the tree view")g_dgettext("ctk30" "-properties","The model for the tree view" ), |
1033 | CTK_TYPE_TREE_MODEL(ctk_tree_model_get_type ()), |
1034 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); |
1035 | |
1036 | tree_view_props[PROP_HEADERS_VISIBLE] = |
1037 | g_param_spec_boolean ("headers-visible", |
1038 | P_("Headers Visible")g_dgettext("ctk30" "-properties","Headers Visible"), |
1039 | P_("Show the column header buttons")g_dgettext("ctk30" "-properties","Show the column header buttons" ), |
1040 | TRUE(!(0)), |
1041 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1042 | |
1043 | tree_view_props[PROP_HEADERS_CLICKABLE] = |
1044 | g_param_spec_boolean ("headers-clickable", |
1045 | P_("Headers Clickable")g_dgettext("ctk30" "-properties","Headers Clickable"), |
1046 | P_("Column headers respond to click events")g_dgettext("ctk30" "-properties","Column headers respond to click events" ), |
1047 | TRUE(!(0)), |
1048 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1049 | |
1050 | tree_view_props[PROP_EXPANDER_COLUMN] = |
1051 | g_param_spec_object ("expander-column", |
1052 | P_("Expander Column")g_dgettext("ctk30" "-properties","Expander Column"), |
1053 | P_("Set the column for the expander column")g_dgettext("ctk30" "-properties","Set the column for the expander column" ), |
1054 | CTK_TYPE_TREE_VIEW_COLUMN(ctk_tree_view_column_get_type ()), |
1055 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB); |
1056 | |
1057 | tree_view_props[PROP_REORDERABLE] = |
1058 | g_param_spec_boolean ("reorderable", |
1059 | P_("Reorderable")g_dgettext("ctk30" "-properties","Reorderable"), |
1060 | P_("View is reorderable")g_dgettext("ctk30" "-properties","View is reorderable"), |
1061 | FALSE(0), |
1062 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1063 | |
1064 | /** |
1065 | * CtkTreeView:rules-hint: |
1066 | * |
1067 | * Sets a hint to the theme to draw rows in alternating colors. |
1068 | * |
1069 | * Deprecated: 3.14: The theme is responsible for drawing rows |
1070 | * using zebra striping |
1071 | */ |
1072 | tree_view_props[PROP_RULES_HINT] = |
1073 | g_param_spec_boolean ("rules-hint", |
1074 | P_("Rules Hint")g_dgettext("ctk30" "-properties","Rules Hint"), |
1075 | P_("Set a hint to the theme engine to draw rows in alternating colors")g_dgettext("ctk30" "-properties","Set a hint to the theme engine to draw rows in alternating colors" ), |
1076 | FALSE(0), |
1077 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY|G_PARAM_DEPRECATED); |
1078 | |
1079 | tree_view_props[PROP_ENABLE_SEARCH] = |
1080 | g_param_spec_boolean ("enable-search", |
1081 | P_("Enable Search")g_dgettext("ctk30" "-properties","Enable Search"), |
1082 | P_("View allows user to search through columns interactively")g_dgettext("ctk30" "-properties","View allows user to search through columns interactively" ), |
1083 | TRUE(!(0)), |
1084 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1085 | |
1086 | tree_view_props[PROP_SEARCH_COLUMN] = |
1087 | g_param_spec_int ("search-column", |
1088 | P_("Search Column")g_dgettext("ctk30" "-properties","Search Column"), |
1089 | P_("Model column to search through during interactive search")g_dgettext("ctk30" "-properties","Model column to search through during interactive search" ), |
1090 | -1, G_MAXINT2147483647, |
1091 | -1, |
1092 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1093 | |
1094 | /** |
1095 | * CtkTreeView:fixed-height-mode: |
1096 | * |
1097 | * Setting the ::fixed-height-mode property to %TRUE speeds up |
1098 | * #CtkTreeView by assuming that all rows have the same height. |
1099 | * Only enable this option if all rows are the same height. |
1100 | * Please see ctk_tree_view_set_fixed_height_mode() for more |
1101 | * information on this option. |
1102 | * |
1103 | * Since: 2.4 |
1104 | */ |
1105 | tree_view_props[PROP_FIXED_HEIGHT_MODE] = |
1106 | g_param_spec_boolean ("fixed-height-mode", |
1107 | P_("Fixed Height Mode")g_dgettext("ctk30" "-properties","Fixed Height Mode"), |
1108 | P_("Speeds up CtkTreeView by assuming that all rows have the same height")g_dgettext("ctk30" "-properties","Speeds up CtkTreeView by assuming that all rows have the same height" ), |
1109 | FALSE(0), |
1110 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1111 | |
1112 | /** |
1113 | * CtkTreeView:hover-selection: |
1114 | * |
1115 | * Enables or disables the hover selection mode of @tree_view. |
1116 | * Hover selection makes the selected row follow the pointer. |
1117 | * Currently, this works only for the selection modes |
1118 | * %CTK_SELECTION_SINGLE and %CTK_SELECTION_BROWSE. |
1119 | * |
1120 | * This mode is primarily intended for treeviews in popups, e.g. |
1121 | * in #CtkComboBox or #CtkEntryCompletion. |
1122 | * |
1123 | * Since: 2.6 |
1124 | */ |
1125 | tree_view_props[PROP_HOVER_SELECTION] = |
1126 | g_param_spec_boolean ("hover-selection", |
1127 | P_("Hover Selection")g_dgettext("ctk30" "-properties","Hover Selection"), |
1128 | P_("Whether the selection should follow the pointer")g_dgettext("ctk30" "-properties","Whether the selection should follow the pointer" ), |
1129 | FALSE(0), |
1130 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1131 | |
1132 | /** |
1133 | * CtkTreeView:hover-expand: |
1134 | * |
1135 | * Enables or disables the hover expansion mode of @tree_view. |
1136 | * Hover expansion makes rows expand or collapse if the pointer moves |
1137 | * over them. |
1138 | * |
1139 | * This mode is primarily intended for treeviews in popups, e.g. |
1140 | * in #CtkComboBox or #CtkEntryCompletion. |
1141 | * |
1142 | * Since: 2.6 |
1143 | */ |
1144 | tree_view_props[PROP_HOVER_EXPAND] = |
1145 | g_param_spec_boolean ("hover-expand", |
1146 | P_("Hover Expand")g_dgettext("ctk30" "-properties","Hover Expand"), |
1147 | P_("Whether rows should be expanded/collapsed when the pointer moves over them")g_dgettext("ctk30" "-properties","Whether rows should be expanded/collapsed when the pointer moves over them" ), |
1148 | FALSE(0), |
1149 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1150 | |
1151 | /** |
1152 | * CtkTreeView:show-expanders: |
1153 | * |
1154 | * %TRUE if the view has expanders. |
1155 | * |
1156 | * Since: 2.12 |
1157 | */ |
1158 | tree_view_props[PROP_SHOW_EXPANDERS] = |
1159 | g_param_spec_boolean ("show-expanders", |
1160 | P_("Show Expanders")g_dgettext("ctk30" "-properties","Show Expanders"), |
1161 | P_("View has expanders")g_dgettext("ctk30" "-properties","View has expanders"), |
1162 | TRUE(!(0)), |
1163 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1164 | |
1165 | /** |
1166 | * CtkTreeView:level-indentation: |
1167 | * |
1168 | * Extra indentation for each level. |
1169 | * |
1170 | * Since: 2.12 |
1171 | */ |
1172 | tree_view_props[PROP_LEVEL_INDENTATION] = |
1173 | g_param_spec_int ("level-indentation", |
1174 | P_("Level Indentation")g_dgettext("ctk30" "-properties","Level Indentation"), |
1175 | P_("Extra indentation for each level")g_dgettext("ctk30" "-properties","Extra indentation for each level" ), |
1176 | 0, G_MAXINT2147483647, |
1177 | 0, |
1178 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1179 | |
1180 | tree_view_props[PROP_RUBBER_BANDING] = |
1181 | g_param_spec_boolean ("rubber-banding", |
1182 | P_("Rubber Banding")g_dgettext("ctk30" "-properties","Rubber Banding"), |
1183 | P_("Whether to enable selection of multiple items by dragging the mouse pointer")g_dgettext("ctk30" "-properties","Whether to enable selection of multiple items by dragging the mouse pointer" ), |
1184 | FALSE(0), |
1185 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1186 | |
1187 | tree_view_props[PROP_ENABLE_GRID_LINES] = |
1188 | g_param_spec_enum ("enable-grid-lines", |
1189 | P_("Enable Grid Lines")g_dgettext("ctk30" "-properties","Enable Grid Lines"), |
1190 | P_("Whether grid lines should be drawn in the tree view")g_dgettext("ctk30" "-properties","Whether grid lines should be drawn in the tree view" ), |
1191 | CTK_TYPE_TREE_VIEW_GRID_LINES(ctk_tree_view_grid_lines_get_type ()), |
1192 | CTK_TREE_VIEW_GRID_LINES_NONE, |
1193 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1194 | |
1195 | tree_view_props[PROP_ENABLE_TREE_LINES] = |
1196 | g_param_spec_boolean ("enable-tree-lines", |
1197 | P_("Enable Tree Lines")g_dgettext("ctk30" "-properties","Enable Tree Lines"), |
1198 | P_("Whether tree lines should be drawn in the tree view")g_dgettext("ctk30" "-properties","Whether tree lines should be drawn in the tree view" ), |
1199 | FALSE(0), |
1200 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1201 | |
1202 | tree_view_props[PROP_TOOLTIP_COLUMN] = |
1203 | g_param_spec_int ("tooltip-column", |
1204 | P_("Tooltip Column")g_dgettext("ctk30" "-properties","Tooltip Column"), |
1205 | P_("The column in the model containing the tooltip texts for the rows")g_dgettext("ctk30" "-properties","The column in the model containing the tooltip texts for the rows" ), |
1206 | -1, G_MAXINT2147483647, |
1207 | -1, |
1208 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1209 | |
1210 | /** |
1211 | * CtkTreeView:activate-on-single-click: |
1212 | * |
1213 | * The activate-on-single-click property specifies whether the "row-activated" signal |
1214 | * will be emitted after a single click. |
1215 | * |
1216 | * Since: 3.8 |
1217 | */ |
1218 | tree_view_props[PROP_ACTIVATE_ON_SINGLE_CLICK] = |
1219 | g_param_spec_boolean ("activate-on-single-click", |
1220 | P_("Activate on Single Click")g_dgettext("ctk30" "-properties","Activate on Single Click"), |
1221 | P_("Activate row on a single click")g_dgettext("ctk30" "-properties","Activate row on a single click" ), |
1222 | FALSE(0), |
1223 | CTK_PARAM_READWRITEG_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB|G_PARAM_EXPLICIT_NOTIFY); |
1224 | |
1225 | g_object_class_install_properties (o_class, LAST_PROP, tree_view_props); |
1226 | |
1227 | /* Style properties */ |
1228 | #define _TREE_VIEW_EXPANDER_SIZE14 14 |
1229 | #define _TREE_VIEW_VERTICAL_SEPARATOR2 2 |
1230 | #define _TREE_VIEW_HORIZONTAL_SEPARATOR2 2 |
1231 | |
1232 | ctk_widget_class_install_style_property (widget_class, |
1233 | g_param_spec_int ("expander-size", |
1234 | P_("Expander Size")g_dgettext("ctk30" "-properties","Expander Size"), |
1235 | P_("Size of the expander arrow")g_dgettext("ctk30" "-properties","Size of the expander arrow" ), |
1236 | 0, |
1237 | G_MAXINT2147483647, |
1238 | _TREE_VIEW_EXPANDER_SIZE14, |
1239 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1240 | |
1241 | ctk_widget_class_install_style_property (widget_class, |
1242 | g_param_spec_int ("vertical-separator", |
1243 | P_("Vertical Separator Width")g_dgettext("ctk30" "-properties","Vertical Separator Width"), |
1244 | P_("Vertical space between cells. Must be an even number")g_dgettext("ctk30" "-properties","Vertical space between cells. Must be an even number" ), |
1245 | 0, |
1246 | G_MAXINT2147483647, |
1247 | _TREE_VIEW_VERTICAL_SEPARATOR2, |
1248 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1249 | |
1250 | ctk_widget_class_install_style_property (widget_class, |
1251 | g_param_spec_int ("horizontal-separator", |
1252 | P_("Horizontal Separator Width")g_dgettext("ctk30" "-properties","Horizontal Separator Width" ), |
1253 | P_("Horizontal space between cells. Must be an even number")g_dgettext("ctk30" "-properties","Horizontal space between cells. Must be an even number" ), |
1254 | 0, |
1255 | G_MAXINT2147483647, |
1256 | _TREE_VIEW_HORIZONTAL_SEPARATOR2, |
1257 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1258 | |
1259 | ctk_widget_class_install_style_property (widget_class, |
1260 | g_param_spec_boolean ("allow-rules", |
1261 | P_("Allow Rules")g_dgettext("ctk30" "-properties","Allow Rules"), |
1262 | P_("Allow drawing of alternating color rows")g_dgettext("ctk30" "-properties","Allow drawing of alternating color rows" ), |
1263 | TRUE(!(0)), |
1264 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1265 | |
1266 | ctk_widget_class_install_style_property (widget_class, |
1267 | g_param_spec_boolean ("indent-expanders", |
1268 | P_("Indent Expanders")g_dgettext("ctk30" "-properties","Indent Expanders"), |
1269 | P_("Make the expanders indented")g_dgettext("ctk30" "-properties","Make the expanders indented" ), |
1270 | TRUE(!(0)), |
1271 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1272 | G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push
clang diagnostic ignored "-Wdeprecated-declarations" |
1273 | ctk_widget_class_install_style_property (widget_class, |
1274 | g_param_spec_boxed ("even-row-color", |
1275 | P_("Even Row Color")g_dgettext("ctk30" "-properties","Even Row Color"), |
1276 | P_("Color to use for even rows")g_dgettext("ctk30" "-properties","Color to use for even rows" ), |
1277 | CDK_TYPE_COLOR(cdk_color_get_type ()), |
1278 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1279 | |
1280 | ctk_widget_class_install_style_property (widget_class, |
1281 | g_param_spec_boxed ("odd-row-color", |
1282 | P_("Odd Row Color")g_dgettext("ctk30" "-properties","Odd Row Color"), |
1283 | P_("Color to use for odd rows")g_dgettext("ctk30" "-properties","Color to use for odd rows"), |
1284 | CDK_TYPE_COLOR(cdk_color_get_type ()), |
1285 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1286 | G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop |
1287 | |
1288 | ctk_widget_class_install_style_property (widget_class, |
1289 | g_param_spec_int ("grid-line-width", |
1290 | P_("Grid line width")g_dgettext("ctk30" "-properties","Grid line width"), |
1291 | P_("Width, in pixels, of the tree view grid lines")g_dgettext("ctk30" "-properties","Width, in pixels, of the tree view grid lines" ), |
1292 | 0, G_MAXINT2147483647, 1, |
1293 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1294 | |
1295 | ctk_widget_class_install_style_property (widget_class, |
1296 | g_param_spec_int ("tree-line-width", |
1297 | P_("Tree line width")g_dgettext("ctk30" "-properties","Tree line width"), |
1298 | P_("Width, in pixels, of the tree view lines")g_dgettext("ctk30" "-properties","Width, in pixels, of the tree view lines" ), |
1299 | 0, G_MAXINT2147483647, 1, |
1300 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1301 | |
1302 | ctk_widget_class_install_style_property (widget_class, |
1303 | g_param_spec_string ("grid-line-pattern", |
1304 | P_("Grid line pattern")g_dgettext("ctk30" "-properties","Grid line pattern"), |
1305 | P_("Dash pattern used to draw the tree view grid lines")g_dgettext("ctk30" "-properties","Dash pattern used to draw the tree view grid lines" ), |
1306 | "\1\1", |
1307 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1308 | |
1309 | ctk_widget_class_install_style_property (widget_class, |
1310 | g_param_spec_string ("tree-line-pattern", |
1311 | P_("Tree line pattern")g_dgettext("ctk30" "-properties","Tree line pattern"), |
1312 | P_("Dash pattern used to draw the tree view lines")g_dgettext("ctk30" "-properties","Dash pattern used to draw the tree view lines" ), |
1313 | "\1\1", |
1314 | CTK_PARAM_READABLEG_PARAM_READABLE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); |
1315 | |
1316 | /* Signals */ |
1317 | /** |
1318 | * CtkTreeView::row-activated: |
1319 | * @tree_view: the object on which the signal is emitted |
1320 | * @path: the #CtkTreePath for the activated row |
1321 | * @column: the #CtkTreeViewColumn in which the activation occurred |
1322 | * |
1323 | * The "row-activated" signal is emitted when the method |
1324 | * ctk_tree_view_row_activated() is called, when the user double |
1325 | * clicks a treeview row with the "activate-on-single-click" |
1326 | * property set to %FALSE, or when the user single clicks a row when |
1327 | * the "activate-on-single-click" property set to %TRUE. It is also |
1328 | * emitted when a non-editable row is selected and one of the keys: |
1329 | * Space, Shift+Space, Return or Enter is pressed. |
1330 | * |
1331 | * For selection handling refer to the |
1332 | * [tree widget conceptual overview][TreeWidget] |
1333 | * as well as #CtkTreeSelection. |
1334 | */ |
1335 | tree_view_signals[ROW_ACTIVATED] = |
1336 | g_signal_new (I_("row-activated")g_intern_static_string ("row-activated"), |
1337 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1338 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1339 | G_STRUCT_OFFSET (CtkTreeViewClass, row_activated)((glong) __builtin_offsetof(CtkTreeViewClass, row_activated)), |
1340 | NULL((void*)0), NULL((void*)0), |
1341 | _ctk_marshal_VOID__BOXED_OBJECT, |
1342 | G_TYPE_NONE((GType) ((1) << (2))), 2, |
1343 | CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ()), |
1344 | CTK_TYPE_TREE_VIEW_COLUMN(ctk_tree_view_column_get_type ())); |
1345 | g_signal_set_va_marshaller (tree_view_signals[ROW_ACTIVATED], |
1346 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1347 | _ctk_marshal_VOID__BOXED_OBJECTv); |
1348 | |
1349 | /** |
1350 | * CtkTreeView::test-expand-row: |
1351 | * @tree_view: the object on which the signal is emitted |
1352 | * @iter: the tree iter of the row to expand |
1353 | * @path: a tree path that points to the row |
1354 | * |
1355 | * The given row is about to be expanded (show its children nodes). Use this |
1356 | * signal if you need to control the expandability of individual rows. |
1357 | * |
1358 | * Returns: %FALSE to allow expansion, %TRUE to reject |
1359 | */ |
1360 | tree_view_signals[TEST_EXPAND_ROW] = |
1361 | g_signal_new (I_("test-expand-row")g_intern_static_string ("test-expand-row"), |
1362 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1363 | G_SIGNAL_RUN_LAST, |
1364 | G_STRUCT_OFFSET (CtkTreeViewClass, test_expand_row)((glong) __builtin_offsetof(CtkTreeViewClass, test_expand_row )), |
1365 | _ctk_boolean_handled_accumulator, NULL((void*)0), |
1366 | _ctk_marshal_BOOLEAN__BOXED_BOXEDg_cclosure_marshal_BOOLEAN__BOXED_BOXED, |
1367 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 2, |
1368 | CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ()), |
1369 | CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ())); |
1370 | g_signal_set_va_marshaller (tree_view_signals[TEST_EXPAND_ROW], |
1371 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1372 | _ctk_marshal_BOOLEAN__BOXED_BOXEDvg_cclosure_marshal_BOOLEAN__BOXED_BOXEDv); |
1373 | |
1374 | /** |
1375 | * CtkTreeView::test-collapse-row: |
1376 | * @tree_view: the object on which the signal is emitted |
1377 | * @iter: the tree iter of the row to collapse |
1378 | * @path: a tree path that points to the row |
1379 | * |
1380 | * The given row is about to be collapsed (hide its children nodes). Use this |
1381 | * signal if you need to control the collapsibility of individual rows. |
1382 | * |
1383 | * Returns: %FALSE to allow collapsing, %TRUE to reject |
1384 | */ |
1385 | tree_view_signals[TEST_COLLAPSE_ROW] = |
1386 | g_signal_new (I_("test-collapse-row")g_intern_static_string ("test-collapse-row"), |
1387 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1388 | G_SIGNAL_RUN_LAST, |
1389 | G_STRUCT_OFFSET (CtkTreeViewClass, test_collapse_row)((glong) __builtin_offsetof(CtkTreeViewClass, test_collapse_row )), |
1390 | _ctk_boolean_handled_accumulator, NULL((void*)0), |
1391 | _ctk_marshal_BOOLEAN__BOXED_BOXEDg_cclosure_marshal_BOOLEAN__BOXED_BOXED, |
1392 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 2, |
1393 | CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ()), |
1394 | CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ())); |
1395 | g_signal_set_va_marshaller (tree_view_signals[TEST_COLLAPSE_ROW], |
1396 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1397 | _ctk_marshal_BOOLEAN__BOXED_BOXEDvg_cclosure_marshal_BOOLEAN__BOXED_BOXEDv); |
1398 | |
1399 | /** |
1400 | * CtkTreeView::row-expanded: |
1401 | * @tree_view: the object on which the signal is emitted |
1402 | * @iter: the tree iter of the expanded row |
1403 | * @path: a tree path that points to the row |
1404 | * |
1405 | * The given row has been expanded (child nodes are shown). |
1406 | */ |
1407 | tree_view_signals[ROW_EXPANDED] = |
1408 | g_signal_new (I_("row-expanded")g_intern_static_string ("row-expanded"), |
1409 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1410 | G_SIGNAL_RUN_LAST, |
1411 | G_STRUCT_OFFSET (CtkTreeViewClass, row_expanded)((glong) __builtin_offsetof(CtkTreeViewClass, row_expanded)), |
1412 | NULL((void*)0), NULL((void*)0), |
1413 | _ctk_marshal_VOID__BOXED_BOXED, |
1414 | G_TYPE_NONE((GType) ((1) << (2))), 2, |
1415 | CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ()), |
1416 | CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ())); |
1417 | g_signal_set_va_marshaller (tree_view_signals[ROW_EXPANDED], |
1418 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1419 | _ctk_marshal_VOID__BOXED_BOXEDv); |
1420 | |
1421 | /** |
1422 | * CtkTreeView::row-collapsed: |
1423 | * @tree_view: the object on which the signal is emitted |
1424 | * @iter: the tree iter of the collapsed row |
1425 | * @path: a tree path that points to the row |
1426 | * |
1427 | * The given row has been collapsed (child nodes are hidden). |
1428 | */ |
1429 | tree_view_signals[ROW_COLLAPSED] = |
1430 | g_signal_new (I_("row-collapsed")g_intern_static_string ("row-collapsed"), |
1431 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1432 | G_SIGNAL_RUN_LAST, |
1433 | G_STRUCT_OFFSET (CtkTreeViewClass, row_collapsed)((glong) __builtin_offsetof(CtkTreeViewClass, row_collapsed)), |
1434 | NULL((void*)0), NULL((void*)0), |
1435 | _ctk_marshal_VOID__BOXED_BOXED, |
1436 | G_TYPE_NONE((GType) ((1) << (2))), 2, |
1437 | CTK_TYPE_TREE_ITER(ctk_tree_iter_get_type ()), |
1438 | CTK_TYPE_TREE_PATH(ctk_tree_path_get_type ())); |
1439 | g_signal_set_va_marshaller (tree_view_signals[ROW_COLLAPSED], |
1440 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1441 | _ctk_marshal_VOID__BOXED_BOXEDv); |
1442 | |
1443 | /** |
1444 | * CtkTreeView::columns-changed: |
1445 | * @tree_view: the object on which the signal is emitted |
1446 | * |
1447 | * The number of columns of the treeview has changed. |
1448 | */ |
1449 | tree_view_signals[COLUMNS_CHANGED] = |
1450 | g_signal_new (I_("columns-changed")g_intern_static_string ("columns-changed"), |
1451 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1452 | G_SIGNAL_RUN_LAST, |
1453 | G_STRUCT_OFFSET (CtkTreeViewClass, columns_changed)((glong) __builtin_offsetof(CtkTreeViewClass, columns_changed )), |
1454 | NULL((void*)0), NULL((void*)0), |
1455 | NULL((void*)0), |
1456 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
1457 | |
1458 | /** |
1459 | * CtkTreeView::cursor-changed: |
1460 | * @tree_view: the object on which the signal is emitted |
1461 | * |
1462 | * The position of the cursor (focused cell) has changed. |
1463 | */ |
1464 | tree_view_signals[CURSOR_CHANGED] = |
1465 | g_signal_new (I_("cursor-changed")g_intern_static_string ("cursor-changed"), |
1466 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1467 | G_SIGNAL_RUN_LAST, |
1468 | G_STRUCT_OFFSET (CtkTreeViewClass, cursor_changed)((glong) __builtin_offsetof(CtkTreeViewClass, cursor_changed) ), |
1469 | NULL((void*)0), NULL((void*)0), |
1470 | NULL((void*)0), |
1471 | G_TYPE_NONE((GType) ((1) << (2))), 0); |
1472 | |
1473 | /** |
1474 | * CtkTreeView::move-cursor: |
1475 | * @tree_view: the object on which the signal is emitted. |
1476 | * @step: the granularity of the move, as a |
1477 | * #CtkMovementStep. %CTK_MOVEMENT_LOGICAL_POSITIONS, |
1478 | * %CTK_MOVEMENT_VISUAL_POSITIONS, %CTK_MOVEMENT_DISPLAY_LINES, |
1479 | * %CTK_MOVEMENT_PAGES and %CTK_MOVEMENT_BUFFER_ENDS are |
1480 | * supported. %CTK_MOVEMENT_LOGICAL_POSITIONS and |
1481 | * %CTK_MOVEMENT_VISUAL_POSITIONS are treated identically. |
1482 | * @direction: the direction to move: +1 to move forwards; |
1483 | * -1 to move backwards. The resulting movement is |
1484 | * undefined for all other values. |
1485 | * |
1486 | * The #CtkTreeView::move-cursor signal is a [keybinding |
1487 | * signal][CtkBindingSignal] which gets emitted when the user |
1488 | * presses one of the cursor keys. |
1489 | * |
1490 | * Applications should not connect to it, but may emit it with |
1491 | * g_signal_emit_by_name() if they need to control the cursor |
1492 | * programmatically. In contrast to ctk_tree_view_set_cursor() and |
1493 | * ctk_tree_view_set_cursor_on_cell() when moving horizontally |
1494 | * #CtkTreeView::move-cursor does not reset the current selection. |
1495 | * |
1496 | * Returns: %TRUE if @step is supported, %FALSE otherwise. |
1497 | */ |
1498 | tree_view_signals[MOVE_CURSOR] = |
1499 | g_signal_new (I_("move-cursor")g_intern_static_string ("move-cursor"), |
1500 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1501 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1502 | G_STRUCT_OFFSET (CtkTreeViewClass, move_cursor)((glong) __builtin_offsetof(CtkTreeViewClass, move_cursor)), |
1503 | NULL((void*)0), NULL((void*)0), |
1504 | _ctk_marshal_BOOLEAN__ENUM_INT, |
1505 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 2, |
1506 | CTK_TYPE_MOVEMENT_STEP(ctk_movement_step_get_type ()), |
1507 | G_TYPE_INT((GType) ((6) << (2)))); |
1508 | g_signal_set_va_marshaller (tree_view_signals[MOVE_CURSOR], |
1509 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1510 | _ctk_marshal_BOOLEAN__ENUM_INTv); |
1511 | |
1512 | tree_view_signals[SELECT_ALL] = |
1513 | g_signal_new (I_("select-all")g_intern_static_string ("select-all"), |
1514 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1515 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1516 | G_STRUCT_OFFSET (CtkTreeViewClass, select_all)((glong) __builtin_offsetof(CtkTreeViewClass, select_all)), |
1517 | NULL((void*)0), NULL((void*)0), |
1518 | _ctk_marshal_BOOLEAN__VOID, |
1519 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 0); |
1520 | g_signal_set_va_marshaller (tree_view_signals[SELECT_ALL], |
1521 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1522 | _ctk_marshal_BOOLEAN__VOIDv); |
1523 | |
1524 | tree_view_signals[UNSELECT_ALL] = |
1525 | g_signal_new (I_("unselect-all")g_intern_static_string ("unselect-all"), |
1526 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1527 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1528 | G_STRUCT_OFFSET (CtkTreeViewClass, unselect_all)((glong) __builtin_offsetof(CtkTreeViewClass, unselect_all)), |
1529 | NULL((void*)0), NULL((void*)0), |
1530 | _ctk_marshal_BOOLEAN__VOID, |
1531 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 0); |
1532 | g_signal_set_va_marshaller (tree_view_signals[UNSELECT_ALL], |
1533 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1534 | _ctk_marshal_BOOLEAN__VOIDv); |
1535 | |
1536 | tree_view_signals[SELECT_CURSOR_ROW] = |
1537 | g_signal_new (I_("select-cursor-row")g_intern_static_string ("select-cursor-row"), |
1538 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1539 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1540 | G_STRUCT_OFFSET (CtkTreeViewClass, select_cursor_row)((glong) __builtin_offsetof(CtkTreeViewClass, select_cursor_row )), |
1541 | NULL((void*)0), NULL((void*)0), |
1542 | _ctk_marshal_BOOLEAN__BOOLEAN, |
1543 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 1, |
1544 | G_TYPE_BOOLEAN((GType) ((5) << (2)))); |
1545 | g_signal_set_va_marshaller (tree_view_signals[SELECT_CURSOR_ROW], |
1546 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1547 | _ctk_marshal_BOOLEAN__BOOLEANv); |
1548 | |
1549 | tree_view_signals[TOGGLE_CURSOR_ROW] = |
1550 | g_signal_new (I_("toggle-cursor-row")g_intern_static_string ("toggle-cursor-row"), |
1551 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1552 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1553 | G_STRUCT_OFFSET (CtkTreeViewClass, toggle_cursor_row)((glong) __builtin_offsetof(CtkTreeViewClass, toggle_cursor_row )), |
1554 | NULL((void*)0), NULL((void*)0), |
1555 | _ctk_marshal_BOOLEAN__VOID, |
1556 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 0); |
1557 | g_signal_set_va_marshaller (tree_view_signals[TOGGLE_CURSOR_ROW], |
1558 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1559 | _ctk_marshal_BOOLEAN__VOIDv); |
1560 | |
1561 | tree_view_signals[EXPAND_COLLAPSE_CURSOR_ROW] = |
1562 | g_signal_new (I_("expand-collapse-cursor-row")g_intern_static_string ("expand-collapse-cursor-row"), |
1563 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1564 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1565 | G_STRUCT_OFFSET (CtkTreeViewClass, expand_collapse_cursor_row)((glong) __builtin_offsetof(CtkTreeViewClass, expand_collapse_cursor_row )), |
1566 | NULL((void*)0), NULL((void*)0), |
1567 | _ctk_marshal_BOOLEAN__BOOLEAN_BOOLEAN_BOOLEAN, |
1568 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 3, |
1569 | G_TYPE_BOOLEAN((GType) ((5) << (2))), |
1570 | G_TYPE_BOOLEAN((GType) ((5) << (2))), |
1571 | G_TYPE_BOOLEAN((GType) ((5) << (2)))); |
1572 | g_signal_set_va_marshaller (tree_view_signals[EXPAND_COLLAPSE_CURSOR_ROW], |
1573 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1574 | _ctk_marshal_BOOLEAN__BOOLEAN_BOOLEAN_BOOLEANv); |
1575 | |
1576 | tree_view_signals[SELECT_CURSOR_PARENT] = |
1577 | g_signal_new (I_("select-cursor-parent")g_intern_static_string ("select-cursor-parent"), |
1578 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1579 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1580 | G_STRUCT_OFFSET (CtkTreeViewClass, select_cursor_parent)((glong) __builtin_offsetof(CtkTreeViewClass, select_cursor_parent )), |
1581 | NULL((void*)0), NULL((void*)0), |
1582 | _ctk_marshal_BOOLEAN__VOID, |
1583 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 0); |
1584 | g_signal_set_va_marshaller (tree_view_signals[SELECT_CURSOR_PARENT], |
1585 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1586 | _ctk_marshal_BOOLEAN__VOIDv); |
1587 | |
1588 | tree_view_signals[START_INTERACTIVE_SEARCH] = |
1589 | g_signal_new (I_("start-interactive-search")g_intern_static_string ("start-interactive-search"), |
1590 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1591 | G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, |
1592 | G_STRUCT_OFFSET (CtkTreeViewClass, start_interactive_search)((glong) __builtin_offsetof(CtkTreeViewClass, start_interactive_search )), |
1593 | NULL((void*)0), NULL((void*)0), |
1594 | _ctk_marshal_BOOLEAN__VOID, |
1595 | G_TYPE_BOOLEAN((GType) ((5) << (2))), 0); |
1596 | g_signal_set_va_marshaller (tree_view_signals[START_INTERACTIVE_SEARCH], |
1597 | G_TYPE_FROM_CLASS (o_class)(((GTypeClass*) (o_class))->g_type), |
1598 | _ctk_marshal_BOOLEAN__VOIDv); |
1599 | |
1600 | /* Key bindings */ |
1601 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_Up0xff52, 0, TRUE(!(0)), |
1602 | CTK_MOVEMENT_DISPLAY_LINES, -1); |
1603 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_KP_Up0xff97, 0, TRUE(!(0)), |
1604 | CTK_MOVEMENT_DISPLAY_LINES, -1); |
1605 | |
1606 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_Down0xff54, 0, TRUE(!(0)), |
1607 | CTK_MOVEMENT_DISPLAY_LINES, 1); |
1608 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_KP_Down0xff99, 0, TRUE(!(0)), |
1609 | CTK_MOVEMENT_DISPLAY_LINES, 1); |
1610 | |
1611 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_p0x070, CDK_CONTROL_MASK, FALSE(0), |
1612 | CTK_MOVEMENT_DISPLAY_LINES, -1); |
1613 | |
1614 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_n0x06e, CDK_CONTROL_MASK, FALSE(0), |
1615 | CTK_MOVEMENT_DISPLAY_LINES, 1); |
1616 | |
1617 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_Home0xff50, 0, TRUE(!(0)), |
1618 | CTK_MOVEMENT_BUFFER_ENDS, -1); |
1619 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_KP_Home0xff95, 0, TRUE(!(0)), |
1620 | CTK_MOVEMENT_BUFFER_ENDS, -1); |
1621 | |
1622 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_End0xff57, 0, TRUE(!(0)), |
1623 | CTK_MOVEMENT_BUFFER_ENDS, 1); |
1624 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_KP_End0xff9c, 0, TRUE(!(0)), |
1625 | CTK_MOVEMENT_BUFFER_ENDS, 1); |
1626 | |
1627 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_Page_Up0xff55, 0, TRUE(!(0)), |
1628 | CTK_MOVEMENT_PAGES, -1); |
1629 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_KP_Page_Up0xff9a, 0, TRUE(!(0)), |
1630 | CTK_MOVEMENT_PAGES, -1); |
1631 | |
1632 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_Page_Down0xff56, 0, TRUE(!(0)), |
1633 | CTK_MOVEMENT_PAGES, 1); |
1634 | ctk_tree_view_add_move_binding (binding_set, CDK_KEY_KP_Page_Down0xff9b, 0, TRUE(!(0)), |
1635 | CTK_MOVEMENT_PAGES, 1); |
1636 | |
1637 | |
1638 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Right0xff53, 0, "move-cursor", 2, |
1639 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1640 | G_TYPE_INT((GType) ((6) << (2))), 1); |
1641 | |
1642 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Left0xff51, 0, "move-cursor", 2, |
1643 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1644 | G_TYPE_INT((GType) ((6) << (2))), -1); |
1645 | |
1646 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Right0xff98, 0, "move-cursor", 2, |
1647 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1648 | G_TYPE_INT((GType) ((6) << (2))), 1); |
1649 | |
1650 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Left0xff96, 0, "move-cursor", 2, |
1651 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1652 | G_TYPE_INT((GType) ((6) << (2))), -1); |
1653 | |
1654 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Right0xff53, CDK_CONTROL_MASK, |
1655 | "move-cursor", 2, |
1656 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1657 | G_TYPE_INT((GType) ((6) << (2))), 1); |
1658 | |
1659 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Left0xff51, CDK_CONTROL_MASK, |
1660 | "move-cursor", 2, |
1661 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1662 | G_TYPE_INT((GType) ((6) << (2))), -1); |
1663 | |
1664 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Right0xff98, CDK_CONTROL_MASK, |
1665 | "move-cursor", 2, |
1666 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1667 | G_TYPE_INT((GType) ((6) << (2))), 1); |
1668 | |
1669 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Left0xff96, CDK_CONTROL_MASK, |
1670 | "move-cursor", 2, |
1671 | G_TYPE_ENUM((GType) ((12) << (2))), CTK_MOVEMENT_VISUAL_POSITIONS, |
1672 | G_TYPE_INT((GType) ((6) << (2))), -1); |
1673 | |
1674 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_space0x020, CDK_CONTROL_MASK, "toggle-cursor-row", 0); |
1675 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Space0xff80, CDK_CONTROL_MASK, "toggle-cursor-row", 0); |
1676 | |
1677 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_a0x061, CDK_CONTROL_MASK, "select-all", 0); |
1678 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_slash0x02f, CDK_CONTROL_MASK, "select-all", 0); |
1679 | |
1680 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_A0x041, CDK_CONTROL_MASK | CDK_SHIFT_MASK, "unselect-all", 0); |
1681 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_backslash0x05c, CDK_CONTROL_MASK, "unselect-all", 0); |
1682 | |
1683 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_space0x020, CDK_SHIFT_MASK, "select-cursor-row", 1, |
1684 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1685 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Space0xff80, CDK_SHIFT_MASK, "select-cursor-row", 1, |
1686 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1687 | |
1688 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_space0x020, 0, "select-cursor-row", 1, |
1689 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1690 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Space0xff80, 0, "select-cursor-row", 1, |
1691 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1692 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Return0xff0d, 0, "select-cursor-row", 1, |
1693 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1694 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_ISO_Enter0xfe34, 0, "select-cursor-row", 1, |
1695 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1696 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Enter0xff8d, 0, "select-cursor-row", 1, |
1697 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1698 | |
1699 | /* expand and collapse rows */ |
1700 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_plus0x02b, 0, "expand-collapse-cursor-row", 3, |
1701 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1702 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1703 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0)); |
1704 | |
1705 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_asterisk0x02a, 0, |
1706 | "expand-collapse-cursor-row", 3, |
1707 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1708 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1709 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1710 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Multiply0xffaa, 0, |
1711 | "expand-collapse-cursor-row", 3, |
1712 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1713 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1714 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1715 | |
1716 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_slash0x02f, 0, |
1717 | "expand-collapse-cursor-row", 3, |
1718 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1719 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1720 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0)); |
1721 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Divide0xffaf, 0, |
1722 | "expand-collapse-cursor-row", 3, |
1723 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1724 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1725 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0)); |
1726 | |
1727 | /* Not doable on US keyboards */ |
1728 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_plus0x02b, CDK_SHIFT_MASK, "expand-collapse-cursor-row", 3, |
1729 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1730 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1731 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1732 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Add0xffab, 0, "expand-collapse-cursor-row", 3, |
1733 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1734 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1735 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0)); |
1736 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Add0xffab, CDK_SHIFT_MASK, "expand-collapse-cursor-row", 3, |
1737 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1738 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1739 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1740 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Add0xffab, CDK_SHIFT_MASK, "expand-collapse-cursor-row", 3, |
1741 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1742 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1743 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1744 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Right0xff53, CDK_SHIFT_MASK, |
1745 | "expand-collapse-cursor-row", 3, |
1746 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1747 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1748 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1749 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Right0xff98, CDK_SHIFT_MASK, |
1750 | "expand-collapse-cursor-row", 3, |
1751 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1752 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1753 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1754 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Right0xff53, |
1755 | CDK_CONTROL_MASK | CDK_SHIFT_MASK, |
1756 | "expand-collapse-cursor-row", 3, |
1757 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1758 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1759 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1760 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Right0xff98, |
1761 | CDK_CONTROL_MASK | CDK_SHIFT_MASK, |
1762 | "expand-collapse-cursor-row", 3, |
1763 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1764 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1765 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1766 | |
1767 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_minus0x02d, 0, "expand-collapse-cursor-row", 3, |
1768 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1769 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1770 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0)); |
1771 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_minus0x02d, CDK_SHIFT_MASK, "expand-collapse-cursor-row", 3, |
1772 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1773 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1774 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1775 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Subtract0xffad, 0, "expand-collapse-cursor-row", 3, |
1776 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1777 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1778 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0)); |
1779 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Subtract0xffad, CDK_SHIFT_MASK, "expand-collapse-cursor-row", 3, |
1780 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0)), |
1781 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1782 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1783 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Left0xff51, CDK_SHIFT_MASK, |
1784 | "expand-collapse-cursor-row", 3, |
1785 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1786 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1787 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1788 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Left0xff96, CDK_SHIFT_MASK, |
1789 | "expand-collapse-cursor-row", 3, |
1790 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1791 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1792 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1793 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_Left0xff51, |
1794 | CDK_CONTROL_MASK | CDK_SHIFT_MASK, |
1795 | "expand-collapse-cursor-row", 3, |
1796 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1797 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1798 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1799 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_KP_Left0xff96, |
1800 | CDK_CONTROL_MASK | CDK_SHIFT_MASK, |
1801 | "expand-collapse-cursor-row", 3, |
1802 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1803 | G_TYPE_BOOLEAN((GType) ((5) << (2))), FALSE(0), |
1804 | G_TYPE_BOOLEAN((GType) ((5) << (2))), TRUE(!(0))); |
1805 | |
1806 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_BackSpace0xff08, 0, "select-cursor-parent", 0); |
1807 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_BackSpace0xff08, CDK_CONTROL_MASK, "select-cursor-parent", 0); |
1808 | |
1809 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_f0x066, CDK_CONTROL_MASK, "start-interactive-search", 0); |
1810 | |
1811 | ctk_binding_entry_add_signal (binding_set, CDK_KEY_F0x046, CDK_CONTROL_MASK, "start-interactive-search", 0); |
1812 | |
1813 | ctk_widget_class_set_accessible_type (widget_class, CTK_TYPE_TREE_VIEW_ACCESSIBLE(ctk_tree_view_accessible_get_type ())); |
1814 | ctk_widget_class_set_css_name (widget_class, "treeview"); |
1815 | } |
1816 | |
1817 | static void |
1818 | ctk_tree_view_init (CtkTreeView *tree_view) |
1819 | { |
1820 | CtkTreeViewPrivate *priv; |
1821 | CtkCssNode *widget_node; |
1822 | |
1823 | priv = tree_view->priv = ctk_tree_view_get_instance_private (tree_view); |
1824 | |
1825 | ctk_widget_set_can_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), TRUE(!(0))); |
1826 | |
1827 | priv->show_expanders = TRUE(!(0)); |
1828 | priv->draw_keyfocus = TRUE(!(0)); |
1829 | priv->headers_visible = TRUE(!(0)); |
1830 | priv->activate_on_single_click = FALSE(0); |
1831 | |
1832 | priv->pixel_cache = _ctk_pixel_cache_new (); |
1833 | |
1834 | /* We need some padding */ |
1835 | priv->dy = 0; |
1836 | priv->cursor_offset = 0; |
1837 | priv->n_columns = 0; |
1838 | priv->header_height = 1; |
1839 | priv->x_drag = 0; |
1840 | priv->drag_pos = -1; |
1841 | priv->header_has_focus = FALSE(0); |
1842 | priv->press_start_x = -1; |
1843 | priv->press_start_y = -1; |
1844 | priv->reorderable = FALSE(0); |
1845 | priv->presize_handler_tick_cb = 0; |
1846 | priv->scroll_sync_timer = 0; |
1847 | priv->fixed_height = -1; |
1848 | priv->fixed_height_mode = FALSE(0); |
1849 | priv->fixed_height_check = 0; |
1850 | priv->selection = _ctk_tree_selection_new_with_tree_view (tree_view); |
1851 | priv->enable_search = TRUE(!(0)); |
1852 | priv->search_column = -1; |
1853 | priv->search_position_func = ctk_tree_view_search_position_func; |
1854 | priv->search_equal_func = ctk_tree_view_search_equal_func; |
1855 | priv->search_custom_entry_set = FALSE(0); |
1856 | priv->typeselect_flush_timeout = 0; |
1857 | priv->init_hadjust_value = TRUE(!(0)); |
1858 | priv->width = 0; |
1859 | |
1860 | priv->hover_selection = FALSE(0); |
1861 | priv->hover_expand = FALSE(0); |
1862 | |
1863 | priv->level_indentation = 0; |
1864 | |
1865 | priv->rubber_banding_enable = FALSE(0); |
1866 | |
1867 | priv->grid_lines = CTK_TREE_VIEW_GRID_LINES_NONE; |
1868 | priv->tree_lines_enabled = FALSE(0); |
1869 | |
1870 | priv->tooltip_column = -1; |
1871 | |
1872 | priv->post_validation_flag = FALSE(0); |
1873 | |
1874 | priv->event_last_x = -10000; |
1875 | priv->event_last_y = -10000; |
1876 | |
1877 | ctk_tree_view_do_set_vadjustment (tree_view, NULL((void*)0)); |
1878 | ctk_tree_view_do_set_hadjustment (tree_view, NULL((void*)0)); |
1879 | |
1880 | ctk_style_context_add_class (ctk_widget_get_style_context (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))), |
1881 | CTK_STYLE_CLASS_VIEW"view"); |
1882 | |
1883 | widget_node = ctk_widget_get_css_node (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1884 | priv->header_node = ctk_css_node_new (); |
1885 | ctk_css_node_set_name (priv->header_node, I_("header")g_intern_static_string ("header")); |
1886 | ctk_css_node_set_parent (priv->header_node, widget_node); |
1887 | ctk_css_node_set_state (priv->header_node, ctk_css_node_get_state (widget_node)); |
1888 | g_object_unref (priv->header_node); |
1889 | |
1890 | priv->multipress_gesture = ctk_gesture_multi_press_new (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1891 | ctk_gesture_single_set_button (CTK_GESTURE_SINGLE (priv->multipress_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((priv->multipress_gesture)), ((ctk_gesture_single_get_type ())))))), 0); |
1892 | g_signal_connect (priv->multipress_gesture, "pressed",g_signal_connect_data ((priv->multipress_gesture), ("pressed" ), (((GCallback) (ctk_tree_view_multipress_gesture_pressed))) , (tree_view), ((void*)0), (GConnectFlags) 0) |
1893 | G_CALLBACK (ctk_tree_view_multipress_gesture_pressed), tree_view)g_signal_connect_data ((priv->multipress_gesture), ("pressed" ), (((GCallback) (ctk_tree_view_multipress_gesture_pressed))) , (tree_view), ((void*)0), (GConnectFlags) 0); |
1894 | g_signal_connect (priv->multipress_gesture, "released",g_signal_connect_data ((priv->multipress_gesture), ("released" ), (((GCallback) (ctk_tree_view_multipress_gesture_released)) ), (tree_view), ((void*)0), (GConnectFlags) 0) |
1895 | G_CALLBACK (ctk_tree_view_multipress_gesture_released), tree_view)g_signal_connect_data ((priv->multipress_gesture), ("released" ), (((GCallback) (ctk_tree_view_multipress_gesture_released)) ), (tree_view), ((void*)0), (GConnectFlags) 0); |
1896 | |
1897 | priv->column_multipress_gesture = ctk_gesture_multi_press_new (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1898 | g_signal_connect (priv->column_multipress_gesture, "pressed",g_signal_connect_data ((priv->column_multipress_gesture), ( "pressed"), (((GCallback) (ctk_tree_view_column_multipress_gesture_pressed ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
1899 | G_CALLBACK (ctk_tree_view_column_multipress_gesture_pressed), tree_view)g_signal_connect_data ((priv->column_multipress_gesture), ( "pressed"), (((GCallback) (ctk_tree_view_column_multipress_gesture_pressed ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
1900 | ctk_event_controller_set_propagation_phase (CTK_EVENT_CONTROLLER (priv->column_multipress_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((priv->column_multipress_gesture)), ((ctk_event_controller_get_type ())))))), |
1901 | CTK_PHASE_CAPTURE); |
1902 | |
1903 | priv->drag_gesture = ctk_gesture_drag_new (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1904 | g_signal_connect (priv->drag_gesture, "drag-begin",g_signal_connect_data ((priv->drag_gesture), ("drag-begin" ), (((GCallback) (ctk_tree_view_drag_gesture_begin))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
1905 | G_CALLBACK (ctk_tree_view_drag_gesture_begin), tree_view)g_signal_connect_data ((priv->drag_gesture), ("drag-begin" ), (((GCallback) (ctk_tree_view_drag_gesture_begin))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
1906 | g_signal_connect (priv->drag_gesture, "drag-update",g_signal_connect_data ((priv->drag_gesture), ("drag-update" ), (((GCallback) (ctk_tree_view_drag_gesture_update))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
1907 | G_CALLBACK (ctk_tree_view_drag_gesture_update), tree_view)g_signal_connect_data ((priv->drag_gesture), ("drag-update" ), (((GCallback) (ctk_tree_view_drag_gesture_update))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
1908 | g_signal_connect (priv->drag_gesture, "drag-end",g_signal_connect_data ((priv->drag_gesture), ("drag-end"), (((GCallback) (ctk_tree_view_drag_gesture_end))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
1909 | G_CALLBACK (ctk_tree_view_drag_gesture_end), tree_view)g_signal_connect_data ((priv->drag_gesture), ("drag-end"), (((GCallback) (ctk_tree_view_drag_gesture_end))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
1910 | |
1911 | priv->column_drag_gesture = ctk_gesture_drag_new (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1912 | g_signal_connect (priv->column_drag_gesture, "drag-begin",g_signal_connect_data ((priv->column_drag_gesture), ("drag-begin" ), (((GCallback) (ctk_tree_view_column_drag_gesture_begin))), (tree_view), ((void*)0), (GConnectFlags) 0) |
1913 | G_CALLBACK (ctk_tree_view_column_drag_gesture_begin), tree_view)g_signal_connect_data ((priv->column_drag_gesture), ("drag-begin" ), (((GCallback) (ctk_tree_view_column_drag_gesture_begin))), (tree_view), ((void*)0), (GConnectFlags) 0); |
1914 | g_signal_connect (priv->column_drag_gesture, "drag-update",g_signal_connect_data ((priv->column_drag_gesture), ("drag-update" ), (((GCallback) (ctk_tree_view_column_drag_gesture_update))) , (tree_view), ((void*)0), (GConnectFlags) 0) |
1915 | G_CALLBACK (ctk_tree_view_column_drag_gesture_update), tree_view)g_signal_connect_data ((priv->column_drag_gesture), ("drag-update" ), (((GCallback) (ctk_tree_view_column_drag_gesture_update))) , (tree_view), ((void*)0), (GConnectFlags) 0); |
1916 | g_signal_connect (priv->column_drag_gesture, "drag-end",g_signal_connect_data ((priv->column_drag_gesture), ("drag-end" ), (((GCallback) (ctk_tree_view_column_drag_gesture_end))), ( tree_view), ((void*)0), (GConnectFlags) 0) |
1917 | G_CALLBACK (ctk_tree_view_column_drag_gesture_end), tree_view)g_signal_connect_data ((priv->column_drag_gesture), ("drag-end" ), (((GCallback) (ctk_tree_view_column_drag_gesture_end))), ( tree_view), ((void*)0), (GConnectFlags) 0); |
1918 | ctk_event_controller_set_propagation_phase (CTK_EVENT_CONTROLLER (priv->column_drag_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((priv->column_drag_gesture)), ((ctk_event_controller_get_type ())))))), |
1919 | CTK_PHASE_CAPTURE); |
1920 | } |
1921 | |
1922 | |
1923 | |
1924 | /* GObject Methods |
1925 | */ |
1926 | |
1927 | static void |
1928 | ctk_tree_view_set_property (GObject *object, |
1929 | guint prop_id, |
1930 | const GValue *value, |
1931 | GParamSpec *pspec) |
1932 | { |
1933 | CtkTreeView *tree_view; |
1934 | |
1935 | tree_view = CTK_TREE_VIEW (object)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_tree_view_get_type ())))))); |
1936 | |
1937 | switch (prop_id) |
1938 | { |
1939 | case PROP_MODEL: |
1940 | ctk_tree_view_set_model (tree_view, g_value_get_object (value)); |
1941 | break; |
1942 | case PROP_HADJUSTMENT: |
1943 | ctk_tree_view_do_set_hadjustment (tree_view, g_value_get_object (value)); |
1944 | break; |
1945 | case PROP_VADJUSTMENT: |
1946 | ctk_tree_view_do_set_vadjustment (tree_view, g_value_get_object (value)); |
1947 | break; |
1948 | case PROP_HSCROLL_POLICY: |
1949 | if (tree_view->priv->hscroll_policy != g_value_get_enum (value)) |
1950 | { |
1951 | tree_view->priv->hscroll_policy = g_value_get_enum (value); |
1952 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1953 | g_object_notify_by_pspec (object, pspec); |
1954 | } |
1955 | break; |
1956 | case PROP_VSCROLL_POLICY: |
1957 | if (tree_view->priv->vscroll_policy != g_value_get_enum (value)) |
1958 | { |
1959 | tree_view->priv->vscroll_policy = g_value_get_enum (value); |
1960 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
1961 | g_object_notify_by_pspec (object, pspec); |
1962 | } |
1963 | break; |
1964 | case PROP_HEADERS_VISIBLE: |
1965 | ctk_tree_view_set_headers_visible (tree_view, g_value_get_boolean (value)); |
1966 | break; |
1967 | case PROP_HEADERS_CLICKABLE: |
1968 | ctk_tree_view_set_headers_clickable (tree_view, g_value_get_boolean (value)); |
1969 | break; |
1970 | case PROP_EXPANDER_COLUMN: |
1971 | ctk_tree_view_set_expander_column (tree_view, g_value_get_object (value)); |
1972 | break; |
1973 | case PROP_REORDERABLE: |
1974 | ctk_tree_view_set_reorderable (tree_view, g_value_get_boolean (value)); |
1975 | break; |
1976 | case PROP_RULES_HINT: |
1977 | G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push
clang diagnostic ignored "-Wdeprecated-declarations" |
1978 | ctk_tree_view_set_rules_hint (tree_view, g_value_get_boolean (value)); |
1979 | G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop |
1980 | break; |
1981 | case PROP_ENABLE_SEARCH: |
1982 | ctk_tree_view_set_enable_search (tree_view, g_value_get_boolean (value)); |
1983 | break; |
1984 | case PROP_SEARCH_COLUMN: |
1985 | ctk_tree_view_set_search_column (tree_view, g_value_get_int (value)); |
1986 | break; |
1987 | case PROP_FIXED_HEIGHT_MODE: |
1988 | ctk_tree_view_set_fixed_height_mode (tree_view, g_value_get_boolean (value)); |
1989 | break; |
1990 | case PROP_HOVER_SELECTION: |
1991 | if (tree_view->priv->hover_selection != g_value_get_boolean (value)) |
1992 | { |
1993 | tree_view->priv->hover_selection = g_value_get_boolean (value); |
1994 | g_object_notify_by_pspec (object, pspec); |
1995 | } |
1996 | break; |
1997 | case PROP_HOVER_EXPAND: |
1998 | if (tree_view->priv->hover_expand != g_value_get_boolean (value)) |
1999 | { |
2000 | tree_view->priv->hover_expand = g_value_get_boolean (value); |
2001 | g_object_notify_by_pspec (object, pspec); |
2002 | } |
2003 | break; |
2004 | case PROP_SHOW_EXPANDERS: |
2005 | ctk_tree_view_set_show_expanders (tree_view, g_value_get_boolean (value)); |
2006 | break; |
2007 | case PROP_LEVEL_INDENTATION: |
2008 | if (tree_view->priv->level_indentation != g_value_get_int (value)) |
2009 | { |
2010 | tree_view->priv->level_indentation = g_value_get_int (value); |
2011 | g_object_notify_by_pspec (object, pspec); |
2012 | } |
2013 | break; |
2014 | case PROP_RUBBER_BANDING: |
2015 | if (tree_view->priv->rubber_banding_enable != g_value_get_boolean (value)) |
2016 | { |
2017 | tree_view->priv->rubber_banding_enable = g_value_get_boolean (value); |
2018 | g_object_notify_by_pspec (object, pspec); |
2019 | } |
2020 | break; |
2021 | case PROP_ENABLE_GRID_LINES: |
2022 | ctk_tree_view_set_grid_lines (tree_view, g_value_get_enum (value)); |
2023 | break; |
2024 | case PROP_ENABLE_TREE_LINES: |
2025 | ctk_tree_view_set_enable_tree_lines (tree_view, g_value_get_boolean (value)); |
2026 | break; |
2027 | case PROP_TOOLTIP_COLUMN: |
2028 | ctk_tree_view_set_tooltip_column (tree_view, g_value_get_int (value)); |
2029 | break; |
2030 | case PROP_ACTIVATE_ON_SINGLE_CLICK: |
2031 | ctk_tree_view_set_activate_on_single_click (tree_view, g_value_get_boolean (value)); |
2032 | break; |
2033 | default: |
2034 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctktreeview.c", 2034, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
2035 | break; |
2036 | } |
2037 | } |
2038 | |
2039 | static void |
2040 | ctk_tree_view_get_property (GObject *object, |
2041 | guint prop_id, |
2042 | GValue *value, |
2043 | GParamSpec *pspec) |
2044 | { |
2045 | CtkTreeView *tree_view; |
2046 | |
2047 | tree_view = CTK_TREE_VIEW (object)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((object)), ((ctk_tree_view_get_type ())))))); |
2048 | |
2049 | switch (prop_id) |
2050 | { |
2051 | case PROP_MODEL: |
2052 | g_value_set_object (value, tree_view->priv->model); |
2053 | break; |
2054 | case PROP_HADJUSTMENT: |
2055 | g_value_set_object (value, tree_view->priv->hadjustment); |
2056 | break; |
2057 | case PROP_VADJUSTMENT: |
2058 | g_value_set_object (value, tree_view->priv->vadjustment); |
2059 | break; |
2060 | case PROP_HSCROLL_POLICY: |
2061 | g_value_set_enum (value, tree_view->priv->hscroll_policy); |
2062 | break; |
2063 | case PROP_VSCROLL_POLICY: |
2064 | g_value_set_enum (value, tree_view->priv->vscroll_policy); |
2065 | break; |
2066 | case PROP_HEADERS_VISIBLE: |
2067 | g_value_set_boolean (value, ctk_tree_view_get_headers_visible (tree_view)); |
2068 | break; |
2069 | case PROP_HEADERS_CLICKABLE: |
2070 | g_value_set_boolean (value, ctk_tree_view_get_headers_clickable (tree_view)); |
2071 | break; |
2072 | case PROP_EXPANDER_COLUMN: |
2073 | g_value_set_object (value, tree_view->priv->expander_column); |
2074 | break; |
2075 | case PROP_REORDERABLE: |
2076 | g_value_set_boolean (value, tree_view->priv->reorderable); |
2077 | break; |
2078 | case PROP_RULES_HINT: |
2079 | g_value_set_boolean (value, tree_view->priv->has_rules); |
2080 | break; |
2081 | case PROP_ENABLE_SEARCH: |
2082 | g_value_set_boolean (value, tree_view->priv->enable_search); |
2083 | break; |
2084 | case PROP_SEARCH_COLUMN: |
2085 | g_value_set_int (value, tree_view->priv->search_column); |
2086 | break; |
2087 | case PROP_FIXED_HEIGHT_MODE: |
2088 | g_value_set_boolean (value, tree_view->priv->fixed_height_mode); |
2089 | break; |
2090 | case PROP_HOVER_SELECTION: |
2091 | g_value_set_boolean (value, tree_view->priv->hover_selection); |
2092 | break; |
2093 | case PROP_HOVER_EXPAND: |
2094 | g_value_set_boolean (value, tree_view->priv->hover_expand); |
2095 | break; |
2096 | case PROP_SHOW_EXPANDERS: |
2097 | g_value_set_boolean (value, tree_view->priv->show_expanders); |
2098 | break; |
2099 | case PROP_LEVEL_INDENTATION: |
2100 | g_value_set_int (value, tree_view->priv->level_indentation); |
2101 | break; |
2102 | case PROP_RUBBER_BANDING: |
2103 | g_value_set_boolean (value, tree_view->priv->rubber_banding_enable); |
2104 | break; |
2105 | case PROP_ENABLE_GRID_LINES: |
2106 | g_value_set_enum (value, tree_view->priv->grid_lines); |
2107 | break; |
2108 | case PROP_ENABLE_TREE_LINES: |
2109 | g_value_set_boolean (value, tree_view->priv->tree_lines_enabled); |
2110 | break; |
2111 | case PROP_TOOLTIP_COLUMN: |
2112 | g_value_set_int (value, tree_view->priv->tooltip_column); |
2113 | break; |
2114 | case PROP_ACTIVATE_ON_SINGLE_CLICK: |
2115 | g_value_set_boolean (value, tree_view->priv->activate_on_single_click); |
2116 | break; |
2117 | default: |
2118 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec)do { GObject *_glib__object = (GObject*) ((object)); GParamSpec *_glib__pspec = (GParamSpec*) ((pspec)); guint _glib__property_id = ((prop_id)); g_warning ("%s:%d: invalid %s id %u for \"%s\" of type '%s' in '%s'" , "ctktreeview.c", 2118, ("property"), _glib__property_id, _glib__pspec ->name, g_type_name ((((((GTypeClass*) (((GTypeInstance*) ( _glib__pspec))->g_class))->g_type)))), (g_type_name ((( (((GTypeClass*) (((GTypeInstance*) (_glib__object))->g_class ))->g_type)))))); } while (0); |
2119 | break; |
2120 | } |
2121 | } |
2122 | |
2123 | static void |
2124 | ctk_tree_view_finalize (GObject *object) |
2125 | { |
2126 | G_OBJECT_CLASS (ctk_tree_view_parent_class)((((GObjectClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), (((GType) ((20) << ( 2))))))))->finalize (object); |
2127 | } |
2128 | |
2129 | |
2130 | static CtkBuildableIface *parent_buildable_iface; |
2131 | |
2132 | static void |
2133 | ctk_tree_view_buildable_init (CtkBuildableIface *iface) |
2134 | { |
2135 | parent_buildable_iface = g_type_interface_peek_parent (iface); |
2136 | iface->add_child = ctk_tree_view_buildable_add_child; |
2137 | iface->get_internal_child = ctk_tree_view_buildable_get_internal_child; |
2138 | } |
2139 | |
2140 | static void |
2141 | ctk_tree_view_buildable_add_child (CtkBuildable *tree_view, |
2142 | CtkBuilder *builder G_GNUC_UNUSED__attribute__ ((__unused__)), |
2143 | GObject *child, |
2144 | const gchar *type G_GNUC_UNUSED__attribute__ ((__unused__))) |
2145 | { |
2146 | ctk_tree_view_append_column (CTK_TREE_VIEW (tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_tree_view_get_type ())))))), CTK_TREE_VIEW_COLUMN (child)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((child)), ((ctk_tree_view_column_get_type ( )))))))); |
2147 | } |
2148 | |
2149 | static GObject * |
2150 | ctk_tree_view_buildable_get_internal_child (CtkBuildable *buildable, |
2151 | CtkBuilder *builder, |
2152 | const gchar *childname) |
2153 | { |
2154 | if (strcmp (childname, "selection") == 0) |
2155 | return G_OBJECT (CTK_TREE_VIEW (buildable)->priv->selection)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((((((CtkTreeView*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((buildable)), ((ctk_tree_view_get_type ()))) )))->priv->selection)), (((GType) ((20) << (2)))) )))); |
2156 | |
2157 | return parent_buildable_iface->get_internal_child (buildable, |
2158 | builder, |
2159 | childname); |
2160 | } |
2161 | |
2162 | /* CtkWidget Methods |
2163 | */ |
2164 | |
2165 | static void |
2166 | ctk_tree_view_free_rbtree (CtkTreeView *tree_view) |
2167 | { |
2168 | _ctk_rbtree_free (tree_view->priv->tree); |
2169 | |
2170 | tree_view->priv->tree = NULL((void*)0); |
2171 | tree_view->priv->button_pressed_node = NULL((void*)0); |
2172 | tree_view->priv->button_pressed_tree = NULL((void*)0); |
2173 | tree_view->priv->prelight_tree = NULL((void*)0); |
2174 | tree_view->priv->prelight_node = NULL((void*)0); |
2175 | } |
2176 | |
2177 | static void |
2178 | ctk_tree_view_destroy_search_window (CtkTreeView *tree_view) |
2179 | { |
2180 | ctk_widget_destroy (tree_view->priv->search_window); |
2181 | |
2182 | tree_view->priv->search_window = NULL((void*)0); |
2183 | tree_view->priv->search_entry = NULL((void*)0); |
2184 | tree_view->priv->search_entry_changed_id = 0; |
2185 | } |
2186 | |
2187 | static void |
2188 | ctk_tree_view_destroy (CtkWidget *widget) |
2189 | { |
2190 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2191 | GList *list; |
2192 | |
2193 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
2194 | ctk_tree_view_stop_rubber_band (tree_view); |
2195 | |
2196 | if (tree_view->priv->columns != NULL((void*)0)) |
2197 | { |
2198 | list = tree_view->priv->columns; |
2199 | while (list) |
2200 | { |
2201 | CtkTreeViewColumn *column; |
2202 | column = CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))); |
2203 | list = list->next; |
2204 | ctk_tree_view_remove_column (tree_view, column); |
2205 | } |
2206 | tree_view->priv->columns = NULL((void*)0); |
2207 | } |
2208 | |
2209 | if (tree_view->priv->tree != NULL((void*)0)) |
2210 | { |
2211 | ctk_tree_view_unref_and_check_selection_tree (tree_view, tree_view->priv->tree); |
2212 | |
2213 | ctk_tree_view_free_rbtree (tree_view); |
2214 | } |
2215 | |
2216 | if (tree_view->priv->selection != NULL((void*)0)) |
2217 | { |
2218 | _ctk_tree_selection_set_tree_view (tree_view->priv->selection, NULL((void*)0)); |
2219 | g_object_unref (tree_view->priv->selection); |
2220 | tree_view->priv->selection = NULL((void*)0); |
2221 | } |
2222 | |
2223 | if (tree_view->priv->scroll_to_path != NULL((void*)0)) |
2224 | { |
2225 | ctk_tree_row_reference_free (tree_view->priv->scroll_to_path); |
2226 | tree_view->priv->scroll_to_path = NULL((void*)0); |
2227 | } |
2228 | |
2229 | if (tree_view->priv->drag_dest_row != NULL((void*)0)) |
2230 | { |
2231 | ctk_tree_row_reference_free (tree_view->priv->drag_dest_row); |
2232 | tree_view->priv->drag_dest_row = NULL((void*)0); |
2233 | } |
2234 | |
2235 | if (tree_view->priv->top_row != NULL((void*)0)) |
2236 | { |
2237 | ctk_tree_row_reference_free (tree_view->priv->top_row); |
2238 | tree_view->priv->top_row = NULL((void*)0); |
2239 | } |
2240 | |
2241 | if (tree_view->priv->column_drop_func_data && |
2242 | tree_view->priv->column_drop_func_data_destroy) |
2243 | { |
2244 | tree_view->priv->column_drop_func_data_destroy (tree_view->priv->column_drop_func_data); |
2245 | tree_view->priv->column_drop_func_data = NULL((void*)0); |
2246 | } |
2247 | |
2248 | if (tree_view->priv->destroy_count_destroy && |
2249 | tree_view->priv->destroy_count_data) |
2250 | { |
2251 | tree_view->priv->destroy_count_destroy (tree_view->priv->destroy_count_data); |
2252 | tree_view->priv->destroy_count_data = NULL((void*)0); |
2253 | } |
2254 | |
2255 | ctk_tree_row_reference_free (tree_view->priv->anchor); |
2256 | tree_view->priv->anchor = NULL((void*)0); |
2257 | |
2258 | /* destroy interactive search dialog */ |
2259 | if (tree_view->priv->search_window) |
2260 | { |
2261 | ctk_tree_view_destroy_search_window (tree_view); |
2262 | if (tree_view->priv->typeselect_flush_timeout) |
2263 | { |
2264 | g_source_remove (tree_view->priv->typeselect_flush_timeout); |
2265 | tree_view->priv->typeselect_flush_timeout = 0; |
2266 | } |
2267 | } |
2268 | |
2269 | if (tree_view->priv->search_custom_entry_set) |
2270 | { |
2271 | g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry,g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_init ))), (tree_view)) |
2272 | G_CALLBACK (ctk_tree_view_search_init),g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_init ))), (tree_view)) |
2273 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_init ))), (tree_view)); |
2274 | g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry,g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view)) |
2275 | G_CALLBACK (ctk_tree_view_search_key_press_event),g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view)) |
2276 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view)); |
2277 | |
2278 | g_object_unref (tree_view->priv->search_entry); |
2279 | |
2280 | tree_view->priv->search_entry = NULL((void*)0); |
2281 | tree_view->priv->search_custom_entry_set = FALSE(0); |
2282 | } |
2283 | |
2284 | if (tree_view->priv->search_destroy && tree_view->priv->search_user_data) |
2285 | { |
2286 | tree_view->priv->search_destroy (tree_view->priv->search_user_data); |
2287 | tree_view->priv->search_user_data = NULL((void*)0); |
2288 | } |
2289 | |
2290 | if (tree_view->priv->search_position_destroy && tree_view->priv->search_position_user_data) |
2291 | { |
2292 | tree_view->priv->search_position_destroy (tree_view->priv->search_position_user_data); |
2293 | tree_view->priv->search_position_user_data = NULL((void*)0); |
2294 | } |
2295 | |
2296 | if (tree_view->priv->row_separator_destroy && tree_view->priv->row_separator_data) |
2297 | { |
2298 | tree_view->priv->row_separator_destroy (tree_view->priv->row_separator_data); |
2299 | tree_view->priv->row_separator_data = NULL((void*)0); |
2300 | } |
2301 | |
2302 | ctk_tree_view_set_model (tree_view, NULL((void*)0)); |
2303 | |
2304 | if (tree_view->priv->hadjustment) |
2305 | { |
2306 | g_object_unref (tree_view->priv->hadjustment); |
2307 | tree_view->priv->hadjustment = NULL((void*)0); |
2308 | } |
2309 | if (tree_view->priv->vadjustment) |
2310 | { |
2311 | g_object_unref (tree_view->priv->vadjustment); |
2312 | tree_view->priv->vadjustment = NULL((void*)0); |
2313 | } |
2314 | |
2315 | if (tree_view->priv->pixel_cache) |
2316 | _ctk_pixel_cache_free (tree_view->priv->pixel_cache); |
2317 | tree_view->priv->pixel_cache = NULL((void*)0); |
2318 | |
2319 | g_clear_object (&tree_view->priv->multipress_gesture)do { _Static_assert (sizeof *((&tree_view->priv->multipress_gesture )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&tree_view->priv->multipress_gesture))) _pp = ( (&tree_view->priv->multipress_gesture)); __typeof__ (*((&tree_view->priv->multipress_gesture))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); |
2320 | g_clear_object (&tree_view->priv->drag_gesture)do { _Static_assert (sizeof *((&tree_view->priv->drag_gesture )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&tree_view->priv->drag_gesture))) _pp = ((& tree_view->priv->drag_gesture)); __typeof__ (*((&tree_view ->priv->drag_gesture))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); |
2321 | g_clear_object (&tree_view->priv->column_multipress_gesture)do { _Static_assert (sizeof *((&tree_view->priv->column_multipress_gesture )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&tree_view->priv->column_multipress_gesture))) _pp = ((&tree_view->priv->column_multipress_gesture)); __typeof__ (*((&tree_view->priv->column_multipress_gesture ))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref ) (_ptr); } while (0); |
2322 | g_clear_object (&tree_view->priv->column_drag_gesture)do { _Static_assert (sizeof *((&tree_view->priv->column_drag_gesture )) == sizeof (gpointer), "Expression evaluates to false"); __typeof__ (((&tree_view->priv->column_drag_gesture))) _pp = ( (&tree_view->priv->column_drag_gesture)); __typeof__ (*((&tree_view->priv->column_drag_gesture))) _ptr = *_pp; *_pp = ((void*)0); if (_ptr) (g_object_unref) (_ptr); } while (0); |
2323 | |
2324 | CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->destroy (widget); |
2325 | } |
2326 | |
2327 | /* CtkWidget::map helper */ |
2328 | static void |
2329 | ctk_tree_view_map_buttons (CtkTreeView *tree_view) |
2330 | { |
2331 | GList *list; |
2332 | |
2333 | g_return_if_fail (ctk_widget_get_mapped (CTK_WIDGET (tree_view)))do { if ((ctk_widget_get_mapped (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view)), ((ctk_widget_get_type ()))) )))))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "ctk_widget_get_mapped (CTK_WIDGET (tree_view))" ); return; } } while (0); |
2334 | |
2335 | if (tree_view->priv->headers_visible) |
2336 | { |
2337 | CtkTreeViewColumn *column; |
2338 | CtkWidget *button; |
2339 | CdkWindow *window; |
2340 | |
2341 | for (list = tree_view->priv->columns; list; list = list->next) |
2342 | { |
2343 | column = list->data; |
2344 | button = ctk_tree_view_column_get_button (column); |
2345 | |
2346 | if (ctk_tree_view_column_get_visible (column) && button) |
2347 | ctk_widget_show_now (button); |
2348 | |
2349 | if (ctk_widget_get_visible (button) && |
2350 | !ctk_widget_get_mapped (button)) |
2351 | ctk_widget_map (button); |
2352 | } |
2353 | for (list = tree_view->priv->columns; list; list = list->next) |
2354 | { |
2355 | column = list->data; |
2356 | if (ctk_tree_view_column_get_visible (column) == FALSE(0)) |
2357 | continue; |
2358 | |
2359 | window = _ctk_tree_view_column_get_window (column); |
2360 | if (ctk_tree_view_column_get_resizable (column)) |
2361 | { |
2362 | cdk_window_raise (window); |
2363 | cdk_window_show (window); |
2364 | } |
2365 | else |
2366 | cdk_window_hide (window); |
2367 | } |
2368 | cdk_window_show (tree_view->priv->header_window); |
2369 | } |
2370 | } |
2371 | |
2372 | static void |
2373 | ctk_tree_view_map (CtkWidget *widget) |
2374 | { |
2375 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2376 | GList *tmp_list; |
2377 | |
2378 | _ctk_pixel_cache_map (tree_view->priv->pixel_cache); |
2379 | |
2380 | ctk_widget_set_mapped (widget, TRUE(!(0))); |
2381 | |
2382 | tmp_list = tree_view->priv->children; |
2383 | while (tmp_list) |
2384 | { |
2385 | CtkTreeViewChild *child = tmp_list->data; |
2386 | tmp_list = tmp_list->next; |
2387 | |
2388 | if (ctk_widget_get_visible (child->widget)) |
2389 | { |
2390 | if (!ctk_widget_get_mapped (child->widget)) |
2391 | ctk_widget_map (child->widget); |
2392 | } |
2393 | } |
2394 | cdk_window_show (tree_view->priv->bin_window); |
2395 | |
2396 | ctk_tree_view_map_buttons (tree_view); |
2397 | |
2398 | cdk_window_show (ctk_widget_get_window (widget)); |
2399 | } |
2400 | |
2401 | static void |
2402 | ctk_tree_view_unmap (CtkWidget *widget) |
2403 | { |
2404 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2405 | |
2406 | CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->unmap (widget); |
2407 | |
2408 | _ctk_pixel_cache_unmap (tree_view->priv->pixel_cache); |
2409 | } |
2410 | |
2411 | static void |
2412 | ctk_tree_view_bin_window_invalidate_handler (CdkWindow *window, |
2413 | cairo_region_t *region) |
2414 | { |
2415 | gpointer widget; |
2416 | CtkTreeView *tree_view; |
2417 | int y; |
2418 | |
2419 | cdk_window_get_user_data (window, &widget); |
2420 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2421 | |
2422 | y = ctk_adjustment_get_value (tree_view->priv->vadjustment); |
2423 | cairo_region_translate (region, |
2424 | 0, y); |
2425 | _ctk_pixel_cache_invalidate (tree_view->priv->pixel_cache, region); |
2426 | cairo_region_translate (region, |
2427 | 0, -y); |
2428 | } |
2429 | |
2430 | static void |
2431 | ctk_tree_view_queue_draw_region (CtkWidget *widget, |
2432 | const cairo_region_t *region) |
2433 | { |
2434 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2435 | |
2436 | /* There is no way we can know if a region targets the |
2437 | not-currently-visible but in pixel cache region, so we |
2438 | always just invalidate the whole thing whenever the |
2439 | tree view gets a queue draw. This doesn't normally happen |
2440 | in normal scrolling cases anyway. */ |
2441 | _ctk_pixel_cache_invalidate (tree_view->priv->pixel_cache, NULL((void*)0)); |
2442 | |
2443 | CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->queue_draw_region (widget, |
2444 | region); |
2445 | } |
2446 | |
2447 | static void |
2448 | ctk_tree_view_realize (CtkWidget *widget) |
2449 | { |
2450 | CtkAllocation allocation; |
2451 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2452 | CdkWindow *window; |
2453 | CdkWindowAttr attributes; |
2454 | GList *tmp_list; |
2455 | gint attributes_mask; |
2456 | |
2457 | ctk_widget_set_realized (widget, TRUE(!(0))); |
2458 | |
2459 | ctk_widget_get_allocation (widget, &allocation); |
2460 | |
2461 | /* Make the main, clipping window */ |
2462 | attributes.window_type = CDK_WINDOW_CHILD; |
2463 | attributes.x = allocation.x; |
2464 | attributes.y = allocation.y; |
2465 | attributes.width = allocation.width; |
2466 | attributes.height = allocation.height; |
2467 | attributes.wclass = CDK_INPUT_OUTPUT; |
2468 | attributes.visual = ctk_widget_get_visual (widget); |
2469 | attributes.event_mask = CDK_VISIBILITY_NOTIFY_MASK; |
2470 | |
2471 | attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL; |
2472 | |
2473 | window = cdk_window_new (ctk_widget_get_parent_window (widget), |
2474 | &attributes, attributes_mask); |
2475 | ctk_widget_set_window (widget, window); |
2476 | ctk_widget_register_window (widget, window); |
2477 | |
2478 | ctk_widget_get_allocation (widget, &allocation); |
2479 | |
2480 | /* Make the window for the tree */ |
2481 | attributes.x = 0; |
2482 | attributes.y = ctk_tree_view_get_effective_header_height (tree_view); |
2483 | attributes.width = MAX (tree_view->priv->width, allocation.width)(((tree_view->priv->width) > (allocation.width)) ? ( tree_view->priv->width) : (allocation.width)); |
2484 | attributes.height = allocation.height; |
2485 | attributes.event_mask = (CDK_SCROLL_MASK | |
2486 | CDK_SMOOTH_SCROLL_MASK | |
2487 | CDK_POINTER_MOTION_MASK | |
2488 | CDK_ENTER_NOTIFY_MASK | |
2489 | CDK_LEAVE_NOTIFY_MASK | |
2490 | CDK_BUTTON_PRESS_MASK | |
2491 | CDK_BUTTON_RELEASE_MASK | |
2492 | ctk_widget_get_events (widget)); |
2493 | |
2494 | tree_view->priv->bin_window = cdk_window_new (window, |
2495 | &attributes, attributes_mask); |
2496 | ctk_widget_register_window (widget, tree_view->priv->bin_window); |
2497 | cdk_window_set_invalidate_handler (tree_view->priv->bin_window, |
2498 | ctk_tree_view_bin_window_invalidate_handler); |
2499 | |
2500 | ctk_widget_get_allocation (widget, &allocation); |
2501 | |
2502 | /* Make the column header window */ |
2503 | attributes.x = 0; |
2504 | attributes.y = 0; |
2505 | attributes.width = MAX (tree_view->priv->width, allocation.width)(((tree_view->priv->width) > (allocation.width)) ? ( tree_view->priv->width) : (allocation.width)); |
2506 | attributes.height = tree_view->priv->header_height; |
2507 | attributes.event_mask = (CDK_SCROLL_MASK | |
2508 | CDK_ENTER_NOTIFY_MASK | |
2509 | CDK_LEAVE_NOTIFY_MASK | |
2510 | CDK_BUTTON_PRESS_MASK | |
2511 | CDK_BUTTON_RELEASE_MASK | |
2512 | CDK_KEY_PRESS_MASK | |
2513 | CDK_KEY_RELEASE_MASK | |
2514 | ctk_widget_get_events (widget)); |
2515 | |
2516 | tree_view->priv->header_window = cdk_window_new (window, |
2517 | &attributes, attributes_mask); |
2518 | ctk_widget_register_window (widget, tree_view->priv->header_window); |
2519 | |
2520 | tmp_list = tree_view->priv->children; |
2521 | while (tmp_list) |
2522 | { |
2523 | CtkTreeViewChild *child = tmp_list->data; |
2524 | tmp_list = tmp_list->next; |
2525 | |
2526 | ctk_widget_set_parent_window (child->widget, tree_view->priv->bin_window); |
2527 | } |
2528 | |
2529 | for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) |
2530 | _ctk_tree_view_column_realize_button (CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ()))))))); |
2531 | |
2532 | /* Need to call those here, since they create GCs */ |
2533 | ctk_tree_view_set_grid_lines (tree_view, tree_view->priv->grid_lines); |
2534 | ctk_tree_view_set_enable_tree_lines (tree_view, tree_view->priv->tree_lines_enabled); |
2535 | |
2536 | install_presize_handler (tree_view); |
2537 | |
2538 | ctk_gesture_set_window (tree_view->priv->multipress_gesture, |
2539 | tree_view->priv->bin_window); |
2540 | ctk_gesture_set_window (tree_view->priv->drag_gesture, |
2541 | tree_view->priv->bin_window); |
2542 | } |
2543 | |
2544 | static void |
2545 | ctk_tree_view_unrealize (CtkWidget *widget) |
2546 | { |
2547 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2548 | CtkTreeViewPrivate *priv = tree_view->priv; |
2549 | GList *list; |
2550 | |
2551 | if (priv->scroll_timeout != 0) |
2552 | { |
2553 | g_source_remove (priv->scroll_timeout); |
2554 | priv->scroll_timeout = 0; |
2555 | } |
2556 | |
2557 | if (priv->auto_expand_timeout != 0) |
2558 | { |
2559 | g_source_remove (priv->auto_expand_timeout); |
2560 | priv->auto_expand_timeout = 0; |
2561 | } |
2562 | |
2563 | if (priv->open_dest_timeout != 0) |
2564 | { |
2565 | g_source_remove (priv->open_dest_timeout); |
2566 | priv->open_dest_timeout = 0; |
2567 | } |
2568 | |
2569 | if (priv->presize_handler_tick_cb != 0) |
2570 | { |
2571 | ctk_widget_remove_tick_callback (widget, priv->presize_handler_tick_cb); |
2572 | priv->presize_handler_tick_cb = 0; |
2573 | } |
2574 | |
2575 | if (priv->validate_rows_timer != 0) |
2576 | { |
2577 | g_source_remove (priv->validate_rows_timer); |
2578 | priv->validate_rows_timer = 0; |
2579 | } |
2580 | |
2581 | if (priv->scroll_sync_timer != 0) |
2582 | { |
2583 | g_source_remove (priv->scroll_sync_timer); |
2584 | priv->scroll_sync_timer = 0; |
2585 | } |
2586 | |
2587 | if (priv->typeselect_flush_timeout) |
2588 | { |
2589 | g_source_remove (priv->typeselect_flush_timeout); |
2590 | priv->typeselect_flush_timeout = 0; |
2591 | } |
2592 | |
2593 | for (list = priv->columns; list; list = list->next) |
2594 | _ctk_tree_view_column_unrealize_button (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))); |
2595 | |
2596 | ctk_widget_unregister_window (widget, priv->bin_window); |
2597 | cdk_window_destroy (priv->bin_window); |
2598 | priv->bin_window = NULL((void*)0); |
2599 | |
2600 | ctk_widget_unregister_window (widget, priv->header_window); |
2601 | cdk_window_destroy (priv->header_window); |
2602 | priv->header_window = NULL((void*)0); |
2603 | |
2604 | if (priv->drag_window) |
2605 | { |
2606 | ctk_widget_unregister_window (widget, priv->drag_window); |
2607 | cdk_window_destroy (priv->drag_window); |
2608 | priv->drag_window = NULL((void*)0); |
2609 | } |
2610 | |
2611 | if (priv->drag_highlight_window) |
2612 | { |
2613 | ctk_widget_unregister_window (widget, priv->drag_highlight_window); |
2614 | cdk_window_destroy (priv->drag_highlight_window); |
2615 | priv->drag_highlight_window = NULL((void*)0); |
2616 | } |
2617 | |
2618 | ctk_gesture_set_window (tree_view->priv->multipress_gesture, NULL((void*)0)); |
2619 | ctk_gesture_set_window (tree_view->priv->drag_gesture, NULL((void*)0)); |
2620 | |
2621 | CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->unrealize (widget); |
2622 | } |
2623 | |
2624 | /* CtkWidget::get_preferred_height helper */ |
2625 | static void |
2626 | ctk_tree_view_update_height (CtkTreeView *tree_view) |
2627 | { |
2628 | GList *list; |
2629 | |
2630 | tree_view->priv->header_height = 0; |
2631 | |
2632 | for (list = tree_view->priv->columns; list; list = list->next) |
2633 | { |
2634 | CtkRequisition requisition; |
2635 | CtkTreeViewColumn *column = list->data; |
2636 | CtkWidget *button = ctk_tree_view_column_get_button (column); |
2637 | |
2638 | if (button == NULL((void*)0)) |
2639 | continue; |
2640 | |
2641 | ctk_widget_get_preferred_size (button, &requisition, NULL((void*)0)); |
2642 | tree_view->priv->header_height = MAX (tree_view->priv->header_height, requisition.height)(((tree_view->priv->header_height) > (requisition.height )) ? (tree_view->priv->header_height) : (requisition.height )); |
2643 | } |
2644 | } |
2645 | |
2646 | static gint |
2647 | ctk_tree_view_get_height (CtkTreeView *tree_view) |
2648 | { |
2649 | if (tree_view->priv->tree == NULL((void*)0)) |
2650 | return 0; |
2651 | else |
2652 | return tree_view->priv->tree->root->offset; |
2653 | } |
2654 | |
2655 | static void |
2656 | ctk_tree_view_get_preferred_width (CtkWidget *widget, |
2657 | gint *minimum, |
2658 | gint *natural) |
2659 | { |
2660 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2661 | GList *list; |
2662 | CtkTreeViewColumn *column; |
2663 | gint width = 0; |
2664 | |
2665 | /* we validate some rows initially just to make sure we have some size. |
2666 | * In practice, with a lot of static lists, this should get a good width. |
2667 | */ |
2668 | do_validate_rows (tree_view, FALSE(0)); |
2669 | |
2670 | /* keep this in sync with size_allocate below */ |
2671 | for (list = tree_view->priv->columns; list; list = list->next) |
2672 | { |
2673 | column = list->data; |
2674 | if (!ctk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column) |
2675 | continue; |
2676 | |
2677 | width += _ctk_tree_view_column_request_width (column); |
2678 | } |
2679 | |
2680 | *minimum = *natural = width; |
2681 | } |
2682 | |
2683 | static void |
2684 | ctk_tree_view_get_preferred_height (CtkWidget *widget, |
2685 | gint *minimum, |
2686 | gint *natural) |
2687 | { |
2688 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2689 | gint height; |
2690 | |
2691 | ctk_tree_view_update_height (tree_view); |
2692 | |
2693 | height = ctk_tree_view_get_height (tree_view) + ctk_tree_view_get_effective_header_height (tree_view); |
2694 | |
2695 | *minimum = *natural = height; |
2696 | } |
2697 | |
2698 | static int |
2699 | ctk_tree_view_calculate_width_before_expander (CtkTreeView *tree_view) |
2700 | { |
2701 | int width = 0; |
2702 | GList *list; |
2703 | gboolean rtl; |
2704 | |
2705 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
2706 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
2707 | list->data != tree_view->priv->expander_column; |
2708 | list = (rtl ? list->prev : list->next)) |
2709 | { |
2710 | CtkTreeViewColumn *column = list->data; |
2711 | |
2712 | width += ctk_tree_view_column_get_width (column); |
2713 | } |
2714 | |
2715 | return width; |
2716 | } |
2717 | |
2718 | /* CtkWidget::size_allocate helper */ |
2719 | static void |
2720 | ctk_tree_view_size_allocate_columns (CtkWidget *widget, |
2721 | gboolean *width_changed) |
2722 | { |
2723 | CtkTreeView *tree_view; |
2724 | GList *list, *first_column, *last_column; |
2725 | CtkTreeViewColumn *column; |
2726 | CtkAllocation widget_allocation; |
2727 | gint width = 0; |
2728 | gint extra, extra_per_column, extra_for_last; |
2729 | gint full_requested_width = 0; |
2730 | gint number_of_expand_columns = 0; |
2731 | gboolean rtl; |
2732 | gboolean update_expand; |
2733 | |
2734 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2735 | |
2736 | for (last_column = g_list_last (tree_view->priv->columns); |
2737 | last_column && |
2738 | !(ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (last_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((last_column->data)), ((ctk_tree_view_column_get_type ())))))))); |
2739 | last_column = last_column->prev) |
2740 | ; |
2741 | if (last_column == NULL((void*)0)) |
2742 | return; |
2743 | |
2744 | for (first_column = g_list_first (tree_view->priv->columns); |
2745 | first_column && |
2746 | !(ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (first_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((first_column->data)), ((ctk_tree_view_column_get_type ())))))))); |
2747 | first_column = first_column->next) |
2748 | ; |
2749 | |
2750 | if (first_column == NULL((void*)0)) |
2751 | return; |
2752 | |
2753 | rtl = (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL); |
2754 | |
2755 | /* find out how many extra space and expandable columns we have */ |
2756 | for (list = tree_view->priv->columns; list != last_column->next; list = list->next) |
2757 | { |
2758 | column = (CtkTreeViewColumn *)list->data; |
2759 | |
2760 | if (!ctk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column) |
2761 | continue; |
2762 | |
2763 | full_requested_width += _ctk_tree_view_column_request_width (column); |
2764 | |
2765 | if (ctk_tree_view_column_get_expand (column)) |
2766 | number_of_expand_columns++; |
2767 | } |
2768 | |
2769 | /* Only update the expand value if the width of the widget has changed, |
2770 | * or the number of expand columns has changed, or if there are no expand |
2771 | * columns, or if we didn't have an size-allocation yet after the |
2772 | * last validated node. |
2773 | */ |
2774 | update_expand = (width_changed && *width_changed == TRUE(!(0))) |
2775 | || number_of_expand_columns != tree_view->priv->last_number_of_expand_columns |
2776 | || number_of_expand_columns == 0 |
2777 | || tree_view->priv->post_validation_flag == TRUE(!(0)); |
2778 | |
2779 | tree_view->priv->post_validation_flag = FALSE(0); |
2780 | |
2781 | ctk_widget_get_allocation (widget, &widget_allocation); |
2782 | if (!update_expand) |
2783 | { |
2784 | extra = tree_view->priv->last_extra_space; |
2785 | extra_for_last = MAX (widget_allocation.width - full_requested_width - extra, 0)(((widget_allocation.width - full_requested_width - extra) > (0)) ? (widget_allocation.width - full_requested_width - extra ) : (0)); |
2786 | } |
2787 | else |
2788 | { |
2789 | extra = MAX (widget_allocation.width - full_requested_width, 0)(((widget_allocation.width - full_requested_width) > (0)) ? (widget_allocation.width - full_requested_width) : (0)); |
2790 | extra_for_last = 0; |
2791 | |
2792 | tree_view->priv->last_extra_space = extra; |
2793 | } |
2794 | |
2795 | if (number_of_expand_columns > 0) |
2796 | extra_per_column = extra/number_of_expand_columns; |
2797 | else |
2798 | extra_per_column = 0; |
2799 | |
2800 | if (update_expand) |
2801 | { |
2802 | tree_view->priv->last_extra_space_per_column = extra_per_column; |
2803 | tree_view->priv->last_number_of_expand_columns = number_of_expand_columns; |
2804 | } |
2805 | |
2806 | for (list = (rtl ? last_column : first_column); |
2807 | list != (rtl ? first_column->prev : last_column->next); |
2808 | list = (rtl ? list->prev : list->next)) |
2809 | { |
2810 | gint column_width; |
2811 | |
2812 | column = list->data; |
2813 | |
2814 | if (!ctk_tree_view_column_get_visible (column) || column == tree_view->priv->drag_column) |
2815 | continue; |
2816 | |
2817 | column_width = _ctk_tree_view_column_request_width (column); |
2818 | |
2819 | if (ctk_tree_view_column_get_expand (column)) |
2820 | { |
2821 | if (number_of_expand_columns == 1) |
2822 | { |
2823 | /* We add the remander to the last column as |
2824 | * */ |
2825 | column_width += extra; |
2826 | } |
2827 | else |
2828 | { |
2829 | column_width += extra_per_column; |
2830 | extra -= extra_per_column; |
2831 | number_of_expand_columns --; |
2832 | } |
2833 | } |
2834 | else if (number_of_expand_columns == 0 && |
2835 | list == last_column) |
2836 | { |
2837 | column_width += extra; |
2838 | } |
2839 | |
2840 | /* In addition to expand, the last column can get even more |
2841 | * extra space so all available space is filled up. |
2842 | */ |
2843 | if (extra_for_last > 0 && list == last_column) |
2844 | column_width += extra_for_last; |
2845 | |
2846 | _ctk_tree_view_column_allocate (column, width, column_width); |
2847 | |
2848 | width += column_width; |
2849 | } |
2850 | |
2851 | /* We change the width here. The user might have been resizing columns, |
2852 | * which changes the total width of the tree view. This is of |
2853 | * importance for getting the horizontal scroll bar right. |
2854 | */ |
2855 | if (tree_view->priv->width != width) |
2856 | { |
2857 | tree_view->priv->width = width; |
2858 | if (width_changed) |
2859 | *width_changed = TRUE(!(0)); |
2860 | } |
2861 | } |
2862 | |
2863 | /* CtkWidget::size_allocate helper */ |
2864 | static void |
2865 | ctk_tree_view_size_allocate_drag_column (CtkWidget *widget) |
2866 | { |
2867 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2868 | CtkAllocation drag_allocation; |
2869 | CtkWidget *button; |
2870 | |
2871 | if (tree_view->priv->drag_column == NULL((void*)0)) |
2872 | return; |
2873 | |
2874 | button = ctk_tree_view_column_get_button (tree_view->priv->drag_column); |
2875 | |
2876 | drag_allocation.x = 0; |
2877 | drag_allocation.y = 0; |
2878 | drag_allocation.width = cdk_window_get_width (tree_view->priv->drag_window); |
2879 | drag_allocation.height = cdk_window_get_height (tree_view->priv->drag_window); |
2880 | ctk_widget_size_allocate (button, &drag_allocation); |
2881 | } |
2882 | |
2883 | static void |
2884 | ctk_tree_view_size_allocate (CtkWidget *widget, |
2885 | CtkAllocation *allocation) |
2886 | { |
2887 | CtkAllocation widget_allocation; |
2888 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
2889 | GList *tmp_list; |
2890 | gboolean width_changed = FALSE(0); |
2891 | gint old_width; |
2892 | double page_size; |
2893 | |
2894 | ctk_widget_get_allocation (widget, &widget_allocation); |
2895 | old_width = widget_allocation.width; |
2896 | if (allocation->width != widget_allocation.width) |
2897 | width_changed = TRUE(!(0)); |
2898 | |
2899 | ctk_widget_set_allocation (widget, allocation); |
2900 | |
2901 | /* We size-allocate the columns first because the width of the |
2902 | * tree view (used in updating the adjustments below) might change. |
2903 | */ |
2904 | ctk_tree_view_size_allocate_columns (widget, &width_changed); |
2905 | ctk_tree_view_size_allocate_drag_column (widget); |
2906 | |
2907 | g_object_freeze_notify (G_OBJECT (tree_view->priv->hadjustment)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->hadjustment)), (((GType) ((20) << (2))))))))); |
2908 | ctk_adjustment_set_page_size (tree_view->priv->hadjustment, |
2909 | allocation->width); |
2910 | ctk_adjustment_set_page_increment (tree_view->priv->hadjustment, |
2911 | allocation->width * 0.9); |
2912 | ctk_adjustment_set_step_increment (tree_view->priv->hadjustment, |
2913 | allocation->width * 0.1); |
2914 | ctk_adjustment_set_lower (tree_view->priv->hadjustment, 0); |
2915 | ctk_adjustment_set_upper (tree_view->priv->hadjustment, |
2916 | MAX (ctk_adjustment_get_page_size (tree_view->priv->hadjustment),(((ctk_adjustment_get_page_size (tree_view->priv->hadjustment )) > (tree_view->priv->width)) ? (ctk_adjustment_get_page_size (tree_view->priv->hadjustment)) : (tree_view->priv-> width)) |
2917 | tree_view->priv->width)(((ctk_adjustment_get_page_size (tree_view->priv->hadjustment )) > (tree_view->priv->width)) ? (ctk_adjustment_get_page_size (tree_view->priv->hadjustment)) : (tree_view->priv-> width))); |
2918 | g_object_thaw_notify (G_OBJECT (tree_view->priv->hadjustment)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->hadjustment)), (((GType) ((20) << (2))))))))); |
2919 | |
2920 | if (ctk_widget_get_direction(widget) == CTK_TEXT_DIR_RTL) |
2921 | { |
2922 | if (allocation->width < tree_view->priv->width) |
2923 | { |
2924 | if (tree_view->priv->init_hadjust_value) |
2925 | { |
2926 | ctk_adjustment_set_value (tree_view->priv->hadjustment, |
2927 | MAX (tree_view->priv->width -(((tree_view->priv->width - allocation->width) > ( 0)) ? (tree_view->priv->width - allocation->width) : (0)) |
2928 | allocation->width, 0)(((tree_view->priv->width - allocation->width) > ( 0)) ? (tree_view->priv->width - allocation->width) : (0))); |
2929 | tree_view->priv->init_hadjust_value = FALSE(0); |
2930 | } |
2931 | else if (allocation->width != old_width) |
2932 | { |
2933 | ctk_adjustment_set_value (tree_view->priv->hadjustment, |
2934 | CLAMP (ctk_adjustment_get_value (tree_view->priv->hadjustment) - allocation->width + old_width,(((ctk_adjustment_get_value (tree_view->priv->hadjustment ) - allocation->width + old_width) > (tree_view->priv ->width - allocation->width)) ? (tree_view->priv-> width - allocation->width) : (((ctk_adjustment_get_value ( tree_view->priv->hadjustment) - allocation->width + old_width ) < (0)) ? (0) : (ctk_adjustment_get_value (tree_view-> priv->hadjustment) - allocation->width + old_width))) |
2935 | 0,(((ctk_adjustment_get_value (tree_view->priv->hadjustment ) - allocation->width + old_width) > (tree_view->priv ->width - allocation->width)) ? (tree_view->priv-> width - allocation->width) : (((ctk_adjustment_get_value ( tree_view->priv->hadjustment) - allocation->width + old_width ) < (0)) ? (0) : (ctk_adjustment_get_value (tree_view-> priv->hadjustment) - allocation->width + old_width))) |
2936 | tree_view->priv->width - allocation->width)(((ctk_adjustment_get_value (tree_view->priv->hadjustment ) - allocation->width + old_width) > (tree_view->priv ->width - allocation->width)) ? (tree_view->priv-> width - allocation->width) : (((ctk_adjustment_get_value ( tree_view->priv->hadjustment) - allocation->width + old_width ) < (0)) ? (0) : (ctk_adjustment_get_value (tree_view-> priv->hadjustment) - allocation->width + old_width)))); |
2937 | } |
2938 | } |
2939 | else |
2940 | { |
2941 | ctk_adjustment_set_value (tree_view->priv->hadjustment, 0); |
2942 | tree_view->priv->init_hadjust_value = TRUE(!(0)); |
2943 | } |
2944 | } |
2945 | else |
2946 | if (ctk_adjustment_get_value (tree_view->priv->hadjustment) + allocation->width > tree_view->priv->width) |
2947 | ctk_adjustment_set_value (tree_view->priv->hadjustment, |
2948 | MAX (tree_view->priv->width -(((tree_view->priv->width - allocation->width) > ( 0)) ? (tree_view->priv->width - allocation->width) : (0)) |
2949 | allocation->width, 0)(((tree_view->priv->width - allocation->width) > ( 0)) ? (tree_view->priv->width - allocation->width) : (0))); |
2950 | |
2951 | page_size = allocation->height - ctk_tree_view_get_effective_header_height (tree_view); |
2952 | ctk_adjustment_configure (tree_view->priv->vadjustment, |
2953 | ctk_adjustment_get_value (tree_view->priv->vadjustment), |
2954 | 0, |
2955 | MAX (page_size, ctk_tree_view_get_height (tree_view))(((page_size) > (ctk_tree_view_get_height (tree_view))) ? ( page_size) : (ctk_tree_view_get_height (tree_view))), |
2956 | page_size * 0.1, |
2957 | page_size * 0.9, |
2958 | page_size); |
2959 | |
2960 | /* now the adjustments and window sizes are in sync, we can sync toprow/dy again */ |
2961 | if (ctk_tree_row_reference_valid (tree_view->priv->top_row)) |
2962 | ctk_tree_view_top_row_to_dy (tree_view); |
2963 | else |
2964 | ctk_tree_view_dy_to_top_row (tree_view); |
2965 | |
2966 | if (ctk_widget_get_realized (widget)) |
2967 | { |
2968 | cdk_window_move_resize (ctk_widget_get_window (widget), |
2969 | allocation->x, allocation->y, |
2970 | allocation->width, allocation->height); |
2971 | cdk_window_move_resize (tree_view->priv->header_window, |
2972 | - (gint) ctk_adjustment_get_value (tree_view->priv->hadjustment), |
2973 | 0, |
2974 | MAX (tree_view->priv->width, allocation->width)(((tree_view->priv->width) > (allocation->width)) ? (tree_view->priv->width) : (allocation->width)), |
2975 | tree_view->priv->header_height); |
2976 | cdk_window_move_resize (tree_view->priv->bin_window, |
2977 | - (gint) ctk_adjustment_get_value (tree_view->priv->hadjustment), |
2978 | ctk_tree_view_get_effective_header_height (tree_view), |
2979 | MAX (tree_view->priv->width, allocation->width)(((tree_view->priv->width) > (allocation->width)) ? (tree_view->priv->width) : (allocation->width)), |
2980 | allocation->height - ctk_tree_view_get_effective_header_height (tree_view)); |
2981 | |
2982 | if (tree_view->priv->tree == NULL((void*)0)) |
2983 | invalidate_empty_focus (tree_view); |
2984 | |
2985 | if (width_changed && tree_view->priv->expander_column) |
2986 | { |
2987 | /* Might seem awkward, but is the best heuristic I could come up |
2988 | * with. Only if the width of the columns before the expander |
2989 | * changes, we will update the prelight status. It is this |
2990 | * width that makes the expander move vertically. Always updating |
2991 | * prelight status causes trouble with hover selections. |
2992 | */ |
2993 | gint width_before_expander; |
2994 | |
2995 | width_before_expander = ctk_tree_view_calculate_width_before_expander (tree_view); |
2996 | |
2997 | if (tree_view->priv->prev_width_before_expander |
2998 | != width_before_expander) |
2999 | update_prelight (tree_view, |
3000 | tree_view->priv->event_last_x, |
3001 | tree_view->priv->event_last_y); |
3002 | |
3003 | tree_view->priv->prev_width_before_expander = width_before_expander; |
3004 | } |
3005 | } |
3006 | |
3007 | for (tmp_list = tree_view->priv->children; tmp_list; tmp_list = tmp_list->next) |
3008 | { |
3009 | CtkTreeViewChild *child = tmp_list->data; |
3010 | CtkTreePath *path; |
3011 | CdkRectangle child_rect; |
3012 | int min_x, max_x, min_y, max_y; |
3013 | int size; |
3014 | CtkTextDirection direction; |
3015 | |
3016 | direction = ctk_widget_get_direction (child->widget); |
3017 | path = _ctk_tree_path_new_from_rbtree (child->tree, child->node); |
3018 | ctk_tree_view_get_cell_area (tree_view, path, child->column, &child_rect); |
3019 | child_rect.x += child->border.left; |
3020 | child_rect.y += child->border.top; |
3021 | child_rect.width -= child->border.left + child->border.right; |
3022 | child_rect.height -= child->border.top + child->border.bottom; |
3023 | |
3024 | ctk_widget_get_preferred_width (CTK_WIDGET (child->widget)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child->widget)), ((ctk_widget_get_type ())))))), &size, NULL((void*)0)); |
3025 | |
3026 | if (size > child_rect.width) |
3027 | { |
3028 | /* Enlarge the child, extending it to the left (RTL) */ |
3029 | if (direction == CTK_TEXT_DIR_RTL) |
3030 | child_rect.x -= (size - child_rect.width); |
3031 | /* or to the right (LTR) */ |
3032 | else |
3033 | child_rect.x += 0; |
3034 | |
3035 | child_rect.width = size; |
3036 | } |
3037 | |
3038 | ctk_widget_get_preferred_height_for_width (CTK_WIDGET (child->widget)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((child->widget)), ((ctk_widget_get_type ())))))), |
3039 | child_rect.width, |
3040 | &size, NULL((void*)0)); |
3041 | if (size > child_rect.height) |
3042 | { |
3043 | /* Enlarge the child, extending in both directions equally */ |
3044 | child_rect.y -= (size - child_rect.height) / 2; |
3045 | child_rect.height = size; |
3046 | } |
3047 | |
3048 | /* push the rect back in the visible area if needed, |
3049 | * preferring the top left corner (for RTL) |
3050 | * or top right corner (for LTR) |
3051 | */ |
3052 | min_x = ctk_adjustment_get_value (tree_view->priv->hadjustment); |
3053 | max_x = min_x + allocation->width - child_rect.width; |
3054 | min_y = 0; |
3055 | max_y = min_y + allocation->height - ctk_tree_view_get_effective_header_height (tree_view) - child_rect.height; |
3056 | |
3057 | if (direction == CTK_TEXT_DIR_LTR) |
3058 | /* Ensure that child's right edge is not sticking to the right |
3059 | * (if (child_rect.x > max_x) child_rect.x = max_x), |
3060 | * then ensure that child's left edge is visible and is not sticking to the left |
3061 | * (if (child_rect.x < min_x) child_rect.x = min_x). |
3062 | */ |
3063 | child_rect.x = MAX (min_x, MIN (max_x, child_rect.x))(((min_x) > ((((max_x) < (child_rect.x)) ? (max_x) : (child_rect .x)))) ? (min_x) : ((((max_x) < (child_rect.x)) ? (max_x) : (child_rect.x)))); |
3064 | else |
3065 | /* Ensure that child's left edge is not sticking to the left |
3066 | * (if (child_rect.x < min_x) child_rect.x = min_x), |
3067 | * then ensure that child's right edge is visible and is not sticking to the right |
3068 | * (if (child_rect.x > max_x) child_rect.x = max_x). |
3069 | */ |
3070 | child_rect.x = MIN (max_x, MAX (min_x, child_rect.x))(((max_x) < ((((min_x) > (child_rect.x)) ? (min_x) : (child_rect .x)))) ? (max_x) : ((((min_x) > (child_rect.x)) ? (min_x) : (child_rect.x)))); |
3071 | |
3072 | child_rect.y = MAX (min_y, MIN (max_y, child_rect.y))(((min_y) > ((((max_y) < (child_rect.y)) ? (max_y) : (child_rect .y)))) ? (min_y) : ((((max_y) < (child_rect.y)) ? (max_y) : (child_rect.y)))); |
3073 | |
3074 | ctk_tree_path_free (path); |
3075 | ctk_widget_size_allocate (child->widget, &child_rect); |
3076 | } |
3077 | } |
3078 | |
3079 | /* Grabs the focus and unsets the CTK_TREE_VIEW_DRAW_KEYFOCUS flag */ |
3080 | static void |
3081 | grab_focus_and_unset_draw_keyfocus (CtkTreeView *tree_view) |
3082 | { |
3083 | CtkWidget *widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
3084 | |
3085 | if (ctk_widget_get_can_focus (widget) && |
3086 | !ctk_widget_has_focus (widget) && |
3087 | !_ctk_widget_get_shadowed (widget)) |
3088 | ctk_widget_grab_focus (widget); |
3089 | |
3090 | tree_view->priv->draw_keyfocus = 0; |
3091 | } |
3092 | |
3093 | static inline gboolean |
3094 | row_is_separator (CtkTreeView *tree_view, |
3095 | CtkTreeIter *iter, |
3096 | CtkTreePath *path) |
3097 | { |
3098 | gboolean is_separator = FALSE(0); |
3099 | |
3100 | if (tree_view->priv->row_separator_func) |
3101 | { |
3102 | CtkTreeIter tmpiter; |
3103 | |
3104 | if (iter) |
3105 | tmpiter = *iter; |
3106 | else |
3107 | { |
3108 | if (!ctk_tree_model_get_iter (tree_view->priv->model, &tmpiter, path)) |
3109 | return FALSE(0); |
3110 | } |
3111 | |
3112 | is_separator = tree_view->priv->row_separator_func (tree_view->priv->model, |
3113 | &tmpiter, |
3114 | tree_view->priv->row_separator_data); |
3115 | } |
3116 | |
3117 | return is_separator; |
3118 | } |
3119 | |
3120 | static int |
3121 | ctk_tree_view_get_expander_size (CtkTreeView *tree_view) |
3122 | { |
3123 | gint expander_size; |
3124 | gint horizontal_separator; |
3125 | |
3126 | ctk_widget_style_get (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
3127 | "expander-size", &expander_size, |
3128 | "horizontal-separator", &horizontal_separator, |
3129 | NULL((void*)0)); |
3130 | |
3131 | return expander_size + (horizontal_separator / 2); |
3132 | } |
3133 | |
3134 | static void |
3135 | get_current_selection_modifiers (CtkWidget *widget, |
3136 | gboolean *modify, |
3137 | gboolean *extend) |
3138 | { |
3139 | CdkModifierType state = 0; |
3140 | CdkModifierType mask; |
3141 | |
3142 | *modify = FALSE(0); |
3143 | *extend = FALSE(0); |
3144 | |
3145 | if (ctk_get_current_event_state (&state)) |
3146 | { |
3147 | mask = ctk_widget_get_modifier_mask (widget, CDK_MODIFIER_INTENT_MODIFY_SELECTION); |
3148 | if ((state & mask) == mask) |
3149 | *modify = TRUE(!(0)); |
3150 | mask = ctk_widget_get_modifier_mask (widget, CDK_MODIFIER_INTENT_EXTEND_SELECTION); |
3151 | if ((state & mask) == mask) |
3152 | *extend = TRUE(!(0)); |
3153 | } |
3154 | } |
3155 | |
3156 | static void |
3157 | ctk_tree_view_multipress_gesture_pressed (CtkGestureMultiPress *gesture, |
3158 | gint n_press, |
3159 | gdouble x, |
3160 | gdouble y, |
3161 | CtkTreeView *tree_view) |
3162 | { |
3163 | gint vertical_separator, horizontal_separator; |
3164 | CtkWidget *widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
3165 | CdkRectangle background_area, cell_area; |
3166 | CtkTreeViewColumn *column = NULL((void*)0); |
3167 | CdkEventSequence *sequence; |
3168 | CdkModifierType modifiers; |
3169 | const CdkEvent *event; |
3170 | gint new_y, y_offset; |
3171 | gint bin_x, bin_y; |
3172 | CtkTreePath *path; |
3173 | CtkRBNode *node; |
3174 | CtkRBTree *tree; |
3175 | gint depth; |
3176 | guint button; |
3177 | GList *list; |
3178 | gboolean rtl; |
3179 | |
3180 | rtl = (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL); |
3181 | ctk_tree_view_stop_editing (tree_view, FALSE(0)); |
3182 | ctk_widget_style_get (widget, |
3183 | "vertical-separator", &vertical_separator, |
3184 | "horizontal-separator", &horizontal_separator, |
3185 | NULL((void*)0)); |
3186 | button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
3187 | |
3188 | if (button > 3) |
3189 | { |
3190 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_DENIED); |
3191 | return; |
3192 | } |
3193 | |
3194 | /* Because grab_focus can cause reentrancy, we delay grab_focus until after |
3195 | * we're done handling the button press. |
3196 | */ |
3197 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, |
3198 | &bin_x, &bin_y); |
3199 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_CLAIMED); |
3200 | |
3201 | if (n_press > 1) |
3202 | ctk_gesture_set_state (tree_view->priv->drag_gesture, |
3203 | CTK_EVENT_SEQUENCE_DENIED); |
3204 | |
3205 | /* Empty tree? */ |
3206 | if (tree_view->priv->tree == NULL((void*)0)) |
3207 | { |
3208 | grab_focus_and_unset_draw_keyfocus (tree_view); |
3209 | return; |
3210 | } |
3211 | |
3212 | /* are we in an arrow? */ |
3213 | if (tree_view->priv->prelight_node && |
3214 | tree_view->priv->arrow_prelit && |
3215 | ctk_tree_view_draw_expanders (tree_view)) |
3216 | { |
3217 | if (button == CDK_BUTTON_PRIMARY(1)) |
3218 | { |
3219 | tree_view->priv->button_pressed_node = tree_view->priv->prelight_node; |
3220 | tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree; |
3221 | ctk_tree_view_queue_draw_arrow (tree_view, |
3222 | tree_view->priv->prelight_tree, |
3223 | tree_view->priv->prelight_node); |
3224 | } |
3225 | |
3226 | grab_focus_and_unset_draw_keyfocus (tree_view); |
3227 | return; |
3228 | } |
3229 | |
3230 | /* find the node that was clicked */ |
3231 | new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, bin_y)((bin_y) + tree_view->priv->dy); |
3232 | if (new_y < 0) |
3233 | new_y = 0; |
3234 | y_offset = -_ctk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node); |
3235 | |
3236 | if (node == NULL((void*)0)) |
3237 | { |
3238 | /* We clicked in dead space */ |
3239 | grab_focus_and_unset_draw_keyfocus (tree_view); |
3240 | return; |
3241 | } |
3242 | |
3243 | /* Get the path and the node */ |
3244 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
3245 | |
3246 | if (row_is_separator (tree_view, NULL((void*)0), path)) |
3247 | { |
3248 | ctk_tree_path_free (path); |
3249 | grab_focus_and_unset_draw_keyfocus (tree_view); |
3250 | return; |
3251 | } |
3252 | |
3253 | depth = ctk_tree_path_get_depth (path); |
3254 | background_area.y = y_offset + bin_y; |
3255 | background_area.height = ctk_tree_view_get_row_height (tree_view, node); |
3256 | background_area.x = 0; |
3257 | |
3258 | /* Let the column have a chance at selecting it. */ |
3259 | rtl = (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL); |
3260 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
3261 | list; list = (rtl ? list->prev : list->next)) |
3262 | { |
3263 | CtkTreeViewColumn *candidate = list->data; |
3264 | |
3265 | if (!ctk_tree_view_column_get_visible (candidate)) |
3266 | continue; |
3267 | |
3268 | background_area.width = ctk_tree_view_column_get_width (candidate); |
3269 | if ((background_area.x > bin_x) || |
3270 | (background_area.x + background_area.width <= bin_x)) |
3271 | { |
3272 | background_area.x += background_area.width; |
3273 | continue; |
3274 | } |
3275 | |
3276 | /* we found the focus column */ |
3277 | column = candidate; |
3278 | cell_area = background_area; |
3279 | cell_area.width -= horizontal_separator; |
3280 | cell_area.height -= vertical_separator; |
3281 | cell_area.x += horizontal_separator/2; |
3282 | cell_area.y += vertical_separator/2; |
3283 | if (ctk_tree_view_is_expander_column (tree_view, column)) |
3284 | { |
3285 | if (!rtl) |
3286 | cell_area.x += (depth - 1) * tree_view->priv->level_indentation; |
3287 | cell_area.width -= (depth - 1) * tree_view->priv->level_indentation; |
3288 | |
3289 | if (ctk_tree_view_draw_expanders (tree_view)) |
3290 | { |
3291 | gint expander_size = ctk_tree_view_get_expander_size (tree_view); |
3292 | if (!rtl) |
3293 | cell_area.x += depth * expander_size; |
3294 | cell_area.width -= depth * expander_size; |
3295 | } |
3296 | } |
3297 | break; |
3298 | } |
3299 | |
3300 | if (column == NULL((void*)0)) |
3301 | { |
3302 | ctk_tree_path_free (path); |
3303 | grab_focus_and_unset_draw_keyfocus (tree_view); |
3304 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_DENIED); |
3305 | return; |
3306 | } |
3307 | |
3308 | _ctk_tree_view_set_focus_column (tree_view, column); |
3309 | |
3310 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
3311 | event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), sequence); |
3312 | cdk_event_get_state (event, &modifiers); |
3313 | |
3314 | /* decide if we edit */ |
3315 | if (button == CDK_BUTTON_PRIMARY(1) && |
3316 | !(modifiers & ctk_accelerator_get_default_mod_mask ())) |
3317 | { |
3318 | CtkTreePath *anchor; |
3319 | CtkTreeIter iter; |
3320 | |
3321 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
3322 | ctk_tree_view_column_cell_set_cell_data (column, |
3323 | tree_view->priv->model, |
3324 | &iter, |
3325 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
3326 | node->children?TRUE(!(0)):FALSE(0)); |
3327 | |
3328 | if (tree_view->priv->anchor) |
3329 | anchor = ctk_tree_row_reference_get_path (tree_view->priv->anchor); |
3330 | else |
3331 | anchor = NULL((void*)0); |
3332 | |
3333 | if ((anchor && !ctk_tree_path_compare (anchor, path)) |
3334 | || !_ctk_tree_view_column_has_editable_cell (column)) |
3335 | { |
3336 | CtkCellEditable *cell_editable = NULL((void*)0); |
3337 | |
3338 | /* FIXME: get the right flags */ |
3339 | guint flags = 0; |
3340 | |
3341 | if (_ctk_tree_view_column_cell_event (column, |
3342 | (CdkEvent *)event, |
3343 | &cell_area, flags)) |
3344 | { |
3345 | CtkCellArea *area = ctk_cell_layout_get_area (CTK_CELL_LAYOUT (column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((column)), ((ctk_cell_layout_get_type ()))))))); |
3346 | cell_editable = ctk_cell_area_get_edit_widget (area); |
3347 | |
3348 | if (cell_editable != NULL((void*)0)) |
3349 | { |
3350 | ctk_tree_path_free (path); |
3351 | ctk_tree_path_free (anchor); |
3352 | return; |
3353 | } |
3354 | } |
3355 | } |
3356 | if (anchor) |
3357 | ctk_tree_path_free (anchor); |
3358 | } |
3359 | |
3360 | /* we only handle selection modifications on the first button press |
3361 | */ |
3362 | if (n_press == 1) |
3363 | { |
3364 | CtkCellRenderer *focus_cell; |
3365 | gboolean modify, extend; |
3366 | |
3367 | get_current_selection_modifiers (widget, &modify, &extend); |
3368 | tree_view->priv->modify_selection_pressed = modify; |
3369 | tree_view->priv->extend_selection_pressed = extend; |
3370 | |
3371 | /* We update the focus cell here, this is also needed if the |
3372 | * column does not contain an editable cell. In this case, |
3373 | * CtkCellArea did not receive the event for processing (and |
3374 | * could not update the focus cell). |
3375 | */ |
3376 | focus_cell = _ctk_tree_view_column_get_cell_at_pos (column, |
3377 | &cell_area, |
3378 | &background_area, |
3379 | bin_x, bin_y); |
3380 | |
3381 | if (focus_cell) |
3382 | ctk_tree_view_column_focus_cell (column, focus_cell); |
3383 | |
3384 | if (modify) |
3385 | { |
3386 | ctk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE); |
3387 | ctk_tree_view_real_toggle_cursor_row (tree_view); |
3388 | } |
3389 | else if (extend) |
3390 | { |
3391 | ctk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE); |
3392 | ctk_tree_view_real_select_cursor_row (tree_view, FALSE(0)); |
3393 | } |
3394 | else |
3395 | { |
3396 | ctk_tree_view_real_set_cursor (tree_view, path, CLEAR_AND_SELECT | CLAMP_NODE); |
3397 | } |
3398 | |
3399 | tree_view->priv->modify_selection_pressed = FALSE(0); |
3400 | tree_view->priv->extend_selection_pressed = FALSE(0); |
3401 | } |
3402 | |
3403 | if (button == CDK_BUTTON_PRIMARY(1) && n_press == 2) |
3404 | ctk_tree_view_row_activated (tree_view, path, column); |
3405 | else |
3406 | { |
3407 | if (n_press == 1) |
3408 | { |
3409 | tree_view->priv->button_pressed_node = tree_view->priv->prelight_node; |
3410 | tree_view->priv->button_pressed_tree = tree_view->priv->prelight_tree; |
3411 | } |
3412 | |
3413 | grab_focus_and_unset_draw_keyfocus (tree_view); |
3414 | } |
3415 | |
3416 | ctk_tree_path_free (path); |
3417 | |
3418 | if (n_press >= 2) |
3419 | ctk_event_controller_reset (CTK_EVENT_CONTROLLER (gesture)((((CtkEventController*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((gesture)), ((ctk_event_controller_get_type ()))))))); |
3420 | } |
3421 | |
3422 | static void |
3423 | ctk_tree_view_drag_gesture_begin (CtkGestureDrag *gesture, |
3424 | gdouble start_x, |
3425 | gdouble start_y, |
3426 | CtkTreeView *tree_view) |
3427 | { |
3428 | gint bin_x, bin_y; |
3429 | CtkRBTree *tree; |
3430 | CtkRBNode *node; |
3431 | |
3432 | if (tree_view->priv->tree == NULL((void*)0)) |
3433 | { |
3434 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_DENIED); |
3435 | return; |
3436 | } |
3437 | |
3438 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y, |
3439 | &bin_x, &bin_y); |
3440 | tree_view->priv->press_start_x = tree_view->priv->rubber_band_x = bin_x; |
3441 | tree_view->priv->press_start_y = tree_view->priv->rubber_band_y = bin_y; |
3442 | _ctk_rbtree_find_offset (tree_view->priv->tree, bin_y + tree_view->priv->dy, |
3443 | &tree, &node); |
3444 | |
3445 | if (tree_view->priv->rubber_banding_enable |
3446 | && !CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0)) |
3447 | && ctk_tree_selection_get_mode (tree_view->priv->selection) == CTK_SELECTION_MULTIPLE) |
3448 | { |
3449 | gboolean modify, extend; |
3450 | |
3451 | tree_view->priv->press_start_y += tree_view->priv->dy; |
3452 | tree_view->priv->rubber_band_y += tree_view->priv->dy; |
3453 | tree_view->priv->rubber_band_status = RUBBER_BAND_MAYBE_START; |
3454 | |
3455 | get_current_selection_modifiers (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &modify, &extend); |
3456 | tree_view->priv->rubber_band_modify = modify; |
3457 | tree_view->priv->rubber_band_extend = extend; |
3458 | } |
3459 | } |
3460 | |
3461 | static void |
3462 | ctk_tree_view_column_multipress_gesture_pressed (CtkGestureMultiPress *gesture, |
3463 | gint n_press, |
3464 | gdouble x G_GNUC_UNUSED__attribute__ ((__unused__)), |
3465 | gdouble y G_GNUC_UNUSED__attribute__ ((__unused__)), |
3466 | CtkTreeView *tree_view) |
3467 | { |
3468 | CdkEventSequence *sequence; |
3469 | CtkTreeViewColumn *column; |
3470 | const CdkEvent *event; |
3471 | GList *list; |
3472 | gint i; |
3473 | |
3474 | if (n_press != 2) |
3475 | return; |
3476 | |
3477 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
3478 | event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), sequence); |
3479 | |
3480 | for (i = 0, list = tree_view->priv->columns; list; list = list->next, i++) |
3481 | { |
3482 | column = list->data; |
3483 | |
3484 | if (event->any.window != _ctk_tree_view_column_get_window (column) || |
3485 | !ctk_tree_view_column_get_resizable (column)) |
3486 | continue; |
3487 | |
3488 | if (ctk_tree_view_column_get_sizing (column) != CTK_TREE_VIEW_COLUMN_AUTOSIZE) |
3489 | { |
3490 | ctk_tree_view_column_set_fixed_width (column, -1); |
3491 | ctk_tree_view_column_set_expand (column, FALSE(0)); |
3492 | _ctk_tree_view_column_autosize (tree_view, column); |
3493 | } |
3494 | |
3495 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_CLAIMED); |
3496 | break; |
3497 | } |
3498 | } |
3499 | |
3500 | static void |
3501 | ctk_tree_view_column_drag_gesture_begin (CtkGestureDrag *gesture, |
3502 | gdouble start_x, |
3503 | gdouble start_y G_GNUC_UNUSED__attribute__ ((__unused__)), |
3504 | CtkTreeView *tree_view) |
3505 | { |
3506 | CdkEventSequence *sequence; |
3507 | CtkTreeViewColumn *column; |
3508 | const CdkEvent *event; |
3509 | CdkWindow *window; |
3510 | gboolean rtl; |
3511 | GList *list; |
3512 | gint i; |
3513 | |
3514 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
3515 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
3516 | event = ctk_gesture_get_last_event (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), sequence); |
3517 | window = event->any.window; |
3518 | |
3519 | for (i = 0, list = tree_view->priv->columns; list; list = list->next, i++) |
3520 | { |
3521 | gpointer drag_data; |
3522 | gint column_width; |
3523 | |
3524 | column = list->data; |
3525 | |
3526 | if (window != _ctk_tree_view_column_get_window (column)) |
3527 | continue; |
3528 | |
3529 | if (!ctk_tree_view_column_get_resizable (column)) |
3530 | break; |
3531 | |
3532 | tree_view->priv->in_column_resize = TRUE(!(0)); |
3533 | |
3534 | /* block attached dnd signal handler */ |
3535 | drag_data = g_object_get_data (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), "ctk-site-data"); |
3536 | if (drag_data) |
3537 | g_signal_handlers_block_matched (tree_view, |
3538 | G_SIGNAL_MATCH_DATA, |
3539 | 0, 0, NULL((void*)0), NULL((void*)0), |
3540 | drag_data); |
3541 | |
3542 | column_width = ctk_tree_view_column_get_width (column); |
3543 | ctk_tree_view_column_set_fixed_width (column, column_width); |
3544 | ctk_tree_view_column_set_expand (column, FALSE(0)); |
3545 | |
3546 | tree_view->priv->drag_pos = i; |
3547 | tree_view->priv->x_drag = start_x + (rtl ? column_width : -column_width); |
3548 | |
3549 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
3550 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
3551 | |
3552 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_CLAIMED); |
3553 | return; |
3554 | } |
3555 | } |
3556 | |
3557 | static void |
3558 | ctk_tree_view_update_button_position (CtkTreeView *tree_view, |
3559 | CtkTreeViewColumn *column) |
3560 | { |
3561 | CtkTreeViewPrivate *priv = tree_view->priv; |
3562 | GList *column_el; |
3563 | |
3564 | column_el = g_list_find (priv->columns, column); |
3565 | g_return_if_fail (column_el != NULL)do { if ((column_el != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column_el != NULL"); return ; } } while (0); |
3566 | |
3567 | ctk_css_node_insert_after (priv->header_node, |
3568 | ctk_widget_get_css_node (ctk_tree_view_column_get_button (column)), |
3569 | column_el->prev ? ctk_widget_get_css_node ( |
3570 | ctk_tree_view_column_get_button (column_el->prev->data)) : NULL((void*)0)); |
3571 | } |
3572 | |
3573 | /* column drag gesture helper */ |
3574 | static gboolean |
3575 | ctk_tree_view_button_release_drag_column (CtkTreeView *tree_view) |
3576 | { |
3577 | CtkWidget *button, *widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
3578 | GList *l; |
3579 | gboolean rtl; |
3580 | CtkStyleContext *context; |
3581 | |
3582 | rtl = (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL); |
3583 | |
3584 | /* Move the button back */ |
3585 | button = ctk_tree_view_column_get_button (tree_view->priv->drag_column); |
3586 | |
3587 | context = ctk_widget_get_style_context (button); |
3588 | ctk_style_context_remove_class (context, CTK_STYLE_CLASS_DND"dnd"); |
3589 | |
3590 | g_object_ref (button)((__typeof__ (button)) (g_object_ref) (button)); |
3591 | ctk_container_remove (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ())))))), button); |
3592 | ctk_widget_set_parent_window (button, tree_view->priv->header_window); |
3593 | ctk_tree_view_update_button_position (tree_view, tree_view->priv->drag_column); |
3594 | ctk_widget_set_parent (button, CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
3595 | g_object_unref (button); |
3596 | ctk_widget_queue_resize (widget); |
3597 | if (ctk_tree_view_column_get_resizable (tree_view->priv->drag_column)) |
3598 | { |
3599 | cdk_window_raise (_ctk_tree_view_column_get_window (tree_view->priv->drag_column)); |
3600 | cdk_window_show (_ctk_tree_view_column_get_window (tree_view->priv->drag_column)); |
3601 | } |
3602 | else |
3603 | cdk_window_hide (_ctk_tree_view_column_get_window (tree_view->priv->drag_column)); |
3604 | |
3605 | ctk_widget_grab_focus (button); |
3606 | |
3607 | if (rtl) |
3608 | { |
3609 | if (tree_view->priv->cur_reorder && |
3610 | tree_view->priv->cur_reorder->right_column != tree_view->priv->drag_column) |
3611 | ctk_tree_view_move_column_after (tree_view, tree_view->priv->drag_column, |
3612 | tree_view->priv->cur_reorder->right_column); |
3613 | } |
3614 | else |
3615 | { |
3616 | if (tree_view->priv->cur_reorder && |
3617 | tree_view->priv->cur_reorder->left_column != tree_view->priv->drag_column) |
3618 | ctk_tree_view_move_column_after (tree_view, tree_view->priv->drag_column, |
3619 | tree_view->priv->cur_reorder->left_column); |
3620 | } |
3621 | tree_view->priv->drag_column = NULL((void*)0); |
3622 | ctk_widget_unregister_window (widget, tree_view->priv->drag_window); |
3623 | cdk_window_destroy (tree_view->priv->drag_window); |
3624 | tree_view->priv->drag_window = NULL((void*)0); |
3625 | |
3626 | for (l = tree_view->priv->column_drag_info; l != NULL((void*)0); l = l->next) |
3627 | g_slice_free (CtkTreeViewColumnReorder, l->data)do { if (1) g_slice_free1 (sizeof (CtkTreeViewColumnReorder), (l->data)); else (void) ((CtkTreeViewColumnReorder*) 0 == (l->data)); } while (0); |
3628 | g_list_free (tree_view->priv->column_drag_info); |
3629 | tree_view->priv->column_drag_info = NULL((void*)0); |
3630 | tree_view->priv->cur_reorder = NULL((void*)0); |
3631 | |
3632 | if (tree_view->priv->drag_highlight_window) |
3633 | cdk_window_hide (tree_view->priv->drag_highlight_window); |
3634 | |
3635 | /* Reset our flags */ |
3636 | tree_view->priv->drag_column_window_state = DRAG_COLUMN_WINDOW_STATE_UNSET; |
3637 | tree_view->priv->in_column_drag = FALSE(0); |
3638 | |
3639 | return TRUE(!(0)); |
3640 | } |
3641 | |
3642 | /* column drag gesture helper */ |
3643 | static gboolean |
3644 | ctk_tree_view_button_release_column_resize (CtkTreeView *tree_view) |
3645 | { |
3646 | gpointer drag_data; |
3647 | |
3648 | tree_view->priv->drag_pos = -1; |
3649 | |
3650 | /* unblock attached dnd signal handler */ |
3651 | drag_data = g_object_get_data (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), "ctk-site-data"); |
3652 | if (drag_data) |
3653 | g_signal_handlers_unblock_matched (tree_view, |
3654 | G_SIGNAL_MATCH_DATA, |
3655 | 0, 0, NULL((void*)0), NULL((void*)0), |
3656 | drag_data); |
3657 | |
3658 | tree_view->priv->in_column_resize = FALSE(0); |
3659 | return TRUE(!(0)); |
3660 | } |
3661 | |
3662 | static void |
3663 | ctk_tree_view_column_drag_gesture_end (CtkGestureDrag *gesture, |
3664 | gdouble offset_x G_GNUC_UNUSED__attribute__ ((__unused__)), |
3665 | gdouble offset_y G_GNUC_UNUSED__attribute__ ((__unused__)), |
3666 | CtkTreeView *tree_view) |
3667 | { |
3668 | CdkEventSequence *sequence; |
3669 | |
3670 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
3671 | |
3672 | /* Cancel reorder if the drag got cancelled */ |
3673 | if (!ctk_gesture_handles_sequence (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), sequence)) |
3674 | tree_view->priv->cur_reorder = NULL((void*)0); |
3675 | |
3676 | if (tree_view->priv->in_column_drag) |
3677 | { |
3678 | CdkDevice *device; |
3679 | |
3680 | ctk_tree_view_button_release_drag_column (tree_view); |
3681 | device = ctk_gesture_get_device (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ()))))))); |
3682 | cdk_seat_ungrab (cdk_device_get_seat (device)); |
3683 | } |
3684 | else if (tree_view->priv->in_column_resize) |
3685 | ctk_tree_view_button_release_column_resize (tree_view); |
3686 | } |
3687 | |
3688 | static void |
3689 | ctk_tree_view_drag_gesture_end (CtkGestureDrag *gesture G_GNUC_UNUSED__attribute__ ((__unused__)), |
3690 | gdouble offset_x G_GNUC_UNUSED__attribute__ ((__unused__)), |
3691 | gdouble offset_y G_GNUC_UNUSED__attribute__ ((__unused__)), |
3692 | CtkTreeView *tree_view) |
3693 | { |
3694 | ctk_tree_view_stop_rubber_band (tree_view); |
3695 | } |
3696 | |
3697 | static void |
3698 | ctk_tree_view_multipress_gesture_released (CtkGestureMultiPress *gesture, |
3699 | gint n_press G_GNUC_UNUSED__attribute__ ((__unused__)), |
3700 | gdouble x G_GNUC_UNUSED__attribute__ ((__unused__)), |
3701 | gdouble y G_GNUC_UNUSED__attribute__ ((__unused__)), |
3702 | CtkTreeView *tree_view) |
3703 | { |
3704 | gboolean modify, extend; |
3705 | guint button; |
3706 | |
3707 | button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
3708 | |
3709 | if (button != CDK_BUTTON_PRIMARY(1) || |
3710 | tree_view->priv->button_pressed_node == NULL((void*)0) || |
3711 | tree_view->priv->button_pressed_node != tree_view->priv->prelight_node) |
3712 | return; |
3713 | |
3714 | get_current_selection_modifiers (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &modify, &extend); |
3715 | |
3716 | if (tree_view->priv->arrow_prelit) |
3717 | { |
3718 | CtkTreePath *path = NULL((void*)0); |
3719 | |
3720 | path = _ctk_tree_path_new_from_rbtree (tree_view->priv->button_pressed_tree, |
3721 | tree_view->priv->button_pressed_node); |
3722 | /* Actually activate the node */ |
3723 | if (tree_view->priv->button_pressed_node->children == NULL((void*)0)) |
3724 | ctk_tree_view_real_expand_row (tree_view, path, |
3725 | tree_view->priv->button_pressed_tree, |
3726 | tree_view->priv->button_pressed_node, |
3727 | FALSE(0), TRUE(!(0))); |
3728 | else |
3729 | ctk_tree_view_real_collapse_row (tree_view, path, |
3730 | tree_view->priv->button_pressed_tree, |
3731 | tree_view->priv->button_pressed_node, TRUE(!(0))); |
3732 | ctk_tree_path_free (path); |
3733 | } |
3734 | else if (tree_view->priv->activate_on_single_click && !modify && !extend) |
3735 | { |
3736 | CtkTreePath *path = NULL((void*)0); |
3737 | |
3738 | path = _ctk_tree_path_new_from_rbtree (tree_view->priv->button_pressed_tree, |
3739 | tree_view->priv->button_pressed_node); |
3740 | ctk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column); |
3741 | ctk_tree_path_free (path); |
3742 | } |
3743 | |
3744 | tree_view->priv->button_pressed_tree = NULL((void*)0); |
3745 | tree_view->priv->button_pressed_node = NULL((void*)0); |
3746 | } |
3747 | |
3748 | /* CtkWidget::motion_event function set. |
3749 | */ |
3750 | |
3751 | static gboolean |
3752 | coords_are_over_arrow (CtkTreeView *tree_view, |
3753 | CtkRBTree *tree, |
3754 | CtkRBNode *node, |
3755 | /* these are in bin window coords */ |
3756 | gint x, |
3757 | gint y) |
3758 | { |
3759 | CdkRectangle arrow; |
3760 | gint x2; |
3761 | |
3762 | if (!ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
3763 | return FALSE(0); |
3764 | |
3765 | if ((node->flags & CTK_RBNODE_IS_PARENT) == 0) |
3766 | return FALSE(0); |
3767 | |
3768 | arrow.y = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
3769 | arrow.height = ctk_tree_view_get_row_height (tree_view, node); |
3770 | |
3771 | ctk_tree_view_get_arrow_xrange (tree_view, tree, &arrow.x, &x2); |
3772 | |
3773 | arrow.width = x2 - arrow.x; |
3774 | |
3775 | return (x >= arrow.x && |
3776 | x < (arrow.x + arrow.width) && |
3777 | y >= arrow.y && |
3778 | y < (arrow.y + arrow.height)); |
3779 | } |
3780 | |
3781 | static gboolean |
3782 | auto_expand_timeout (gpointer data) |
3783 | { |
3784 | CtkTreeView *tree_view = CTK_TREE_VIEW (data)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_view_get_type ())))))); |
3785 | CtkTreePath *path; |
3786 | |
3787 | if (tree_view->priv->prelight_node) |
3788 | { |
3789 | path = _ctk_tree_path_new_from_rbtree (tree_view->priv->prelight_tree, |
3790 | tree_view->priv->prelight_node); |
3791 | |
3792 | if (tree_view->priv->prelight_node->children) |
3793 | ctk_tree_view_collapse_row (tree_view, path); |
3794 | else |
3795 | ctk_tree_view_expand_row (tree_view, path, FALSE(0)); |
3796 | |
3797 | ctk_tree_path_free (path); |
3798 | } |
3799 | |
3800 | tree_view->priv->auto_expand_timeout = 0; |
3801 | |
3802 | return FALSE(0); |
3803 | } |
3804 | |
3805 | static void |
3806 | remove_auto_expand_timeout (CtkTreeView *tree_view) |
3807 | { |
3808 | if (tree_view->priv->auto_expand_timeout != 0) |
3809 | { |
3810 | g_source_remove (tree_view->priv->auto_expand_timeout); |
3811 | tree_view->priv->auto_expand_timeout = 0; |
3812 | } |
3813 | } |
3814 | |
3815 | static void |
3816 | do_prelight (CtkTreeView *tree_view, |
3817 | CtkRBTree *tree, |
3818 | CtkRBNode *node, |
3819 | /* these are in bin_window coords */ |
3820 | gint x, |
3821 | gint y) |
3822 | { |
3823 | if (tree_view->priv->prelight_tree == tree && |
3824 | tree_view->priv->prelight_node == node) |
3825 | { |
3826 | /* We are still on the same node, |
3827 | but we might need to take care of the arrow */ |
3828 | |
3829 | if (tree && node && ctk_tree_view_draw_expanders (tree_view)) |
3830 | { |
3831 | gboolean over_arrow; |
3832 | |
3833 | over_arrow = coords_are_over_arrow (tree_view, tree, node, x, y); |
3834 | |
3835 | if (over_arrow != tree_view->priv->arrow_prelit) |
3836 | { |
3837 | if (over_arrow) |
3838 | tree_view->priv->arrow_prelit = TRUE(!(0)); |
3839 | else |
3840 | tree_view->priv->arrow_prelit = FALSE(0); |
3841 | |
3842 | ctk_tree_view_queue_draw_arrow (tree_view, tree, node); |
3843 | } |
3844 | } |
3845 | |
3846 | return; |
3847 | } |
3848 | |
3849 | if (tree_view->priv->prelight_tree && tree_view->priv->prelight_node) |
3850 | { |
3851 | /* Unprelight the old node and arrow */ |
3852 | |
3853 | CTK_RBNODE_UNSET_FLAG (tree_view->priv->prelight_node,do{ (tree_view->priv->prelight_node->flags&=~(CTK_RBNODE_IS_PRELIT )); }while (0) |
3854 | CTK_RBNODE_IS_PRELIT)do{ (tree_view->priv->prelight_node->flags&=~(CTK_RBNODE_IS_PRELIT )); }while (0); |
3855 | |
3856 | if (tree_view->priv->arrow_prelit |
3857 | && ctk_tree_view_draw_expanders (tree_view)) |
3858 | { |
3859 | tree_view->priv->arrow_prelit = FALSE(0); |
3860 | |
3861 | ctk_tree_view_queue_draw_arrow (tree_view, |
3862 | tree_view->priv->prelight_tree, |
3863 | tree_view->priv->prelight_node); |
3864 | } |
3865 | |
3866 | _ctk_tree_view_queue_draw_node (tree_view, |
3867 | tree_view->priv->prelight_tree, |
3868 | tree_view->priv->prelight_node, |
3869 | NULL((void*)0)); |
3870 | } |
3871 | |
3872 | |
3873 | if (tree_view->priv->hover_expand) |
3874 | remove_auto_expand_timeout (tree_view); |
3875 | |
3876 | /* Set the new prelight values */ |
3877 | tree_view->priv->prelight_node = node; |
3878 | tree_view->priv->prelight_tree = tree; |
3879 | |
3880 | if (!node || !tree) |
3881 | return; |
3882 | |
3883 | /* Prelight the new node and arrow */ |
3884 | |
3885 | if (ctk_tree_view_draw_expanders (tree_view) |
3886 | && coords_are_over_arrow (tree_view, tree, node, x, y)) |
3887 | { |
3888 | tree_view->priv->arrow_prelit = TRUE(!(0)); |
3889 | |
3890 | ctk_tree_view_queue_draw_arrow (tree_view, tree, node); |
3891 | } |
3892 | |
3893 | CTK_RBNODE_SET_FLAG (node, CTK_RBNODE_IS_PRELIT)do{ (node->flags|=CTK_RBNODE_IS_PRELIT); }while (0); |
3894 | |
3895 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
3896 | |
3897 | if (tree_view->priv->hover_expand) |
3898 | { |
3899 | tree_view->priv->auto_expand_timeout = |
3900 | cdk_threads_add_timeout (AUTO_EXPAND_TIMEOUT500, auto_expand_timeout, tree_view); |
3901 | g_source_set_name_by_id (tree_view->priv->auto_expand_timeout, "[ctk+] auto_expand_timeout"); |
3902 | } |
3903 | } |
3904 | |
3905 | static void |
3906 | prelight_or_select (CtkTreeView *tree_view, |
3907 | CtkRBTree *tree, |
3908 | CtkRBNode *node, |
3909 | /* these are in bin_window coords */ |
3910 | gint x, |
3911 | gint y) |
3912 | { |
3913 | CtkSelectionMode mode = ctk_tree_selection_get_mode (tree_view->priv->selection); |
3914 | |
3915 | if (tree_view->priv->hover_selection && |
3916 | (mode == CTK_SELECTION_SINGLE || mode == CTK_SELECTION_BROWSE) && |
3917 | !(tree_view->priv->edited_column && |
3918 | ctk_cell_area_get_edit_widget |
3919 | (ctk_cell_layout_get_area (CTK_CELL_LAYOUT (tree_view->priv->edited_column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->edited_column)), ((ctk_cell_layout_get_type ())))))))))) |
3920 | { |
3921 | if (node) |
3922 | { |
3923 | if (!CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
3924 | { |
3925 | CtkTreePath *path; |
3926 | |
3927 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
3928 | ctk_tree_selection_select_path (tree_view->priv->selection, path); |
3929 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
3930 | { |
3931 | tree_view->priv->draw_keyfocus = FALSE(0); |
3932 | ctk_tree_view_real_set_cursor (tree_view, path, 0); |
3933 | } |
3934 | ctk_tree_path_free (path); |
3935 | } |
3936 | } |
3937 | |
3938 | else if (mode == CTK_SELECTION_SINGLE) |
3939 | ctk_tree_selection_unselect_all (tree_view->priv->selection); |
3940 | } |
3941 | |
3942 | do_prelight (tree_view, tree, node, x, y); |
3943 | } |
3944 | |
3945 | static void |
3946 | ensure_unprelighted (CtkTreeView *tree_view) |
3947 | { |
3948 | do_prelight (tree_view, |
3949 | NULL((void*)0), NULL((void*)0), |
3950 | -1000, -1000); /* coords not possibly over an arrow */ |
3951 | |
3952 | g_assert (tree_view->priv->prelight_node == NULL)do { if (tree_view->priv->prelight_node == ((void*)0)) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c", 3952, ((const char*) (__func__)), "tree_view->priv->prelight_node == NULL" ); } while (0); |
3953 | } |
3954 | |
3955 | static void |
3956 | update_prelight (CtkTreeView *tree_view, |
3957 | gint x, |
3958 | gint y) |
3959 | { |
3960 | int new_y; |
3961 | CtkRBTree *tree; |
3962 | CtkRBNode *node; |
3963 | |
3964 | if (tree_view->priv->tree == NULL((void*)0)) |
3965 | return; |
3966 | |
3967 | if (x == -10000) |
3968 | { |
3969 | ensure_unprelighted (tree_view); |
3970 | return; |
3971 | } |
3972 | |
3973 | new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y)((y) + tree_view->priv->dy); |
3974 | if (new_y < 0) |
3975 | new_y = 0; |
3976 | |
3977 | _ctk_rbtree_find_offset (tree_view->priv->tree, |
3978 | new_y, &tree, &node); |
3979 | |
3980 | if (node) |
3981 | prelight_or_select (tree_view, tree, node, x, y); |
3982 | } |
3983 | |
3984 | |
3985 | |
3986 | |
3987 | /* Our motion arrow is either a box (in the case of the original spot) |
3988 | * or an arrow. It is expander_size wide. |
3989 | */ |
3990 | /* |
3991 | * 11111111111111 |
3992 | * 01111111111110 |
3993 | * 00111111111100 |
3994 | * 00011111111000 |
3995 | * 00001111110000 |
3996 | * 00000111100000 |
3997 | * 00000111100000 |
3998 | * 00000111100000 |
3999 | * ~ ~ ~ ~ ~ ~ ~ |
4000 | * 00000111100000 |
4001 | * 00000111100000 |
4002 | * 00000111100000 |
4003 | * 00001111110000 |
4004 | * 00011111111000 |
4005 | * 00111111111100 |
4006 | * 01111111111110 |
4007 | * 11111111111111 |
4008 | */ |
4009 | |
4010 | static void |
4011 | ctk_tree_view_motion_draw_column_motion_arrow (CtkTreeView *tree_view) |
4012 | { |
4013 | CtkTreeViewColumnReorder *reorder = tree_view->priv->cur_reorder; |
4014 | CtkWidget *widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
4015 | cairo_surface_t *mask_image; |
4016 | cairo_region_t *mask_region; |
4017 | gint x; |
4018 | gint y; |
4019 | gint width; |
4020 | gint height; |
4021 | gint arrow_type = DRAG_COLUMN_WINDOW_STATE_UNSET; |
4022 | CdkWindowAttr attributes; |
4023 | guint attributes_mask; |
4024 | cairo_t *cr; |
4025 | |
4026 | if (!reorder || |
4027 | reorder->left_column == tree_view->priv->drag_column || |
4028 | reorder->right_column == tree_view->priv->drag_column) |
4029 | arrow_type = DRAG_COLUMN_WINDOW_STATE_ORIGINAL; |
4030 | else if (reorder->left_column || reorder->right_column) |
4031 | { |
4032 | CtkAllocation left_allocation, right_allocation; |
4033 | CdkRectangle visible_rect; |
4034 | CtkWidget *button; |
4035 | |
4036 | ctk_tree_view_get_visible_rect (tree_view, &visible_rect); |
4037 | if (reorder->left_column) |
4038 | { |
4039 | button = ctk_tree_view_column_get_button (reorder->left_column); |
4040 | ctk_widget_get_allocation (button, &left_allocation); |
4041 | x = left_allocation.x + left_allocation.width; |
4042 | } |
4043 | else |
4044 | { |
4045 | button = ctk_tree_view_column_get_button (reorder->right_column); |
4046 | ctk_widget_get_allocation (button, &right_allocation); |
4047 | x = right_allocation.x; |
4048 | } |
4049 | |
4050 | if (x < visible_rect.x) |
4051 | arrow_type = DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT; |
4052 | else if (x > visible_rect.x + visible_rect.width) |
4053 | arrow_type = DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT; |
4054 | else |
4055 | arrow_type = DRAG_COLUMN_WINDOW_STATE_ARROW; |
4056 | } |
4057 | |
4058 | /* We want to draw the rectangle over the initial location. */ |
4059 | if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ORIGINAL) |
4060 | { |
4061 | if (tree_view->priv->drag_column_window_state != DRAG_COLUMN_WINDOW_STATE_ORIGINAL) |
4062 | { |
4063 | CtkAllocation drag_allocation; |
4064 | CtkWidget *button; |
4065 | |
4066 | if (tree_view->priv->drag_highlight_window) |
4067 | { |
4068 | ctk_widget_unregister_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
4069 | cdk_window_destroy (tree_view->priv->drag_highlight_window); |
4070 | } |
4071 | |
4072 | button = ctk_tree_view_column_get_button (tree_view->priv->drag_column); |
4073 | attributes.window_type = CDK_WINDOW_CHILD; |
4074 | attributes.wclass = CDK_INPUT_OUTPUT; |
4075 | attributes.x = tree_view->priv->drag_column_x; |
4076 | attributes.y = 0; |
4077 | ctk_widget_get_allocation (button, &drag_allocation); |
4078 | width = attributes.width = drag_allocation.width; |
4079 | height = attributes.height = drag_allocation.height; |
Value stored to 'height' is never read | |
4080 | attributes.visual = cdk_screen_get_rgba_visual (ctk_widget_get_screen (widget)); |
4081 | attributes.event_mask = CDK_VISIBILITY_NOTIFY_MASK | CDK_POINTER_MOTION_MASK; |
4082 | attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL; |
4083 | tree_view->priv->drag_highlight_window = cdk_window_new (tree_view->priv->header_window, &attributes, attributes_mask); |
4084 | ctk_widget_register_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
4085 | |
4086 | tree_view->priv->drag_column_window_state = DRAG_COLUMN_WINDOW_STATE_ORIGINAL; |
4087 | } |
4088 | } |
4089 | else if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW) |
4090 | { |
4091 | CtkAllocation button_allocation; |
4092 | CtkWidget *button; |
4093 | |
4094 | width = ctk_tree_view_get_expander_size (tree_view); |
4095 | |
4096 | /* Get x, y, width, height of arrow */ |
4097 | cdk_window_get_origin (tree_view->priv->header_window, &x, &y); |
4098 | if (reorder->left_column) |
4099 | { |
4100 | button = ctk_tree_view_column_get_button (reorder->left_column); |
4101 | ctk_widget_get_allocation (button, &button_allocation); |
4102 | x += button_allocation.x + button_allocation.width - width/2; |
4103 | height = button_allocation.height; |
4104 | } |
4105 | else |
4106 | { |
4107 | button = ctk_tree_view_column_get_button (reorder->right_column); |
4108 | ctk_widget_get_allocation (button, &button_allocation); |
4109 | x += button_allocation.x - width/2; |
4110 | height = button_allocation.height; |
4111 | } |
4112 | y -= width/2; /* The arrow takes up only half the space */ |
4113 | height += width; |
4114 | |
4115 | /* Create the new window */ |
4116 | if (tree_view->priv->drag_column_window_state != DRAG_COLUMN_WINDOW_STATE_ARROW) |
4117 | { |
4118 | if (tree_view->priv->drag_highlight_window) |
4119 | { |
4120 | ctk_widget_unregister_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
4121 | cdk_window_destroy (tree_view->priv->drag_highlight_window); |
4122 | } |
4123 | |
4124 | attributes.window_type = CDK_WINDOW_TEMP; |
4125 | attributes.wclass = CDK_INPUT_OUTPUT; |
4126 | attributes.visual = ctk_widget_get_visual (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
4127 | attributes.event_mask = CDK_VISIBILITY_NOTIFY_MASK | CDK_POINTER_MOTION_MASK; |
4128 | attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL; |
4129 | attributes.x = x; |
4130 | attributes.y = y; |
4131 | attributes.width = width; |
4132 | attributes.height = height; |
4133 | tree_view->priv->drag_highlight_window = cdk_window_new (cdk_screen_get_root_window (ctk_widget_get_screen (widget)), |
4134 | &attributes, attributes_mask); |
4135 | ctk_widget_register_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
4136 | |
4137 | mask_image = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height); |
4138 | |
4139 | cr = cairo_create (mask_image); |
4140 | cairo_move_to (cr, 0, 0); |
4141 | cairo_line_to (cr, width, 0); |
4142 | cairo_line_to (cr, width / 2., width / 2); |
4143 | cairo_move_to (cr, 0, height); |
4144 | cairo_line_to (cr, width, height); |
4145 | cairo_line_to (cr, width / 2., height - width / 2.); |
4146 | cairo_fill (cr); |
4147 | cairo_destroy (cr); |
4148 | |
4149 | mask_region = cdk_cairo_region_create_from_surface (mask_image); |
4150 | cdk_window_shape_combine_region (tree_view->priv->drag_highlight_window, |
4151 | mask_region, 0, 0); |
4152 | |
4153 | cairo_region_destroy (mask_region); |
4154 | cairo_surface_destroy (mask_image); |
4155 | } |
4156 | |
4157 | tree_view->priv->drag_column_window_state = DRAG_COLUMN_WINDOW_STATE_ARROW; |
4158 | cdk_window_move (tree_view->priv->drag_highlight_window, x, y); |
4159 | } |
4160 | else if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT || |
4161 | arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT) |
4162 | { |
4163 | CtkAllocation allocation; |
4164 | CtkWidget *button; |
4165 | gint expander_size; |
4166 | |
4167 | expander_size = ctk_tree_view_get_expander_size (tree_view); |
4168 | |
4169 | /* Get x, y, width, height of arrow */ |
4170 | width = expander_size/2; /* remember, the arrow only takes half the available width */ |
4171 | cdk_window_get_origin (ctk_widget_get_window (widget), |
4172 | &x, &y); |
4173 | if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT) |
4174 | { |
4175 | ctk_widget_get_allocation (widget, &allocation); |
4176 | x += allocation.width - width; |
4177 | } |
4178 | |
4179 | if (reorder->left_column) |
4180 | { |
4181 | button = ctk_tree_view_column_get_button (reorder->left_column); |
4182 | ctk_widget_get_allocation (button, &allocation); |
4183 | height = allocation.height; |
4184 | } |
4185 | else |
4186 | { |
4187 | button = ctk_tree_view_column_get_button (reorder->right_column); |
4188 | ctk_widget_get_allocation (button, &allocation); |
4189 | height = allocation.height; |
4190 | } |
4191 | |
4192 | y -= expander_size; |
4193 | height += 2 * expander_size; |
4194 | |
4195 | /* Create the new window */ |
4196 | if (tree_view->priv->drag_column_window_state != DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT && |
4197 | tree_view->priv->drag_column_window_state != DRAG_COLUMN_WINDOW_STATE_ARROW_RIGHT) |
4198 | { |
4199 | if (tree_view->priv->drag_highlight_window) |
4200 | { |
4201 | ctk_widget_unregister_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
4202 | cdk_window_destroy (tree_view->priv->drag_highlight_window); |
4203 | } |
4204 | |
4205 | attributes.window_type = CDK_WINDOW_TEMP; |
4206 | attributes.wclass = CDK_INPUT_OUTPUT; |
4207 | attributes.visual = ctk_widget_get_visual (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
4208 | attributes.event_mask = CDK_VISIBILITY_NOTIFY_MASK | CDK_POINTER_MOTION_MASK; |
4209 | attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL; |
4210 | attributes.x = x; |
4211 | attributes.y = y; |
4212 | attributes.width = width; |
4213 | attributes.height = height; |
4214 | tree_view->priv->drag_highlight_window = cdk_window_new (cdk_screen_get_root_window (ctk_widget_get_screen (widget)), &attributes, attributes_mask); |
4215 | ctk_widget_register_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
4216 | |
4217 | mask_image = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height); |
4218 | |
4219 | cr = cairo_create (mask_image); |
4220 | /* mirror if we're on the left */ |
4221 | if (arrow_type == DRAG_COLUMN_WINDOW_STATE_ARROW_LEFT) |
4222 | { |
4223 | cairo_translate (cr, width, 0); |
4224 | cairo_scale (cr, -1, 1); |
4225 | } |
4226 | cairo_move_to (cr, 0, 0); |
4227 | cairo_line_to (cr, width, width); |
4228 | cairo_line_to (cr, 0, expander_size); |
4229 | cairo_move_to (cr, 0, height); |
4230 | cairo_line_to (cr, width, height - width); |
4231 | cairo_line_to (cr, 0, height - expander_size); |
4232 | cairo_fill (cr); |
4233 | cairo_destroy (cr); |
4234 | |
4235 | mask_region = cdk_cairo_region_create_from_surface (mask_image); |
4236 | cdk_window_shape_combine_region (tree_view->priv->drag_highlight_window, |
4237 | mask_region, 0, 0); |
4238 | |
4239 | cairo_region_destroy (mask_region); |
4240 | cairo_surface_destroy (mask_image); |
4241 | } |
4242 | |
4243 | tree_view->priv->drag_column_window_state = arrow_type; |
4244 | cdk_window_move (tree_view->priv->drag_highlight_window, x, y); |
4245 | } |
4246 | else |
4247 | { |
4248 | g_warning (G_STRLOC"ctktreeview.c" ":" "4248""Invalid CtkTreeViewColumnReorder struct"); |
4249 | cdk_window_hide (tree_view->priv->drag_highlight_window); |
4250 | return; |
4251 | } |
4252 | |
4253 | cdk_window_show (tree_view->priv->drag_highlight_window); |
4254 | cdk_window_raise (tree_view->priv->drag_highlight_window); |
4255 | } |
4256 | |
4257 | static gboolean |
4258 | ctk_tree_view_motion_resize_column (CtkTreeView *tree_view, |
4259 | gdouble x, |
4260 | gdouble y G_GNUC_UNUSED__attribute__ ((__unused__))) |
4261 | { |
4262 | gint new_width; |
4263 | CtkTreeViewColumn *column; |
4264 | |
4265 | column = ctk_tree_view_get_column (tree_view, tree_view->priv->drag_pos); |
4266 | |
4267 | if (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL) |
4268 | new_width = MAX (tree_view->priv->x_drag - x, 0)(((tree_view->priv->x_drag - x) > (0)) ? (tree_view-> priv->x_drag - x) : (0)); |
4269 | else |
4270 | new_width = MAX (x - tree_view->priv->x_drag, 0)(((x - tree_view->priv->x_drag) > (0)) ? (x - tree_view ->priv->x_drag) : (0)); |
4271 | |
4272 | if (new_width != ctk_tree_view_column_get_fixed_width (column)) |
4273 | ctk_tree_view_column_set_fixed_width (column, new_width); |
4274 | |
4275 | return FALSE(0); |
4276 | } |
4277 | |
4278 | static void |
4279 | ctk_tree_view_update_current_reorder (CtkTreeView *tree_view) |
4280 | { |
4281 | CtkTreeViewColumnReorder *reorder = NULL((void*)0); |
4282 | CdkEventSequence *sequence; |
4283 | GList *list; |
4284 | gdouble x; |
4285 | |
4286 | sequence = ctk_gesture_single_get_current_sequence |
4287 | (CTK_GESTURE_SINGLE (tree_view->priv->column_drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((tree_view->priv->column_drag_gesture) ), ((ctk_gesture_single_get_type ()))))))); |
4288 | ctk_gesture_get_point (tree_view->priv->column_drag_gesture, |
4289 | sequence, &x, NULL((void*)0)); |
4290 | x += ctk_adjustment_get_value (tree_view->priv->hadjustment); |
4291 | |
4292 | for (list = tree_view->priv->column_drag_info; list; list = list->next) |
4293 | { |
4294 | reorder = (CtkTreeViewColumnReorder *) list->data; |
4295 | if (x >= reorder->left_align && x < reorder->right_align) |
4296 | break; |
4297 | reorder = NULL((void*)0); |
4298 | } |
4299 | |
4300 | tree_view->priv->cur_reorder = reorder; |
4301 | ctk_tree_view_motion_draw_column_motion_arrow (tree_view); |
4302 | } |
4303 | |
4304 | static void |
4305 | ctk_tree_view_vertical_autoscroll (CtkTreeView *tree_view) |
4306 | { |
4307 | CdkRectangle visible_rect; |
4308 | gint y; |
4309 | gint offset; |
4310 | |
4311 | if (ctk_gesture_is_recognized (tree_view->priv->drag_gesture)) |
4312 | { |
4313 | CdkEventSequence *sequence; |
4314 | gdouble py; |
4315 | |
4316 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (tree_view->priv->drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((tree_view->priv->drag_gesture)), ((ctk_gesture_single_get_type ()))))))); |
4317 | ctk_gesture_get_point (tree_view->priv->drag_gesture, sequence, NULL((void*)0), &py); |
4318 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, 0, py, |
4319 | NULL((void*)0), &y); |
4320 | } |
4321 | else |
4322 | { |
4323 | y = tree_view->priv->event_last_y; |
4324 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, 0, y, NULL((void*)0), &y); |
4325 | } |
4326 | |
4327 | y += tree_view->priv->dy; |
4328 | ctk_tree_view_get_visible_rect (tree_view, &visible_rect); |
4329 | |
4330 | /* see if we are near the edge. */ |
4331 | offset = y - (visible_rect.y + 2 * SCROLL_EDGE_SIZE15); |
4332 | if (offset > 0) |
4333 | { |
4334 | offset = y - (visible_rect.y + visible_rect.height - 2 * SCROLL_EDGE_SIZE15); |
4335 | if (offset < 0) |
4336 | return; |
4337 | } |
4338 | |
4339 | ctk_adjustment_set_value (tree_view->priv->vadjustment, |
4340 | MAX (ctk_adjustment_get_value (tree_view->priv->vadjustment) + offset, 0.0)(((ctk_adjustment_get_value (tree_view->priv->vadjustment ) + offset) > (0.0)) ? (ctk_adjustment_get_value (tree_view ->priv->vadjustment) + offset) : (0.0))); |
4341 | } |
4342 | |
4343 | static gboolean |
4344 | ctk_tree_view_horizontal_autoscroll (CtkTreeView *tree_view) |
4345 | { |
4346 | CdkEventSequence *sequence; |
4347 | CdkRectangle visible_rect; |
4348 | gdouble x; |
4349 | gint offset; |
4350 | |
4351 | sequence = ctk_gesture_single_get_current_sequence |
4352 | (CTK_GESTURE_SINGLE (tree_view->priv->column_drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((tree_view->priv->column_drag_gesture) ), ((ctk_gesture_single_get_type ()))))))); |
4353 | ctk_gesture_get_point (tree_view->priv->column_drag_gesture, |
4354 | sequence, &x, NULL((void*)0)); |
4355 | ctk_tree_view_get_visible_rect (tree_view, &visible_rect); |
4356 | |
4357 | x += ctk_adjustment_get_value (tree_view->priv->hadjustment); |
4358 | |
4359 | /* See if we are near the edge. */ |
4360 | offset = x - (visible_rect.x + SCROLL_EDGE_SIZE15); |
4361 | if (offset > 0) |
4362 | { |
4363 | offset = x - (visible_rect.x + visible_rect.width - SCROLL_EDGE_SIZE15); |
4364 | if (offset < 0) |
4365 | return TRUE(!(0)); |
4366 | } |
4367 | offset = offset/3; |
4368 | |
4369 | ctk_adjustment_set_value (tree_view->priv->hadjustment, |
4370 | MAX (ctk_adjustment_get_value (tree_view->priv->hadjustment) + offset, 0.0)(((ctk_adjustment_get_value (tree_view->priv->hadjustment ) + offset) > (0.0)) ? (ctk_adjustment_get_value (tree_view ->priv->hadjustment) + offset) : (0.0))); |
4371 | |
4372 | return TRUE(!(0)); |
4373 | |
4374 | } |
4375 | |
4376 | static gboolean |
4377 | ctk_tree_view_motion_drag_column (CtkTreeView *tree_view, |
4378 | gdouble x, |
4379 | gdouble y G_GNUC_UNUSED__attribute__ ((__unused__))) |
4380 | { |
4381 | CtkAllocation allocation, button_allocation; |
4382 | CtkTreeViewColumn *column = tree_view->priv->drag_column; |
4383 | CtkWidget *button; |
4384 | gint win_x, win_y; |
4385 | |
4386 | button = ctk_tree_view_column_get_button (column); |
4387 | x += ctk_adjustment_get_value (tree_view->priv->hadjustment); |
4388 | |
4389 | /* Handle moving the header */ |
4390 | cdk_window_get_position (tree_view->priv->drag_window, &win_x, &win_y); |
4391 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
4392 | ctk_widget_get_allocation (button, &button_allocation); |
4393 | win_x = CLAMP (x - _ctk_tree_view_column_get_drag_x (column), 0,(((x - _ctk_tree_view_column_get_drag_x (column)) > ((((tree_view ->priv->width) > (allocation.width)) ? (tree_view-> priv->width) : (allocation.width)) - button_allocation.width )) ? ((((tree_view->priv->width) > (allocation.width )) ? (tree_view->priv->width) : (allocation.width)) - button_allocation .width) : (((x - _ctk_tree_view_column_get_drag_x (column)) < (0)) ? (0) : (x - _ctk_tree_view_column_get_drag_x (column)) )) |
4394 | MAX (tree_view->priv->width, allocation.width) - button_allocation.width)(((x - _ctk_tree_view_column_get_drag_x (column)) > ((((tree_view ->priv->width) > (allocation.width)) ? (tree_view-> priv->width) : (allocation.width)) - button_allocation.width )) ? ((((tree_view->priv->width) > (allocation.width )) ? (tree_view->priv->width) : (allocation.width)) - button_allocation .width) : (((x - _ctk_tree_view_column_get_drag_x (column)) < (0)) ? (0) : (x - _ctk_tree_view_column_get_drag_x (column)) )); |
4395 | cdk_window_move (tree_view->priv->drag_window, win_x, win_y); |
4396 | cdk_window_raise (tree_view->priv->drag_window); |
4397 | |
4398 | /* autoscroll, if needed */ |
4399 | ctk_tree_view_horizontal_autoscroll (tree_view); |
4400 | /* Update the current reorder position and arrow; */ |
4401 | ctk_tree_view_update_current_reorder (tree_view); |
4402 | |
4403 | return TRUE(!(0)); |
4404 | } |
4405 | |
4406 | static void |
4407 | ctk_tree_view_stop_rubber_band (CtkTreeView *tree_view) |
4408 | { |
4409 | remove_scroll_timeout (tree_view); |
4410 | |
4411 | if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE) |
4412 | { |
4413 | CtkTreePath *tmp_path; |
4414 | |
4415 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
4416 | |
4417 | /* The anchor path should be set to the start path */ |
4418 | if (tree_view->priv->rubber_band_start_node) |
4419 | { |
4420 | tmp_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->rubber_band_start_tree, |
4421 | tree_view->priv->rubber_band_start_node); |
4422 | |
4423 | if (tree_view->priv->anchor) |
4424 | ctk_tree_row_reference_free (tree_view->priv->anchor); |
4425 | |
4426 | tree_view->priv->anchor = |
4427 | ctk_tree_row_reference_new_proxy (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), |
4428 | tree_view->priv->model, |
4429 | tmp_path); |
4430 | |
4431 | ctk_tree_path_free (tmp_path); |
4432 | } |
4433 | |
4434 | /* ... and the cursor to the end path */ |
4435 | if (tree_view->priv->rubber_band_end_node) |
4436 | { |
4437 | tmp_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->rubber_band_end_tree, |
4438 | tree_view->priv->rubber_band_end_node); |
4439 | ctk_tree_view_real_set_cursor (CTK_TREE_VIEW (tree_view)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_tree_view_get_type ())))))), tmp_path, 0); |
4440 | ctk_tree_path_free (tmp_path); |
4441 | } |
4442 | |
4443 | _ctk_tree_selection_emit_changed (tree_view->priv->selection); |
4444 | |
4445 | ctk_css_node_set_parent (tree_view->priv->rubber_band_cssnode, NULL((void*)0)); |
4446 | tree_view->priv->rubber_band_cssnode = NULL((void*)0); |
4447 | } |
4448 | |
4449 | /* Clear status variables */ |
4450 | tree_view->priv->rubber_band_status = RUBBER_BAND_OFF; |
4451 | tree_view->priv->rubber_band_extend = FALSE(0); |
4452 | tree_view->priv->rubber_band_modify = FALSE(0); |
4453 | |
4454 | tree_view->priv->rubber_band_start_node = NULL((void*)0); |
4455 | tree_view->priv->rubber_band_start_tree = NULL((void*)0); |
4456 | tree_view->priv->rubber_band_end_node = NULL((void*)0); |
4457 | tree_view->priv->rubber_band_end_tree = NULL((void*)0); |
4458 | } |
4459 | |
4460 | static void |
4461 | ctk_tree_view_update_rubber_band_selection_range (CtkTreeView *tree_view, |
4462 | CtkRBTree *start_tree, |
4463 | CtkRBNode *start_node, |
4464 | CtkRBTree *end_tree G_GNUC_UNUSED__attribute__ ((__unused__)), |
4465 | CtkRBNode *end_node, |
4466 | gboolean select, |
4467 | gboolean skip_start, |
4468 | gboolean skip_end) |
4469 | { |
4470 | if (start_node == end_node) |
4471 | return; |
4472 | |
4473 | /* We skip the first node and jump inside the loop */ |
4474 | if (skip_start) |
4475 | goto skip_first; |
4476 | |
4477 | do |
4478 | { |
4479 | /* Small optimization by assuming insensitive nodes are never |
4480 | * selected. |
4481 | */ |
4482 | if (!CTK_RBNODE_FLAG_SET (start_node, CTK_RBNODE_IS_SELECTED)(start_node?(((start_node->flags&CTK_RBNODE_IS_SELECTED )==CTK_RBNODE_IS_SELECTED)?(!(0)):(0)):(0))) |
4483 | { |
4484 | CtkTreePath *path; |
4485 | gboolean selectable; |
4486 | |
4487 | path = _ctk_tree_path_new_from_rbtree (start_tree, start_node); |
4488 | selectable = _ctk_tree_selection_row_is_selectable (tree_view->priv->selection, start_node, path); |
4489 | ctk_tree_path_free (path); |
4490 | |
4491 | if (!selectable) |
4492 | goto node_not_selectable; |
4493 | } |
4494 | |
4495 | if (select) |
4496 | { |
4497 | if (tree_view->priv->rubber_band_extend) |
4498 | CTK_RBNODE_SET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags|=CTK_RBNODE_IS_SELECTED); }while (0 ); |
4499 | else if (tree_view->priv->rubber_band_modify) |
4500 | { |
4501 | /* Toggle the selection state */ |
4502 | if (CTK_RBNODE_FLAG_SET (start_node, CTK_RBNODE_IS_SELECTED)(start_node?(((start_node->flags&CTK_RBNODE_IS_SELECTED )==CTK_RBNODE_IS_SELECTED)?(!(0)):(0)):(0))) |
4503 | CTK_RBNODE_UNSET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags&=~(CTK_RBNODE_IS_SELECTED)); }while (0); |
4504 | else |
4505 | CTK_RBNODE_SET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags|=CTK_RBNODE_IS_SELECTED); }while (0 ); |
4506 | } |
4507 | else |
4508 | CTK_RBNODE_SET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags|=CTK_RBNODE_IS_SELECTED); }while (0 ); |
4509 | } |
4510 | else |
4511 | { |
4512 | /* Mirror the above */ |
4513 | if (tree_view->priv->rubber_band_extend) |
4514 | CTK_RBNODE_UNSET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags&=~(CTK_RBNODE_IS_SELECTED)); }while (0); |
4515 | else if (tree_view->priv->rubber_band_modify) |
4516 | { |
4517 | /* Toggle the selection state */ |
4518 | if (CTK_RBNODE_FLAG_SET (start_node, CTK_RBNODE_IS_SELECTED)(start_node?(((start_node->flags&CTK_RBNODE_IS_SELECTED )==CTK_RBNODE_IS_SELECTED)?(!(0)):(0)):(0))) |
4519 | CTK_RBNODE_UNSET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags&=~(CTK_RBNODE_IS_SELECTED)); }while (0); |
4520 | else |
4521 | CTK_RBNODE_SET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags|=CTK_RBNODE_IS_SELECTED); }while (0 ); |
4522 | } |
4523 | else |
4524 | CTK_RBNODE_UNSET_FLAG (start_node, CTK_RBNODE_IS_SELECTED)do{ (start_node->flags&=~(CTK_RBNODE_IS_SELECTED)); }while (0); |
4525 | } |
4526 | |
4527 | _ctk_tree_view_queue_draw_node (tree_view, start_tree, start_node, NULL((void*)0)); |
4528 | |
4529 | node_not_selectable: |
4530 | if (start_node == end_node) |
4531 | break; |
4532 | |
4533 | skip_first: |
4534 | |
4535 | if (start_node->children) |
4536 | { |
4537 | start_tree = start_node->children; |
4538 | start_node = _ctk_rbtree_first (start_tree); |
4539 | } |
4540 | else |
4541 | { |
4542 | _ctk_rbtree_next_full (start_tree, start_node, &start_tree, &start_node); |
4543 | |
4544 | if (!start_tree) |
4545 | /* Ran out of tree */ |
4546 | break; |
4547 | } |
4548 | |
4549 | if (skip_end && start_node == end_node) |
4550 | break; |
4551 | } |
4552 | while (TRUE(!(0))); |
4553 | } |
4554 | |
4555 | static void |
4556 | ctk_tree_view_update_rubber_band_selection (CtkTreeView *tree_view) |
4557 | { |
4558 | CtkRBTree *start_tree, *end_tree; |
4559 | CtkRBNode *start_node, *end_node; |
4560 | gdouble start_y, offset_y; |
4561 | gint bin_y; |
4562 | |
4563 | if (!ctk_gesture_is_active (tree_view->priv->drag_gesture)) |
4564 | return; |
4565 | |
4566 | ctk_gesture_drag_get_offset (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
4567 | NULL((void*)0), &offset_y); |
4568 | ctk_gesture_drag_get_start_point (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
4569 | NULL((void*)0), &start_y); |
4570 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, 0, start_y, |
4571 | NULL((void*)0), &bin_y); |
4572 | bin_y = MAX (0, bin_y + offset_y + tree_view->priv->dy)(((0) > (bin_y + offset_y + tree_view->priv->dy)) ? ( 0) : (bin_y + offset_y + tree_view->priv->dy)); |
4573 | |
4574 | _ctk_rbtree_find_offset (tree_view->priv->tree, MIN (tree_view->priv->press_start_y, bin_y)(((tree_view->priv->press_start_y) < (bin_y)) ? (tree_view ->priv->press_start_y) : (bin_y)), &start_tree, &start_node); |
4575 | _ctk_rbtree_find_offset (tree_view->priv->tree, MAX (tree_view->priv->press_start_y, bin_y)(((tree_view->priv->press_start_y) > (bin_y)) ? (tree_view ->priv->press_start_y) : (bin_y)), &end_tree, &end_node); |
4576 | |
4577 | /* Handle the start area first */ |
4578 | if (!start_node && !end_node) |
4579 | { |
4580 | if (tree_view->priv->rubber_band_start_node) |
4581 | { |
4582 | CtkRBNode *node = tree_view->priv->rubber_band_start_node; |
4583 | CtkRBTree *tree = tree_view->priv->rubber_band_start_tree; |
4584 | |
4585 | if (tree_view->priv->rubber_band_modify) |
4586 | { |
4587 | /* Toggle the selection state */ |
4588 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
4589 | CTK_RBNODE_UNSET_FLAG (node, CTK_RBNODE_IS_SELECTED)do{ (node->flags&=~(CTK_RBNODE_IS_SELECTED)); }while ( 0); |
4590 | else |
4591 | CTK_RBNODE_SET_FLAG (node, CTK_RBNODE_IS_SELECTED)do{ (node->flags|=CTK_RBNODE_IS_SELECTED); }while (0); |
4592 | } |
4593 | else |
4594 | CTK_RBNODE_UNSET_FLAG (node, CTK_RBNODE_IS_SELECTED)do{ (node->flags&=~(CTK_RBNODE_IS_SELECTED)); }while ( 0); |
4595 | |
4596 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
4597 | } |
4598 | } |
4599 | if (!tree_view->priv->rubber_band_start_node || !start_node) |
4600 | { |
4601 | ctk_tree_view_update_rubber_band_selection_range (tree_view, |
4602 | start_tree, |
4603 | start_node, |
4604 | end_tree, |
4605 | end_node, |
4606 | TRUE(!(0)), |
4607 | FALSE(0), |
4608 | FALSE(0)); |
4609 | } |
4610 | else if (_ctk_rbtree_node_find_offset (start_tree, start_node) < |
4611 | _ctk_rbtree_node_find_offset (tree_view->priv->rubber_band_start_tree, tree_view->priv->rubber_band_start_node)) |
4612 | { |
4613 | /* New node is above the old one; selection became bigger */ |
4614 | ctk_tree_view_update_rubber_band_selection_range (tree_view, |
4615 | start_tree, |
4616 | start_node, |
4617 | tree_view->priv->rubber_band_start_tree, |
4618 | tree_view->priv->rubber_band_start_node, |
4619 | TRUE(!(0)), |
4620 | FALSE(0), |
4621 | TRUE(!(0))); |
4622 | } |
4623 | else if (_ctk_rbtree_node_find_offset (start_tree, start_node) > |
4624 | _ctk_rbtree_node_find_offset (tree_view->priv->rubber_band_start_tree, tree_view->priv->rubber_band_start_node)) |
4625 | { |
4626 | /* New node is below the old one; selection became smaller */ |
4627 | ctk_tree_view_update_rubber_band_selection_range (tree_view, |
4628 | tree_view->priv->rubber_band_start_tree, |
4629 | tree_view->priv->rubber_band_start_node, |
4630 | start_tree, |
4631 | start_node, |
4632 | FALSE(0), |
4633 | FALSE(0), |
4634 | TRUE(!(0))); |
4635 | } |
4636 | |
4637 | tree_view->priv->rubber_band_start_tree = start_tree; |
4638 | tree_view->priv->rubber_band_start_node = start_node; |
4639 | |
4640 | /* Next, handle the end area */ |
4641 | if (!tree_view->priv->rubber_band_end_node) |
4642 | { |
4643 | /* In the event this happens, start_node was also NULL; this case is |
4644 | * handled above. |
4645 | */ |
4646 | } |
4647 | else if (!end_node) |
4648 | { |
4649 | /* Find the last node in the tree */ |
4650 | _ctk_rbtree_find_offset (tree_view->priv->tree, ctk_tree_view_get_height (tree_view) - 1, |
4651 | &end_tree, &end_node); |
4652 | |
4653 | /* Selection reached end of the tree */ |
4654 | ctk_tree_view_update_rubber_band_selection_range (tree_view, |
4655 | tree_view->priv->rubber_band_end_tree, |
4656 | tree_view->priv->rubber_band_end_node, |
4657 | end_tree, |
4658 | end_node, |
4659 | TRUE(!(0)), |
4660 | TRUE(!(0)), |
4661 | FALSE(0)); |
4662 | } |
4663 | else if (_ctk_rbtree_node_find_offset (end_tree, end_node) > |
4664 | _ctk_rbtree_node_find_offset (tree_view->priv->rubber_band_end_tree, tree_view->priv->rubber_band_end_node)) |
4665 | { |
4666 | /* New node is below the old one; selection became bigger */ |
4667 | ctk_tree_view_update_rubber_band_selection_range (tree_view, |
4668 | tree_view->priv->rubber_band_end_tree, |
4669 | tree_view->priv->rubber_band_end_node, |
4670 | end_tree, |
4671 | end_node, |
4672 | TRUE(!(0)), |
4673 | TRUE(!(0)), |
4674 | FALSE(0)); |
4675 | } |
4676 | else if (_ctk_rbtree_node_find_offset (end_tree, end_node) < |
4677 | _ctk_rbtree_node_find_offset (tree_view->priv->rubber_band_end_tree, tree_view->priv->rubber_band_end_node)) |
4678 | { |
4679 | /* New node is above the old one; selection became smaller */ |
4680 | ctk_tree_view_update_rubber_band_selection_range (tree_view, |
4681 | end_tree, |
4682 | end_node, |
4683 | tree_view->priv->rubber_band_end_tree, |
4684 | tree_view->priv->rubber_band_end_node, |
4685 | FALSE(0), |
4686 | TRUE(!(0)), |
4687 | FALSE(0)); |
4688 | } |
4689 | |
4690 | tree_view->priv->rubber_band_end_tree = end_tree; |
4691 | tree_view->priv->rubber_band_end_node = end_node; |
4692 | } |
4693 | |
4694 | static void |
4695 | ctk_tree_view_update_rubber_band (CtkTreeView *tree_view) |
4696 | { |
4697 | gdouble start_x, start_y, offset_x, offset_y, x, y; |
4698 | CdkRectangle old_area; |
4699 | CdkRectangle new_area; |
4700 | cairo_region_t *invalid_region; |
4701 | gint bin_x, bin_y; |
4702 | |
4703 | if (!ctk_gesture_is_recognized (tree_view->priv->drag_gesture)) |
4704 | return; |
4705 | |
4706 | old_area.x = MIN (tree_view->priv->press_start_x, tree_view->priv->rubber_band_x)(((tree_view->priv->press_start_x) < (tree_view-> priv->rubber_band_x)) ? (tree_view->priv->press_start_x ) : (tree_view->priv->rubber_band_x)); |
4707 | old_area.y = MIN (tree_view->priv->press_start_y, tree_view->priv->rubber_band_y)(((tree_view->priv->press_start_y) < (tree_view-> priv->rubber_band_y)) ? (tree_view->priv->press_start_y ) : (tree_view->priv->rubber_band_y)) - tree_view->priv->dy; |
4708 | old_area.width = ABS (tree_view->priv->rubber_band_x - tree_view->priv->press_start_x)(((tree_view->priv->rubber_band_x - tree_view->priv-> press_start_x) < 0) ? -(tree_view->priv->rubber_band_x - tree_view->priv->press_start_x) : (tree_view->priv ->rubber_band_x - tree_view->priv->press_start_x)) + 1; |
4709 | old_area.height = ABS (tree_view->priv->rubber_band_y - tree_view->priv->press_start_y)(((tree_view->priv->rubber_band_y - tree_view->priv-> press_start_y) < 0) ? -(tree_view->priv->rubber_band_y - tree_view->priv->press_start_y) : (tree_view->priv ->rubber_band_y - tree_view->priv->press_start_y)) + 1; |
4710 | |
4711 | ctk_gesture_drag_get_offset (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
4712 | &offset_x, &offset_y); |
4713 | ctk_gesture_drag_get_start_point (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
4714 | &start_x, &start_y); |
4715 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y, |
4716 | &bin_x, &bin_y); |
4717 | bin_y += tree_view->priv->dy; |
4718 | |
4719 | x = MAX (bin_x + offset_x, 0)(((bin_x + offset_x) > (0)) ? (bin_x + offset_x) : (0)); |
4720 | y = MAX (bin_y + offset_y, 0)(((bin_y + offset_y) > (0)) ? (bin_y + offset_y) : (0)); |
4721 | |
4722 | new_area.x = MIN (tree_view->priv->press_start_x, x)(((tree_view->priv->press_start_x) < (x)) ? (tree_view ->priv->press_start_x) : (x)); |
4723 | new_area.y = MIN (tree_view->priv->press_start_y, y)(((tree_view->priv->press_start_y) < (y)) ? (tree_view ->priv->press_start_y) : (y)) - tree_view->priv->dy; |
4724 | new_area.width = ABS (x - tree_view->priv->press_start_x)(((x - tree_view->priv->press_start_x) < 0) ? -(x - tree_view ->priv->press_start_x) : (x - tree_view->priv->press_start_x )) + 1; |
4725 | new_area.height = ABS (y - tree_view->priv->press_start_y)(((y - tree_view->priv->press_start_y) < 0) ? -(y - tree_view ->priv->press_start_y) : (y - tree_view->priv->press_start_y )) + 1; |
4726 | |
4727 | invalid_region = cairo_region_create_rectangle (&old_area); |
4728 | cairo_region_union_rectangle (invalid_region, &new_area); |
4729 | |
4730 | cdk_window_invalidate_region (tree_view->priv->bin_window, invalid_region, TRUE(!(0))); |
4731 | |
4732 | cairo_region_destroy (invalid_region); |
4733 | |
4734 | tree_view->priv->rubber_band_x = x; |
4735 | tree_view->priv->rubber_band_y = y; |
4736 | |
4737 | ctk_tree_view_update_rubber_band_selection (tree_view); |
4738 | } |
4739 | |
4740 | static void |
4741 | ctk_tree_view_paint_rubber_band (CtkTreeView *tree_view, |
4742 | cairo_t *cr) |
4743 | { |
4744 | gdouble start_x, start_y, offset_x, offset_y; |
4745 | CdkRectangle rect; |
4746 | CtkStyleContext *context; |
4747 | gint bin_x, bin_y; |
4748 | |
4749 | if (!ctk_gesture_is_recognized (tree_view->priv->drag_gesture)) |
4750 | return; |
4751 | |
4752 | ctk_gesture_drag_get_offset (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
4753 | &offset_x, &offset_y); |
4754 | ctk_gesture_drag_get_start_point (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
4755 | &start_x, &start_y); |
4756 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y, |
4757 | &bin_x, &bin_y); |
4758 | bin_x = MAX (0, bin_x + offset_x)(((0) > (bin_x + offset_x)) ? (0) : (bin_x + offset_x)); |
4759 | bin_y = MAX (0, bin_y + offset_y + tree_view->priv->dy)(((0) > (bin_y + offset_y + tree_view->priv->dy)) ? ( 0) : (bin_y + offset_y + tree_view->priv->dy)); |
4760 | |
4761 | cairo_save (cr); |
4762 | |
4763 | context = ctk_widget_get_style_context (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
4764 | |
4765 | ctk_style_context_save_to_node (context, tree_view->priv->rubber_band_cssnode); |
4766 | |
4767 | rect.x = MIN (tree_view->priv->press_start_x, bin_x)(((tree_view->priv->press_start_x) < (bin_x)) ? (tree_view ->priv->press_start_x) : (bin_x)); |
4768 | rect.y = MIN (tree_view->priv->press_start_y, bin_y)(((tree_view->priv->press_start_y) < (bin_y)) ? (tree_view ->priv->press_start_y) : (bin_y)) - tree_view->priv->dy; |
4769 | rect.width = ABS (tree_view->priv->press_start_x - bin_x)(((tree_view->priv->press_start_x - bin_x) < 0) ? -( tree_view->priv->press_start_x - bin_x) : (tree_view-> priv->press_start_x - bin_x)) + 1; |
4770 | rect.height = ABS (tree_view->priv->press_start_y - bin_y)(((tree_view->priv->press_start_y - bin_y) < 0) ? -( tree_view->priv->press_start_y - bin_y) : (tree_view-> priv->press_start_y - bin_y)) + 1; |
4771 | |
4772 | cdk_cairo_rectangle (cr, &rect); |
4773 | cairo_clip (cr); |
4774 | |
4775 | ctk_render_background (context, cr, |
4776 | rect.x, rect.y, |
4777 | rect.width, rect.height); |
4778 | ctk_render_frame (context, cr, |
4779 | rect.x, rect.y, |
4780 | rect.width, rect.height); |
4781 | |
4782 | ctk_style_context_restore (context); |
4783 | cairo_restore (cr); |
4784 | } |
4785 | |
4786 | static void |
4787 | ctk_tree_view_column_drag_gesture_update (CtkGestureDrag *gesture, |
4788 | gdouble offset_x, |
4789 | gdouble offset_y, |
4790 | CtkTreeView *tree_view) |
4791 | { |
4792 | gdouble start_x, start_y, x, y; |
4793 | CdkEventSequence *sequence; |
4794 | |
4795 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((gesture)), ((ctk_gesture_single_get_type () ))))))); |
4796 | |
4797 | if (ctk_gesture_get_sequence_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), sequence) != CTK_EVENT_SEQUENCE_CLAIMED) |
4798 | return; |
4799 | |
4800 | ctk_gesture_drag_get_start_point (gesture, &start_x, &start_y); |
4801 | x = start_x + offset_x; |
4802 | y = start_y + offset_y; |
4803 | |
4804 | if (tree_view->priv->in_column_resize) |
4805 | ctk_tree_view_motion_resize_column (tree_view, x, y); |
4806 | else if (tree_view->priv->in_column_drag) |
4807 | ctk_tree_view_motion_drag_column (tree_view, x, y); |
4808 | } |
4809 | |
4810 | static void |
4811 | ctk_tree_view_drag_gesture_update (CtkGestureDrag *gesture, |
4812 | gdouble offset_x G_GNUC_UNUSED__attribute__ ((__unused__)), |
4813 | gdouble offset_y G_GNUC_UNUSED__attribute__ ((__unused__)), |
4814 | CtkTreeView *tree_view) |
4815 | { |
4816 | if (tree_view->priv->tree == NULL((void*)0)) |
4817 | { |
4818 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_DENIED); |
4819 | return; |
4820 | } |
4821 | |
4822 | if (tree_view->priv->rubber_band_status == RUBBER_BAND_MAYBE_START) |
4823 | { |
4824 | CtkCssNode *widget_node; |
4825 | |
4826 | widget_node = ctk_widget_get_css_node (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
4827 | tree_view->priv->rubber_band_cssnode = ctk_css_node_new (); |
4828 | ctk_css_node_set_name (tree_view->priv->rubber_band_cssnode, I_("rubberband")g_intern_static_string ("rubberband")); |
4829 | ctk_css_node_set_parent (tree_view->priv->rubber_band_cssnode, widget_node); |
4830 | ctk_css_node_set_state (tree_view->priv->rubber_band_cssnode, ctk_css_node_get_state (widget_node)); |
4831 | g_object_unref (tree_view->priv->rubber_band_cssnode); |
4832 | |
4833 | ctk_tree_view_update_rubber_band (tree_view); |
4834 | |
4835 | tree_view->priv->rubber_band_status = RUBBER_BAND_ACTIVE; |
4836 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_CLAIMED); |
4837 | } |
4838 | else if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE) |
4839 | { |
4840 | ctk_tree_view_update_rubber_band (tree_view); |
4841 | |
4842 | add_scroll_timeout (tree_view); |
4843 | } |
4844 | else if (!tree_view->priv->rubber_band_status) |
4845 | { |
4846 | if (ctk_tree_view_maybe_begin_dragging_row (tree_view)) |
4847 | ctk_gesture_set_state (CTK_GESTURE (gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((gesture)), ((ctk_gesture_get_type ())))))), CTK_EVENT_SEQUENCE_DENIED); |
4848 | } |
4849 | } |
4850 | |
4851 | static gboolean |
4852 | ctk_tree_view_motion (CtkWidget *widget, |
4853 | CdkEventMotion *event) |
4854 | { |
4855 | CtkTreeView *tree_view; |
4856 | CtkRBTree *tree; |
4857 | CtkRBNode *node; |
4858 | gint new_y; |
4859 | |
4860 | tree_view = (CtkTreeView *) widget; |
4861 | |
4862 | if (tree_view->priv->tree) |
4863 | { |
4864 | /* If we are currently pressing down a button, we don't want to prelight anything else. */ |
4865 | if (ctk_gesture_is_active (tree_view->priv->drag_gesture) || |
4866 | ctk_gesture_is_active (tree_view->priv->multipress_gesture)) |
4867 | node = NULL((void*)0); |
4868 | |
4869 | new_y = MAX (0, TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, event->y))(((0) > (((event->y) + tree_view->priv->dy))) ? ( 0) : (((event->y) + tree_view->priv->dy))); |
4870 | |
4871 | _ctk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node); |
4872 | |
4873 | tree_view->priv->event_last_x = event->x; |
4874 | tree_view->priv->event_last_y = event->y; |
4875 | prelight_or_select (tree_view, tree, node, event->x, event->y); |
4876 | } |
4877 | |
4878 | return CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->motion_notify_event (widget, event); |
4879 | } |
4880 | |
4881 | /* Invalidate the focus rectangle near the edge of the bin_window; used when |
4882 | * the tree is empty. |
4883 | */ |
4884 | static void |
4885 | invalidate_empty_focus (CtkTreeView *tree_view) |
4886 | { |
4887 | CdkRectangle area; |
4888 | |
4889 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
4890 | return; |
4891 | |
4892 | area.x = 0; |
4893 | area.y = 0; |
4894 | area.width = cdk_window_get_width (tree_view->priv->bin_window); |
4895 | area.height = cdk_window_get_height (tree_view->priv->bin_window); |
4896 | cdk_window_invalidate_rect (tree_view->priv->bin_window, &area, FALSE(0)); |
4897 | } |
4898 | |
4899 | /* Draws background and a focus rectangle near the edge of the bin_window; |
4900 | * used when the tree is empty. |
4901 | */ |
4902 | static void |
4903 | draw_empty (CtkTreeView *tree_view, |
4904 | cairo_t *cr) |
4905 | { |
4906 | CtkWidget *widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
4907 | CtkStyleContext *context; |
4908 | gint width, height; |
4909 | |
4910 | context = ctk_widget_get_style_context (widget); |
4911 | |
4912 | width = cdk_window_get_width (tree_view->priv->bin_window); |
4913 | height = cdk_window_get_height (tree_view->priv->bin_window); |
4914 | |
4915 | ctk_render_background (context, cr, 0, 0, width, height); |
4916 | |
4917 | if (ctk_widget_has_visible_focus (widget)) |
4918 | ctk_render_focus (context, cr, 0, 0, width, height); |
4919 | } |
4920 | |
4921 | typedef enum { |
4922 | CTK_TREE_VIEW_GRID_LINE, |
4923 | CTK_TREE_VIEW_TREE_LINE, |
4924 | CTK_TREE_VIEW_FOREGROUND_LINE |
4925 | } CtkTreeViewLineType; |
4926 | |
4927 | static void |
4928 | ctk_tree_view_draw_line (CtkTreeView *tree_view, |
4929 | cairo_t *cr, |
4930 | CtkTreeViewLineType type, |
4931 | int x1, |
4932 | int y1, |
4933 | int x2, |
4934 | int y2) |
4935 | { |
4936 | CtkStyleContext *context; |
4937 | |
4938 | cairo_save (cr); |
4939 | |
4940 | context = ctk_widget_get_style_context (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
4941 | |
4942 | switch (type) |
4943 | { |
4944 | case CTK_TREE_VIEW_TREE_LINE: |
4945 | { |
4946 | const CdkRGBA *color; |
4947 | |
4948 | color = _ctk_css_rgba_value_get_rgba (_ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BORDER_LEFT_COLOR)); |
4949 | |
4950 | cdk_cairo_set_source_rgba (cr, color); |
4951 | cairo_set_line_width (cr, tree_view->priv->tree_line_width); |
4952 | if (tree_view->priv->tree_line_dashes[0]) |
4953 | cairo_set_dash (cr, tree_view->priv->tree_line_dashes, 2, 0.5); |
4954 | } |
4955 | break; |
4956 | |
4957 | case CTK_TREE_VIEW_GRID_LINE: |
4958 | { |
4959 | const CdkRGBA *color; |
4960 | |
4961 | color = _ctk_css_rgba_value_get_rgba (_ctk_style_context_peek_property (context, CTK_CSS_PROPERTY_BORDER_TOP_COLOR)); |
4962 | |
4963 | cdk_cairo_set_source_rgba (cr, color); |
4964 | cairo_set_line_width (cr, tree_view->priv->grid_line_width); |
4965 | if (tree_view->priv->grid_line_dashes[0]) |
4966 | cairo_set_dash (cr, tree_view->priv->grid_line_dashes, 2, 0.5); |
4967 | } |
4968 | break; |
4969 | |
4970 | case CTK_TREE_VIEW_FOREGROUND_LINE: |
4971 | { |
4972 | CdkRGBA color; |
4973 | |
4974 | cairo_set_line_width (cr, 1.0); |
4975 | ctk_style_context_get_color (context, ctk_style_context_get_state (context), &color); |
4976 | cdk_cairo_set_source_rgba (cr, &color); |
4977 | } |
4978 | break; |
4979 | |
4980 | default: |
4981 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctktreeview.c", 4981, ( (const char*) (__func__)), ((void*)0)); } while (0); |
4982 | break; |
4983 | } |
4984 | |
4985 | cairo_move_to (cr, x1 + 0.5, y1 + 0.5); |
4986 | cairo_line_to (cr, x2 + 0.5, y2 + 0.5); |
4987 | cairo_stroke (cr); |
4988 | |
4989 | cairo_restore (cr); |
4990 | } |
4991 | |
4992 | static void |
4993 | ctk_tree_view_draw_grid_lines (CtkTreeView *tree_view, |
4994 | cairo_t *cr) |
4995 | { |
4996 | GList *list, *first, *last; |
4997 | gboolean rtl; |
4998 | gint current_x = 0; |
4999 | |
5000 | if (tree_view->priv->grid_lines != CTK_TREE_VIEW_GRID_LINES_VERTICAL |
5001 | && tree_view->priv->grid_lines != CTK_TREE_VIEW_GRID_LINES_BOTH) |
5002 | return; |
5003 | |
5004 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
5005 | |
5006 | first = g_list_first (tree_view->priv->columns); |
5007 | last = g_list_last (tree_view->priv->columns); |
5008 | |
5009 | for (list = (rtl ? last : first); |
5010 | list; |
5011 | list = (rtl ? list->prev : list->next)) |
5012 | { |
5013 | CtkTreeViewColumn *column = list->data; |
5014 | |
5015 | /* We don't want a line for the last column */ |
5016 | if (column == (rtl ? first->data : last->data)) |
5017 | break; |
5018 | |
5019 | if (!ctk_tree_view_column_get_visible (column)) |
5020 | continue; |
5021 | |
5022 | current_x += ctk_tree_view_column_get_width (column); |
5023 | |
5024 | ctk_tree_view_draw_line (tree_view, cr, |
5025 | CTK_TREE_VIEW_GRID_LINE, |
5026 | current_x - 1, 0, |
5027 | current_x - 1, ctk_tree_view_get_height (tree_view)); |
5028 | } |
5029 | } |
5030 | |
5031 | /* Warning: Very scary function. |
5032 | * Modify at your own risk |
5033 | * |
5034 | * KEEP IN SYNC WITH ctk_tree_view_create_row_drag_icon()! |
5035 | * FIXME: It’s not... |
5036 | */ |
5037 | static gboolean |
5038 | ctk_tree_view_bin_draw (CtkWidget *widget, |
5039 | cairo_t *cr) |
5040 | { |
5041 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
5042 | CtkTreePath *path; |
5043 | CtkRBTree *tree; |
5044 | GList *list; |
5045 | CtkRBNode *node; |
5046 | CtkRBNode *drag_highlight = NULL((void*)0); |
5047 | CtkRBTree *drag_highlight_tree = NULL((void*)0); |
5048 | CtkTreeIter iter; |
5049 | gint new_y; |
5050 | gint y_offset, cell_offset; |
5051 | gint max_height; |
5052 | gint depth; |
5053 | CdkRectangle background_area; |
5054 | CdkRectangle cell_area; |
5055 | CdkRectangle clip; |
5056 | guint flags; |
5057 | gint bin_window_width; |
5058 | gint bin_window_height; |
5059 | CtkTreePath *drag_dest_path = NULL((void*)0); |
5060 | GList *first_column, *last_column; |
5061 | gint vertical_separator; |
5062 | gint horizontal_separator; |
5063 | gboolean allow_rules; |
5064 | gboolean has_can_focus_cell; |
5065 | gboolean rtl; |
5066 | gint n_visible_columns; |
5067 | gint grid_line_width; |
5068 | gint expander_size; |
5069 | gboolean draw_vgrid_lines, draw_hgrid_lines; |
5070 | CtkStyleContext *context; |
5071 | gboolean parity; |
5072 | |
5073 | rtl = (ctk_widget_get_direction (widget) == CTK_TEXT_DIR_RTL); |
5074 | context = ctk_widget_get_style_context (widget); |
5075 | |
5076 | ctk_widget_style_get (widget, |
5077 | "horizontal-separator", &horizontal_separator, |
5078 | "vertical-separator", &vertical_separator, |
5079 | "allow-rules", &allow_rules, |
5080 | NULL((void*)0)); |
5081 | |
5082 | if (tree_view->priv->tree == NULL((void*)0)) |
5083 | { |
5084 | draw_empty (tree_view, cr); |
5085 | return TRUE(!(0)); |
5086 | } |
5087 | |
5088 | bin_window_width = cdk_window_get_width (tree_view->priv->bin_window); |
5089 | bin_window_height = cdk_window_get_height (tree_view->priv->bin_window); |
5090 | if (!cdk_cairo_get_clip_rectangle (cr, &clip)) |
5091 | return TRUE(!(0)); |
5092 | |
5093 | new_y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, clip.y)((clip.y) + tree_view->priv->dy); |
5094 | |
5095 | if (new_y < 0) |
5096 | new_y = 0; |
5097 | y_offset = -_ctk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node); |
5098 | |
5099 | if (ctk_tree_view_get_height (tree_view) < bin_window_height) |
5100 | { |
5101 | ctk_style_context_save (context); |
5102 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_CELL"cell"); |
5103 | |
5104 | ctk_render_background (context, cr, |
5105 | 0, ctk_tree_view_get_height (tree_view), |
5106 | bin_window_width, |
5107 | bin_window_height - ctk_tree_view_get_height (tree_view)); |
5108 | |
5109 | ctk_style_context_restore (context); |
5110 | } |
5111 | |
5112 | if (node == NULL((void*)0)) |
5113 | goto done; |
5114 | |
5115 | /* find the path for the node */ |
5116 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
5117 | ctk_tree_model_get_iter (tree_view->priv->model, |
5118 | &iter, |
5119 | path); |
5120 | depth = ctk_tree_path_get_depth (path); |
5121 | ctk_tree_path_free (path); |
5122 | |
5123 | if (tree_view->priv->drag_dest_row) |
5124 | drag_dest_path = ctk_tree_row_reference_get_path (tree_view->priv->drag_dest_row); |
5125 | |
5126 | if (drag_dest_path) |
5127 | _ctk_tree_view_find_node (tree_view, drag_dest_path, |
5128 | &drag_highlight_tree, &drag_highlight); |
5129 | |
5130 | draw_vgrid_lines = |
5131 | tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_VERTICAL |
5132 | || tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_BOTH; |
5133 | draw_hgrid_lines = |
5134 | tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_HORIZONTAL |
5135 | || tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_BOTH; |
5136 | expander_size = ctk_tree_view_get_expander_size (tree_view); |
5137 | |
5138 | if (draw_vgrid_lines || draw_hgrid_lines) |
5139 | ctk_widget_style_get (widget, "grid-line-width", &grid_line_width, NULL((void*)0)); |
5140 | |
5141 | n_visible_columns = 0; |
5142 | for (list = tree_view->priv->columns; list; list = list->next) |
5143 | { |
5144 | if (!ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))))) |
5145 | continue; |
5146 | n_visible_columns ++; |
5147 | } |
5148 | |
5149 | /* Find the last column */ |
5150 | for (last_column = g_list_last (tree_view->priv->columns); |
5151 | last_column && |
5152 | !(ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (last_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((last_column->data)), ((ctk_tree_view_column_get_type ())))))))); |
5153 | last_column = last_column->prev) |
5154 | ; |
5155 | |
5156 | /* and the first */ |
5157 | for (first_column = g_list_first (tree_view->priv->columns); |
5158 | first_column && |
5159 | !(ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (first_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((first_column->data)), ((ctk_tree_view_column_get_type ())))))))); |
5160 | first_column = first_column->next) |
5161 | ; |
5162 | |
5163 | /* Actually process the expose event. To do this, we want to |
5164 | * start at the first node of the event, and walk the tree in |
5165 | * order, drawing each successive node. |
5166 | */ |
5167 | |
5168 | parity = !(_ctk_rbtree_node_get_index (tree, node) % 2); |
5169 | |
5170 | do |
5171 | { |
5172 | gboolean is_separator = FALSE(0); |
5173 | gint n_col = 0; |
5174 | |
5175 | parity = !parity; |
5176 | is_separator = row_is_separator (tree_view, &iter, NULL((void*)0)); |
5177 | |
5178 | max_height = ctk_tree_view_get_row_height (tree_view, node); |
5179 | |
5180 | cell_offset = 0; |
5181 | |
5182 | background_area.y = y_offset + clip.y; |
5183 | background_area.height = max_height; |
5184 | |
5185 | flags = 0; |
5186 | |
5187 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PRELIT)(node?(((node->flags&CTK_RBNODE_IS_PRELIT)==CTK_RBNODE_IS_PRELIT )?(!(0)):(0)):(0))) |
5188 | flags |= CTK_CELL_RENDERER_PRELIT; |
5189 | |
5190 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
5191 | flags |= CTK_CELL_RENDERER_SELECTED; |
5192 | |
5193 | /* we *need* to set cell data on all cells before the call |
5194 | * to _has_can_focus_cell, else _has_can_focus_cell() does not |
5195 | * return a correct value. |
5196 | */ |
5197 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
5198 | list; |
5199 | list = (rtl ? list->prev : list->next)) |
5200 | { |
5201 | CtkTreeViewColumn *column = list->data; |
5202 | ctk_tree_view_column_cell_set_cell_data (column, |
5203 | tree_view->priv->model, |
5204 | &iter, |
5205 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
5206 | node->children?TRUE(!(0)):FALSE(0)); |
5207 | } |
5208 | |
5209 | has_can_focus_cell = ctk_tree_view_has_can_focus_cell (tree_view); |
5210 | |
5211 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
5212 | list; |
5213 | list = (rtl ? list->prev : list->next)) |
5214 | { |
5215 | CtkTreeViewColumn *column = list->data; |
5216 | CtkStateFlags state = 0; |
5217 | gint width; |
5218 | gboolean draw_focus; |
5219 | |
5220 | if (!ctk_tree_view_column_get_visible (column)) |
5221 | continue; |
5222 | |
5223 | n_col++; |
5224 | width = ctk_tree_view_column_get_width (column); |
5225 | |
5226 | if (cell_offset > clip.x + clip.width || |
5227 | cell_offset + width < clip.x) |
5228 | { |
5229 | cell_offset += width; |
5230 | continue; |
5231 | } |
5232 | |
5233 | if (ctk_tree_view_column_get_sort_indicator (column)) |
5234 | flags |= CTK_CELL_RENDERER_SORTED; |
5235 | else |
5236 | flags &= ~CTK_CELL_RENDERER_SORTED; |
5237 | |
5238 | if (tree_view->priv->cursor_node == node) |
5239 | flags |= CTK_CELL_RENDERER_FOCUSED; |
5240 | else |
5241 | flags &= ~CTK_CELL_RENDERER_FOCUSED; |
5242 | |
5243 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0))) |
5244 | flags |= CTK_CELL_RENDERER_EXPANDABLE; |
5245 | else |
5246 | flags &= ~CTK_CELL_RENDERER_EXPANDABLE; |
5247 | |
5248 | if (node->children) |
5249 | flags |= CTK_CELL_RENDERER_EXPANDED; |
5250 | else |
5251 | flags &= ~CTK_CELL_RENDERER_EXPANDED; |
5252 | |
5253 | background_area.x = cell_offset; |
5254 | background_area.width = width; |
5255 | |
5256 | cell_area = background_area; |
5257 | cell_area.y += vertical_separator / 2; |
5258 | cell_area.x += horizontal_separator / 2; |
5259 | cell_area.height -= vertical_separator; |
5260 | cell_area.width -= horizontal_separator; |
5261 | |
5262 | if (draw_vgrid_lines) |
5263 | { |
5264 | if (list == first_column) |
5265 | { |
5266 | cell_area.width -= grid_line_width / 2; |
5267 | } |
5268 | else if (list == last_column) |
5269 | { |
5270 | cell_area.x += grid_line_width / 2; |
5271 | cell_area.width -= grid_line_width / 2; |
5272 | } |
5273 | else |
5274 | { |
5275 | cell_area.x += grid_line_width / 2; |
5276 | cell_area.width -= grid_line_width; |
5277 | } |
5278 | } |
5279 | |
5280 | if (draw_hgrid_lines) |
5281 | { |
5282 | cell_area.y += grid_line_width / 2; |
5283 | cell_area.height -= grid_line_width; |
5284 | } |
5285 | |
5286 | if (!cdk_rectangle_intersect (&clip, &background_area, NULL((void*)0))) |
5287 | { |
5288 | cell_offset += ctk_tree_view_column_get_width (column); |
5289 | continue; |
5290 | } |
5291 | |
5292 | ctk_tree_view_column_cell_set_cell_data (column, |
5293 | tree_view->priv->model, |
5294 | &iter, |
5295 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
5296 | node->children?TRUE(!(0)):FALSE(0)); |
5297 | |
5298 | ctk_style_context_save (context); |
5299 | |
5300 | state = ctk_cell_renderer_get_state (NULL((void*)0), widget, flags); |
5301 | ctk_style_context_set_state (context, state); |
5302 | |
5303 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_CELL"cell"); |
5304 | |
5305 | if (node == tree_view->priv->cursor_node && has_can_focus_cell |
5306 | && ((column == tree_view->priv->focus_column |
5307 | && tree_view->priv->draw_keyfocus && |
5308 | ctk_widget_has_visible_focus (widget)) |
5309 | || (column == tree_view->priv->edited_column))) |
5310 | draw_focus = TRUE(!(0)); |
5311 | else |
5312 | draw_focus = FALSE(0); |
5313 | |
5314 | /* Draw background */ |
5315 | ctk_render_background (context, cr, |
5316 | background_area.x, |
5317 | background_area.y, |
5318 | background_area.width, |
5319 | background_area.height); |
5320 | |
5321 | /* Draw frame */ |
5322 | ctk_render_frame (context, cr, |
5323 | background_area.x, |
5324 | background_area.y, |
5325 | background_area.width, |
5326 | background_area.height); |
5327 | |
5328 | if (ctk_tree_view_is_expander_column (tree_view, column)) |
5329 | { |
5330 | if (!rtl) |
5331 | cell_area.x += (depth - 1) * tree_view->priv->level_indentation; |
5332 | cell_area.width -= (depth - 1) * tree_view->priv->level_indentation; |
5333 | |
5334 | if (ctk_tree_view_draw_expanders (tree_view)) |
5335 | { |
5336 | if (!rtl) |
5337 | cell_area.x += depth * expander_size; |
5338 | cell_area.width -= depth * expander_size; |
5339 | } |
5340 | |
5341 | if (is_separator) |
5342 | { |
5343 | ctk_style_context_save (context); |
5344 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_SEPARATOR"separator"); |
5345 | |
5346 | ctk_render_line (context, cr, |
5347 | cell_area.x, |
5348 | cell_area.y + cell_area.height / 2, |
5349 | cell_area.x + cell_area.width, |
5350 | cell_area.y + cell_area.height / 2); |
5351 | |
5352 | ctk_style_context_restore (context); |
5353 | } |
5354 | else |
5355 | { |
5356 | _ctk_tree_view_column_cell_render (column, |
5357 | cr, |
5358 | &background_area, |
5359 | &cell_area, |
5360 | flags, |
5361 | draw_focus); |
5362 | } |
5363 | |
5364 | if (ctk_tree_view_draw_expanders (tree_view) |
5365 | && (node->flags & CTK_RBNODE_IS_PARENT) == CTK_RBNODE_IS_PARENT) |
5366 | { |
5367 | ctk_tree_view_draw_arrow (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
5368 | cr, |
5369 | tree, |
5370 | node); |
5371 | } |
5372 | } |
5373 | else |
5374 | { |
5375 | if (is_separator) |
5376 | { |
5377 | ctk_style_context_save (context); |
5378 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_SEPARATOR"separator"); |
5379 | |
5380 | ctk_render_line (context, cr, |
5381 | cell_area.x, |
5382 | cell_area.y + cell_area.height / 2, |
5383 | cell_area.x + cell_area.width, |
5384 | cell_area.y + cell_area.height / 2); |
5385 | |
5386 | ctk_style_context_restore (context); |
5387 | } |
5388 | else |
5389 | _ctk_tree_view_column_cell_render (column, |
5390 | cr, |
5391 | &background_area, |
5392 | &cell_area, |
5393 | flags, |
5394 | draw_focus); |
5395 | } |
5396 | |
5397 | if (draw_hgrid_lines) |
5398 | { |
5399 | if (background_area.y >= clip.y) |
5400 | ctk_tree_view_draw_line (tree_view, cr, |
5401 | CTK_TREE_VIEW_GRID_LINE, |
5402 | background_area.x, background_area.y, |
5403 | background_area.x + background_area.width, |
5404 | background_area.y); |
5405 | |
5406 | if (background_area.y + max_height < clip.y + clip.height) |
5407 | ctk_tree_view_draw_line (tree_view, cr, |
5408 | CTK_TREE_VIEW_GRID_LINE, |
5409 | background_area.x, background_area.y + max_height, |
5410 | background_area.x + background_area.width, |
5411 | background_area.y + max_height); |
5412 | } |
5413 | |
5414 | if (ctk_tree_view_is_expander_column (tree_view, column) && |
5415 | tree_view->priv->tree_lines_enabled) |
5416 | { |
5417 | gint x = background_area.x; |
5418 | gint mult = rtl ? -1 : 1; |
5419 | gint y0 = background_area.y; |
5420 | gint y1 = background_area.y + background_area.height/2; |
5421 | gint y2 = background_area.y + background_area.height; |
5422 | |
5423 | if (rtl) |
5424 | x += background_area.width - 1; |
5425 | |
5426 | if ((node->flags & CTK_RBNODE_IS_PARENT) == CTK_RBNODE_IS_PARENT |
5427 | && depth > 1) |
5428 | { |
5429 | ctk_tree_view_draw_line (tree_view, cr, |
5430 | CTK_TREE_VIEW_TREE_LINE, |
5431 | x + expander_size * (depth - 1.5) * mult, |
5432 | y1, |
5433 | x + expander_size * (depth - 1.1) * mult, |
5434 | y1); |
5435 | } |
5436 | else if (depth > 1) |
5437 | { |
5438 | ctk_tree_view_draw_line (tree_view, cr, |
5439 | CTK_TREE_VIEW_TREE_LINE, |
5440 | x + expander_size * (depth - 1.5) * mult, |
5441 | y1, |
5442 | x + expander_size * (depth - 0.5) * mult, |
5443 | y1); |
5444 | } |
5445 | |
5446 | if (depth > 1) |
5447 | { |
5448 | gint i; |
5449 | CtkRBNode *tmp_node; |
5450 | CtkRBTree *tmp_tree; |
5451 | |
5452 | if (!_ctk_rbtree_next (tree, node)) |
5453 | ctk_tree_view_draw_line (tree_view, cr, |
5454 | CTK_TREE_VIEW_TREE_LINE, |
5455 | x + expander_size * (depth - 1.5) * mult, |
5456 | y0, |
5457 | x + expander_size * (depth - 1.5) * mult, |
5458 | y1); |
5459 | else |
5460 | ctk_tree_view_draw_line (tree_view, cr, |
5461 | CTK_TREE_VIEW_TREE_LINE, |
5462 | x + expander_size * (depth - 1.5) * mult, |
5463 | y0, |
5464 | x + expander_size * (depth - 1.5) * mult, |
5465 | y2); |
5466 | |
5467 | tmp_node = tree->parent_node; |
5468 | tmp_tree = tree->parent_tree; |
5469 | |
5470 | for (i = depth - 2; i > 0; i--) |
5471 | { |
5472 | if (_ctk_rbtree_next (tmp_tree, tmp_node)) |
5473 | ctk_tree_view_draw_line (tree_view, cr, |
5474 | CTK_TREE_VIEW_TREE_LINE, |
5475 | x + expander_size * (i - 0.5) * mult, |
5476 | y0, |
5477 | x + expander_size * (i - 0.5) * mult, |
5478 | y2); |
5479 | |
5480 | tmp_node = tmp_tree->parent_node; |
5481 | tmp_tree = tmp_tree->parent_tree; |
5482 | } |
5483 | } |
5484 | } |
5485 | |
5486 | ctk_style_context_restore (context); |
5487 | cell_offset += ctk_tree_view_column_get_width (column); |
5488 | } |
5489 | |
5490 | if (node == drag_highlight) |
5491 | { |
5492 | /* Draw indicator for the drop |
5493 | */ |
5494 | CtkRBTree *drag_tree = NULL((void*)0); |
5495 | CtkRBNode *drag_node = NULL((void*)0); |
5496 | |
5497 | ctk_style_context_save (context); |
5498 | ctk_style_context_set_state (context, ctk_style_context_get_state (context) | CTK_STATE_FLAG_DROP_ACTIVE); |
5499 | |
5500 | switch (tree_view->priv->drag_dest_pos) |
5501 | { |
5502 | case CTK_TREE_VIEW_DROP_BEFORE: |
5503 | ctk_style_context_add_class (context, "before"); |
5504 | break; |
5505 | |
5506 | case CTK_TREE_VIEW_DROP_AFTER: |
5507 | ctk_style_context_add_class (context, "after"); |
5508 | break; |
5509 | |
5510 | case CTK_TREE_VIEW_DROP_INTO_OR_BEFORE: |
5511 | case CTK_TREE_VIEW_DROP_INTO_OR_AFTER: |
5512 | ctk_style_context_add_class (context, "into"); |
5513 | break; |
5514 | } |
5515 | |
5516 | _ctk_tree_view_find_node (tree_view, drag_dest_path, &drag_tree, &drag_node); |
5517 | if (drag_tree != NULL((void*)0)) |
5518 | ctk_render_frame (context, cr, |
5519 | 0, ctk_tree_view_get_row_y_offset (tree_view, drag_tree, drag_node), |
5520 | cdk_window_get_width (tree_view->priv->bin_window), |
5521 | ctk_tree_view_get_row_height (tree_view, drag_node)); |
5522 | |
5523 | ctk_style_context_restore (context); |
5524 | } |
5525 | |
5526 | /* draw the big row-spanning focus rectangle, if needed */ |
5527 | if (!has_can_focus_cell && node == tree_view->priv->cursor_node && |
5528 | tree_view->priv->draw_keyfocus && |
5529 | ctk_widget_has_visible_focus (widget)) |
5530 | { |
5531 | gint tmp_y, tmp_height; |
5532 | CtkStateFlags focus_rect_state = 0; |
5533 | |
5534 | ctk_style_context_save (context); |
5535 | |
5536 | focus_rect_state = ctk_cell_renderer_get_state (NULL((void*)0), widget, flags); |
5537 | ctk_style_context_set_state (context, focus_rect_state); |
5538 | |
5539 | if (draw_hgrid_lines) |
5540 | { |
5541 | tmp_y = ctk_tree_view_get_row_y_offset (tree_view, tree, node) + grid_line_width / 2; |
5542 | tmp_height = ctk_tree_view_get_row_height (tree_view, node) - grid_line_width; |
5543 | } |
5544 | else |
5545 | { |
5546 | tmp_y = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
5547 | tmp_height = ctk_tree_view_get_row_height (tree_view, node); |
5548 | } |
5549 | |
5550 | ctk_render_focus (context, cr, |
5551 | 0, tmp_y, |
5552 | cdk_window_get_width (tree_view->priv->bin_window), |
5553 | tmp_height); |
5554 | |
5555 | ctk_style_context_restore (context); |
5556 | } |
5557 | |
5558 | y_offset += max_height; |
5559 | if (node->children) |
5560 | { |
5561 | CtkTreeIter parent = iter; |
5562 | gboolean has_child; |
5563 | |
5564 | tree = node->children; |
5565 | node = _ctk_rbtree_first (tree); |
5566 | |
5567 | has_child = ctk_tree_model_iter_children (tree_view->priv->model, |
5568 | &iter, |
5569 | &parent); |
5570 | depth++; |
5571 | |
5572 | /* Sanity Check! */ |
5573 | TREE_VIEW_INTERNAL_ASSERT (has_child, FALSE)do{ if (!(has_child)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "5573", ((const char* ) (__func__)), "has_child"); return (0); }; }while (0); |
5574 | } |
5575 | else |
5576 | { |
5577 | gboolean done = FALSE(0); |
5578 | |
5579 | do |
5580 | { |
5581 | node = _ctk_rbtree_next (tree, node); |
5582 | if (node != NULL((void*)0)) |
5583 | { |
5584 | gboolean has_next = ctk_tree_model_iter_next (tree_view->priv->model, &iter); |
5585 | done = TRUE(!(0)); |
5586 | |
5587 | /* Sanity Check! */ |
5588 | TREE_VIEW_INTERNAL_ASSERT (has_next, FALSE)do{ if (!(has_next)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "5588", ((const char* ) (__func__)), "has_next"); return (0); }; }while (0); |
5589 | } |
5590 | else |
5591 | { |
5592 | CtkTreeIter parent_iter = iter; |
5593 | gboolean has_parent; |
5594 | |
5595 | node = tree->parent_node; |
5596 | tree = tree->parent_tree; |
5597 | if (tree == NULL((void*)0)) |
5598 | /* we should go to done to free some memory */ |
5599 | goto done; |
5600 | has_parent = ctk_tree_model_iter_parent (tree_view->priv->model, |
5601 | &iter, |
5602 | &parent_iter); |
5603 | depth--; |
5604 | |
5605 | /* Sanity check */ |
5606 | TREE_VIEW_INTERNAL_ASSERT (has_parent, FALSE)do{ if (!(has_parent)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "5606", ((const char* ) (__func__)), "has_parent"); return (0); }; }while (0); |
5607 | } |
5608 | } |
5609 | while (!done); |
5610 | } |
5611 | } |
5612 | while (y_offset < clip.height); |
5613 | |
5614 | done: |
5615 | ctk_tree_view_draw_grid_lines (tree_view, cr); |
5616 | |
5617 | if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE) |
5618 | ctk_tree_view_paint_rubber_band (tree_view, cr); |
5619 | |
5620 | if (drag_dest_path) |
5621 | ctk_tree_path_free (drag_dest_path); |
5622 | |
5623 | return FALSE(0); |
5624 | } |
5625 | |
5626 | static void |
5627 | draw_bin (cairo_t *cr, |
5628 | gpointer user_data) |
5629 | { |
5630 | CtkWidget *widget = CTK_WIDGET (user_data)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((user_data)), ((ctk_widget_get_type ())))))); |
5631 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
5632 | GList *tmp_list; |
5633 | |
5634 | cairo_save (cr); |
5635 | |
5636 | ctk_cairo_transform_to_window (cr, widget, tree_view->priv->bin_window); |
5637 | ctk_tree_view_bin_draw (widget, cr); |
5638 | |
5639 | cairo_restore (cr); |
5640 | |
5641 | /* We can't just chain up to Container::draw as it will try to send the |
5642 | * event to the headers, so we handle propagating it to our children |
5643 | * (eg. widgets being edited) ourselves. |
5644 | */ |
5645 | tmp_list = tree_view->priv->children; |
5646 | while (tmp_list) |
5647 | { |
5648 | CtkTreeViewChild *child = tmp_list->data; |
5649 | tmp_list = tmp_list->next; |
5650 | |
5651 | ctk_container_propagate_draw (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ())))))), child->widget, cr); |
5652 | } |
5653 | } |
5654 | |
5655 | static gboolean |
5656 | ctk_tree_view_draw (CtkWidget *widget, |
5657 | cairo_t *cr) |
5658 | { |
5659 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
5660 | CtkWidget *button; |
5661 | CtkStyleContext *context; |
5662 | |
5663 | context = ctk_widget_get_style_context (widget); |
5664 | |
5665 | if (ctk_cairo_should_draw_window (cr, tree_view->priv->bin_window)) |
5666 | { |
5667 | cairo_rectangle_int_t view_rect; |
5668 | cairo_rectangle_int_t canvas_rect; |
5669 | |
5670 | view_rect.x = 0; |
5671 | view_rect.y = ctk_tree_view_get_effective_header_height (tree_view); |
5672 | view_rect.width = ctk_widget_get_allocated_width (widget); |
5673 | view_rect.height = ctk_widget_get_allocated_height (widget) - view_rect.y; |
5674 | |
5675 | cdk_window_get_position (tree_view->priv->bin_window, &canvas_rect.x, &canvas_rect.y); |
5676 | canvas_rect.y = -ctk_adjustment_get_value (tree_view->priv->vadjustment); |
5677 | canvas_rect.width = cdk_window_get_width (tree_view->priv->bin_window); |
5678 | canvas_rect.height = ctk_tree_view_get_height (tree_view); |
5679 | |
5680 | _ctk_pixel_cache_draw (tree_view->priv->pixel_cache, cr, tree_view->priv->bin_window, |
5681 | &view_rect, &canvas_rect, |
5682 | draw_bin, widget); |
5683 | } |
5684 | else if (tree_view->priv->drag_highlight_window && |
5685 | ctk_cairo_should_draw_window (cr, tree_view->priv->drag_highlight_window)) |
5686 | { |
5687 | CdkRGBA color; |
5688 | |
5689 | ctk_style_context_get_color (context, ctk_style_context_get_state (context), &color); |
5690 | cairo_save (cr); |
5691 | ctk_cairo_transform_to_window (cr, CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_highlight_window); |
5692 | if (tree_view->priv->drag_column_window_state == DRAG_COLUMN_WINDOW_STATE_ORIGINAL) |
5693 | { |
5694 | cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0); |
5695 | cairo_paint (cr); |
5696 | cdk_cairo_set_source_rgba (cr, &color); |
5697 | cairo_rectangle (cr, |
5698 | 1, 1, |
5699 | cdk_window_get_width (tree_view->priv->drag_highlight_window) - 2, |
5700 | cdk_window_get_height (tree_view->priv->drag_highlight_window) - 2); |
5701 | cairo_stroke (cr); |
5702 | } |
5703 | else |
5704 | { |
5705 | cdk_cairo_set_source_rgba (cr, &color); |
5706 | cairo_paint (cr); |
5707 | } |
5708 | cairo_restore (cr); |
5709 | } |
5710 | else |
5711 | { |
5712 | ctk_render_background (context, cr, |
5713 | 0, 0, |
5714 | ctk_widget_get_allocated_width (widget), |
5715 | ctk_widget_get_allocated_height (widget)); |
5716 | } |
5717 | |
5718 | ctk_style_context_save (context); |
5719 | ctk_style_context_remove_class (context, CTK_STYLE_CLASS_VIEW"view"); |
5720 | |
5721 | if (ctk_cairo_should_draw_window (cr, tree_view->priv->header_window)) |
5722 | { |
5723 | GList *list; |
5724 | |
5725 | for (list = tree_view->priv->columns; list != NULL((void*)0); list = list->next) |
5726 | { |
5727 | CtkTreeViewColumn *column = list->data; |
5728 | |
5729 | if (column == tree_view->priv->drag_column) |
5730 | continue; |
5731 | |
5732 | if (ctk_tree_view_column_get_visible (column)) |
5733 | { |
5734 | button = ctk_tree_view_column_get_button (column); |
5735 | ctk_container_propagate_draw (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ())))))), |
5736 | button, cr); |
5737 | } |
5738 | } |
5739 | } |
5740 | |
5741 | if (tree_view->priv->drag_window && |
5742 | ctk_cairo_should_draw_window (cr, tree_view->priv->drag_window)) |
5743 | { |
5744 | button = ctk_tree_view_column_get_button (tree_view->priv->drag_column); |
5745 | ctk_container_propagate_draw (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ())))))), |
5746 | button, cr); |
5747 | } |
5748 | |
5749 | ctk_style_context_restore (context); |
5750 | |
5751 | return FALSE(0); |
5752 | } |
5753 | |
5754 | enum |
5755 | { |
5756 | DROP_HOME, |
5757 | DROP_RIGHT, |
5758 | DROP_LEFT, |
5759 | DROP_END |
5760 | }; |
5761 | |
5762 | /* returns 0x1 when no column has been found -- yes it's hackish */ |
5763 | static CtkTreeViewColumn * |
5764 | ctk_tree_view_get_drop_column (CtkTreeView *tree_view, |
5765 | CtkTreeViewColumn *column, |
5766 | gint drop_position) |
5767 | { |
5768 | CtkTreeViewColumn *left_column = NULL((void*)0); |
5769 | CtkTreeViewColumn *cur_column = NULL((void*)0); |
5770 | GList *tmp_list; |
5771 | |
5772 | if (!ctk_tree_view_column_get_reorderable (column)) |
5773 | return (CtkTreeViewColumn *)0x1; |
5774 | |
5775 | switch (drop_position) |
5776 | { |
5777 | case DROP_HOME: |
5778 | /* find first column where we can drop */ |
5779 | tmp_list = tree_view->priv->columns; |
5780 | if (column == CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ()))))))) |
5781 | return (CtkTreeViewColumn *)0x1; |
5782 | |
5783 | while (tmp_list) |
5784 | { |
5785 | g_assert (tmp_list)do { if (tmp_list) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c" , 5785, ((const char*) (__func__)), "tmp_list"); } while (0); |
5786 | |
5787 | cur_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
5788 | tmp_list = tmp_list->next; |
5789 | |
5790 | if (left_column && |
5791 | ctk_tree_view_column_get_visible (left_column) == FALSE(0)) |
5792 | continue; |
5793 | |
5794 | if (!tree_view->priv->column_drop_func) |
5795 | return left_column; |
5796 | |
5797 | if (!tree_view->priv->column_drop_func (tree_view, column, left_column, cur_column, tree_view->priv->column_drop_func_data)) |
5798 | { |
5799 | left_column = cur_column; |
5800 | continue; |
5801 | } |
5802 | |
5803 | return left_column; |
5804 | } |
5805 | |
5806 | if (!tree_view->priv->column_drop_func) |
5807 | return left_column; |
5808 | |
5809 | if (tree_view->priv->column_drop_func (tree_view, column, left_column, NULL((void*)0), tree_view->priv->column_drop_func_data)) |
5810 | return left_column; |
5811 | else |
5812 | return (CtkTreeViewColumn *)0x1; |
5813 | break; |
5814 | |
5815 | case DROP_RIGHT: |
5816 | /* find first column after column where we can drop */ |
5817 | tmp_list = tree_view->priv->columns; |
5818 | |
5819 | for (; tmp_list; tmp_list = tmp_list->next) |
5820 | if (CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))) == column) |
5821 | break; |
5822 | |
5823 | if (!tmp_list || !tmp_list->next) |
5824 | return (CtkTreeViewColumn *)0x1; |
5825 | |
5826 | tmp_list = tmp_list->next; |
5827 | left_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
5828 | tmp_list = tmp_list->next; |
5829 | |
5830 | while (tmp_list) |
5831 | { |
5832 | g_assert (tmp_list)do { if (tmp_list) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c" , 5832, ((const char*) (__func__)), "tmp_list"); } while (0); |
5833 | |
5834 | cur_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
5835 | tmp_list = tmp_list->next; |
5836 | |
5837 | if (left_column && |
5838 | ctk_tree_view_column_get_visible (left_column) == FALSE(0)) |
5839 | { |
5840 | left_column = cur_column; |
5841 | if (tmp_list) |
5842 | tmp_list = tmp_list->next; |
5843 | continue; |
5844 | } |
5845 | |
5846 | if (!tree_view->priv->column_drop_func) |
5847 | return left_column; |
5848 | |
5849 | if (!tree_view->priv->column_drop_func (tree_view, column, left_column, cur_column, tree_view->priv->column_drop_func_data)) |
5850 | { |
5851 | left_column = cur_column; |
5852 | continue; |
5853 | } |
5854 | |
5855 | return left_column; |
5856 | } |
5857 | |
5858 | if (!tree_view->priv->column_drop_func) |
5859 | return left_column; |
5860 | |
5861 | if (tree_view->priv->column_drop_func (tree_view, column, left_column, NULL((void*)0), tree_view->priv->column_drop_func_data)) |
5862 | return left_column; |
5863 | else |
5864 | return (CtkTreeViewColumn *)0x1; |
5865 | break; |
5866 | |
5867 | case DROP_LEFT: |
5868 | /* find first column before column where we can drop */ |
5869 | tmp_list = tree_view->priv->columns; |
5870 | |
5871 | for (; tmp_list; tmp_list = tmp_list->next) |
5872 | if (CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))) == column) |
5873 | break; |
5874 | |
5875 | if (!tmp_list || !tmp_list->prev) |
5876 | return (CtkTreeViewColumn *)0x1; |
5877 | |
5878 | tmp_list = tmp_list->prev; |
5879 | cur_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
5880 | tmp_list = tmp_list->prev; |
5881 | |
5882 | while (tmp_list) |
5883 | { |
5884 | g_assert (tmp_list)do { if (tmp_list) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c" , 5884, ((const char*) (__func__)), "tmp_list"); } while (0); |
5885 | |
5886 | left_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
5887 | |
5888 | if (left_column && |
5889 | ctk_tree_view_column_get_visible (left_column) == FALSE(0)) |
5890 | { |
5891 | /*if (!tmp_list->prev) |
5892 | return (CtkTreeViewColumn *)0x1; |
5893 | */ |
5894 | /* |
5895 | cur_column = CTK_TREE_VIEW_COLUMN (tmp_list->prev->data); |
5896 | tmp_list = tmp_list->prev->prev; |
5897 | continue;*/ |
5898 | |
5899 | cur_column = left_column; |
5900 | if (tmp_list) |
5901 | tmp_list = tmp_list->prev; |
5902 | continue; |
5903 | } |
5904 | |
5905 | if (!tree_view->priv->column_drop_func) |
5906 | return left_column; |
5907 | |
5908 | if (tree_view->priv->column_drop_func (tree_view, column, left_column, cur_column, tree_view->priv->column_drop_func_data)) |
5909 | return left_column; |
5910 | |
5911 | cur_column = left_column; |
5912 | tmp_list = tmp_list->prev; |
5913 | } |
5914 | |
5915 | if (!tree_view->priv->column_drop_func) |
5916 | return NULL((void*)0); |
5917 | |
5918 | if (tree_view->priv->column_drop_func (tree_view, column, NULL((void*)0), cur_column, tree_view->priv->column_drop_func_data)) |
5919 | return NULL((void*)0); |
5920 | else |
5921 | return (CtkTreeViewColumn *)0x1; |
5922 | break; |
5923 | |
5924 | case DROP_END: |
5925 | /* same as DROP_HOME case, but doing it backwards */ |
5926 | tmp_list = g_list_last (tree_view->priv->columns); |
5927 | cur_column = NULL((void*)0); |
5928 | |
5929 | if (column == CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ()))))))) |
5930 | return (CtkTreeViewColumn *)0x1; |
5931 | |
5932 | while (tmp_list) |
5933 | { |
5934 | g_assert (tmp_list)do { if (tmp_list) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c" , 5934, ((const char*) (__func__)), "tmp_list"); } while (0); |
5935 | |
5936 | left_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
5937 | |
5938 | if (left_column && |
5939 | ctk_tree_view_column_get_visible (left_column) == FALSE(0)) |
5940 | { |
5941 | cur_column = left_column; |
5942 | tmp_list = tmp_list->prev; |
5943 | } |
5944 | |
5945 | if (!tree_view->priv->column_drop_func) |
5946 | return left_column; |
5947 | |
5948 | if (tree_view->priv->column_drop_func (tree_view, column, left_column, cur_column, tree_view->priv->column_drop_func_data)) |
5949 | return left_column; |
5950 | |
5951 | cur_column = left_column; |
5952 | tmp_list = tmp_list->prev; |
5953 | } |
5954 | |
5955 | if (!tree_view->priv->column_drop_func) |
5956 | return NULL((void*)0); |
5957 | |
5958 | if (tree_view->priv->column_drop_func (tree_view, column, NULL((void*)0), cur_column, tree_view->priv->column_drop_func_data)) |
5959 | return NULL((void*)0); |
5960 | else |
5961 | return (CtkTreeViewColumn *)0x1; |
5962 | break; |
5963 | } |
5964 | |
5965 | return (CtkTreeViewColumn *)0x1; |
5966 | } |
5967 | |
5968 | static gboolean |
5969 | ctk_tree_view_search_key_cancels_search (guint keyval) |
5970 | { |
5971 | return keyval == CDK_KEY_Escape0xff1b |
5972 | || keyval == CDK_KEY_Tab0xff09 |
5973 | || keyval == CDK_KEY_KP_Tab0xff89 |
5974 | || keyval == CDK_KEY_ISO_Left_Tab0xfe20; |
5975 | } |
5976 | |
5977 | static gboolean |
5978 | ctk_tree_view_key_press (CtkWidget *widget, |
5979 | CdkEventKey *event) |
5980 | { |
5981 | CtkTreeView *tree_view = (CtkTreeView *) widget; |
5982 | CtkWidget *button; |
5983 | |
5984 | if (tree_view->priv->rubber_band_status) |
5985 | { |
5986 | if (event->keyval == CDK_KEY_Escape0xff1b) |
5987 | ctk_tree_view_stop_rubber_band (tree_view); |
5988 | |
5989 | return TRUE(!(0)); |
5990 | } |
5991 | |
5992 | if (tree_view->priv->in_column_drag) |
5993 | { |
5994 | if (event->keyval == CDK_KEY_Escape0xff1b) |
5995 | ctk_gesture_set_state (CTK_GESTURE (tree_view->priv->column_drag_gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->column_drag_gesture)), ((ctk_gesture_get_type ())))))), |
5996 | CTK_EVENT_SEQUENCE_DENIED); |
5997 | return TRUE(!(0)); |
5998 | } |
5999 | |
6000 | if (tree_view->priv->headers_visible) |
6001 | { |
6002 | GList *focus_column; |
6003 | gboolean rtl; |
6004 | |
6005 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
6006 | |
6007 | for (focus_column = tree_view->priv->columns; |
6008 | focus_column; |
6009 | focus_column = focus_column->next) |
6010 | { |
6011 | CtkTreeViewColumn *column = CTK_TREE_VIEW_COLUMN (focus_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((focus_column->data)), ((ctk_tree_view_column_get_type ())))))); |
6012 | |
6013 | button = ctk_tree_view_column_get_button (column); |
6014 | if (ctk_widget_has_focus (button)) |
6015 | break; |
6016 | } |
6017 | |
6018 | if (focus_column && |
6019 | (event->state & CDK_SHIFT_MASK) && (event->state & CDK_MOD1_MASK) && |
6020 | (event->keyval == CDK_KEY_Left0xff51 || event->keyval == CDK_KEY_KP_Left0xff96 |
6021 | || event->keyval == CDK_KEY_Right0xff53 || event->keyval == CDK_KEY_KP_Right0xff98)) |
6022 | { |
6023 | CtkTreeViewColumn *column = CTK_TREE_VIEW_COLUMN (focus_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((focus_column->data)), ((ctk_tree_view_column_get_type ())))))); |
6024 | gint column_width; |
6025 | |
6026 | if (!ctk_tree_view_column_get_resizable (column)) |
6027 | { |
6028 | ctk_widget_error_bell (widget); |
6029 | return TRUE(!(0)); |
6030 | } |
6031 | |
6032 | column_width = ctk_tree_view_column_get_width (column); |
6033 | |
6034 | if (event->keyval == (rtl ? CDK_KEY_Right0xff53 : CDK_KEY_Left0xff51) |
6035 | || event->keyval == (rtl ? CDK_KEY_KP_Right0xff98 : CDK_KEY_KP_Left0xff96)) |
6036 | { |
6037 | column_width = MAX (column_width - 2, 0)(((column_width - 2) > (0)) ? (column_width - 2) : (0)); |
6038 | } |
6039 | else if (event->keyval == (rtl ? CDK_KEY_Left0xff51 : CDK_KEY_Right0xff53) |
6040 | || event->keyval == (rtl ? CDK_KEY_KP_Left0xff96 : CDK_KEY_KP_Right0xff98)) |
6041 | { |
6042 | column_width = column_width + 2; |
6043 | } |
6044 | |
6045 | ctk_tree_view_column_set_fixed_width (column, column_width); |
6046 | ctk_tree_view_column_set_expand (column, FALSE(0)); |
6047 | return TRUE(!(0)); |
6048 | } |
6049 | |
6050 | if (focus_column && |
6051 | (event->state & CDK_MOD1_MASK) && |
6052 | (event->keyval == CDK_KEY_Left0xff51 || event->keyval == CDK_KEY_KP_Left0xff96 |
6053 | || event->keyval == CDK_KEY_Right0xff53 || event->keyval == CDK_KEY_KP_Right0xff98 |
6054 | || event->keyval == CDK_KEY_Home0xff50 || event->keyval == CDK_KEY_KP_Home0xff95 |
6055 | || event->keyval == CDK_KEY_End0xff57 || event->keyval == CDK_KEY_KP_End0xff9c)) |
6056 | { |
6057 | CtkTreeViewColumn *column = CTK_TREE_VIEW_COLUMN (focus_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((focus_column->data)), ((ctk_tree_view_column_get_type ())))))); |
6058 | |
6059 | if (event->keyval == (rtl ? CDK_KEY_Right0xff53 : CDK_KEY_Left0xff51) |
6060 | || event->keyval == (rtl ? CDK_KEY_KP_Right0xff98 : CDK_KEY_KP_Left0xff96)) |
6061 | { |
6062 | CtkTreeViewColumn *col; |
6063 | col = ctk_tree_view_get_drop_column (tree_view, column, DROP_LEFT); |
6064 | if (col != (CtkTreeViewColumn *)0x1) |
6065 | ctk_tree_view_move_column_after (tree_view, column, col); |
6066 | else |
6067 | ctk_widget_error_bell (widget); |
6068 | } |
6069 | else if (event->keyval == (rtl ? CDK_KEY_Left0xff51 : CDK_KEY_Right0xff53) |
6070 | || event->keyval == (rtl ? CDK_KEY_KP_Left0xff96 : CDK_KEY_KP_Right0xff98)) |
6071 | { |
6072 | CtkTreeViewColumn *col; |
6073 | col = ctk_tree_view_get_drop_column (tree_view, column, DROP_RIGHT); |
6074 | if (col != (CtkTreeViewColumn *)0x1) |
6075 | ctk_tree_view_move_column_after (tree_view, column, col); |
6076 | else |
6077 | ctk_widget_error_bell (widget); |
6078 | } |
6079 | else if (event->keyval == CDK_KEY_Home0xff50 || event->keyval == CDK_KEY_KP_Home0xff95) |
6080 | { |
6081 | CtkTreeViewColumn *col; |
6082 | col = ctk_tree_view_get_drop_column (tree_view, column, DROP_HOME); |
6083 | if (col != (CtkTreeViewColumn *)0x1) |
6084 | ctk_tree_view_move_column_after (tree_view, column, col); |
6085 | else |
6086 | ctk_widget_error_bell (widget); |
6087 | } |
6088 | else if (event->keyval == CDK_KEY_End0xff57 || event->keyval == CDK_KEY_KP_End0xff9c) |
6089 | { |
6090 | CtkTreeViewColumn *col; |
6091 | col = ctk_tree_view_get_drop_column (tree_view, column, DROP_END); |
6092 | if (col != (CtkTreeViewColumn *)0x1) |
6093 | ctk_tree_view_move_column_after (tree_view, column, col); |
6094 | else |
6095 | ctk_widget_error_bell (widget); |
6096 | } |
6097 | |
6098 | return TRUE(!(0)); |
6099 | } |
6100 | } |
6101 | |
6102 | /* Chain up to the parent class. It handles the keybindings. */ |
6103 | if (CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->key_press_event (widget, event)) |
6104 | return TRUE(!(0)); |
6105 | |
6106 | if (tree_view->priv->search_entry_avoid_unhandled_binding) |
6107 | { |
6108 | tree_view->priv->search_entry_avoid_unhandled_binding = FALSE(0); |
6109 | return FALSE(0); |
6110 | } |
6111 | |
6112 | /* Initially, before the search window is visible, we pass the event to the |
6113 | * IM context of the search entry box. If it triggers a commit or a preedit, |
6114 | * we then show the search window without loosing tree view focus. |
6115 | * If the seach window is already visible, we forward the events to it, |
6116 | * keeping the focus on the tree view. |
6117 | */ |
6118 | if (ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) |
6119 | && tree_view->priv->enable_search |
6120 | && !tree_view->priv->search_custom_entry_set |
6121 | && !ctk_tree_view_search_key_cancels_search (event->keyval)) |
6122 | { |
6123 | CtkWidget *search_window; |
6124 | |
6125 | ctk_tree_view_ensure_interactive_directory (tree_view); |
6126 | |
6127 | search_window = tree_view->priv->search_window; |
6128 | if (!ctk_widget_is_visible (search_window)) |
6129 | { |
6130 | CtkIMContext *im_context = |
6131 | _ctk_entry_get_im_context (CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ()))))))); |
6132 | |
6133 | tree_view->priv->imcontext_changed = FALSE(0); |
6134 | ctk_im_context_filter_keypress (im_context, event); |
6135 | |
6136 | if (tree_view->priv->imcontext_changed) |
6137 | { |
6138 | CdkDevice *device; |
6139 | |
6140 | device = cdk_event_get_device ((CdkEvent *) event); |
6141 | if (ctk_tree_view_real_start_interactive_search (tree_view, |
6142 | device, |
6143 | FALSE(0))) |
6144 | { |
6145 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
6146 | return TRUE(!(0)); |
6147 | } |
6148 | else |
6149 | { |
6150 | ctk_entry_set_text (CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ())))))), ""); |
6151 | return FALSE(0); |
6152 | } |
6153 | } |
6154 | } |
6155 | else |
6156 | { |
6157 | CdkEvent *new_event; |
6158 | gulong popup_menu_id; |
6159 | |
6160 | new_event = cdk_event_copy ((CdkEvent *) event); |
6161 | g_object_unref (((CdkEventKey *) new_event)->window); |
6162 | ((CdkEventKey *) new_event)->window = |
6163 | g_object_ref (ctk_widget_get_window (search_window))((__typeof__ (ctk_widget_get_window (search_window))) (g_object_ref ) (ctk_widget_get_window (search_window))); |
6164 | ctk_widget_realize (search_window); |
6165 | |
6166 | popup_menu_id = g_signal_connect (tree_view->priv->search_entry,g_signal_connect_data ((tree_view->priv->search_entry), ("popup-menu"), (((GCallback) (ctk_true))), (((void*)0)), (( void*)0), (GConnectFlags) 0) |
6167 | "popup-menu", G_CALLBACK (ctk_true),g_signal_connect_data ((tree_view->priv->search_entry), ("popup-menu"), (((GCallback) (ctk_true))), (((void*)0)), (( void*)0), (GConnectFlags) 0) |
6168 | NULL)g_signal_connect_data ((tree_view->priv->search_entry), ("popup-menu"), (((GCallback) (ctk_true))), (((void*)0)), (( void*)0), (GConnectFlags) 0); |
6169 | |
6170 | /* Because we keep the focus on the treeview, we need to forward the |
6171 | * key events to the entry, when it is visible. */ |
6172 | ctk_widget_event (search_window, new_event); |
6173 | cdk_event_free (new_event); |
6174 | |
6175 | g_signal_handler_disconnect (tree_view->priv->search_entry, |
6176 | popup_menu_id); |
6177 | |
6178 | } |
6179 | } |
6180 | |
6181 | return FALSE(0); |
6182 | } |
6183 | |
6184 | static gboolean |
6185 | ctk_tree_view_key_release (CtkWidget *widget, |
6186 | CdkEventKey *event) |
6187 | { |
6188 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
6189 | |
6190 | if (tree_view->priv->rubber_band_status) |
6191 | return TRUE(!(0)); |
6192 | |
6193 | return CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->key_release_event (widget, event); |
6194 | } |
6195 | |
6196 | /* FIXME Is this function necessary? Can I get an enter_notify event |
6197 | * w/o either an expose event or a mouse motion event? |
6198 | */ |
6199 | static gboolean |
6200 | ctk_tree_view_enter_notify (CtkWidget *widget, |
6201 | CdkEventCrossing *event) |
6202 | { |
6203 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
6204 | CtkRBTree *tree; |
6205 | CtkRBNode *node; |
6206 | gint new_y; |
6207 | |
6208 | /* Sanity check it */ |
6209 | if (event->window != tree_view->priv->bin_window) |
6210 | return FALSE(0); |
6211 | |
6212 | if (tree_view->priv->tree == NULL((void*)0)) |
6213 | return FALSE(0); |
6214 | |
6215 | /* find the node internally */ |
6216 | new_y = TREE_WINDOW_Y_TO_RBTREE_Y(tree_view, event->y)((event->y) + tree_view->priv->dy); |
6217 | if (new_y < 0) |
6218 | new_y = 0; |
6219 | _ctk_rbtree_find_offset (tree_view->priv->tree, new_y, &tree, &node); |
6220 | |
6221 | tree_view->priv->event_last_x = event->x; |
6222 | tree_view->priv->event_last_y = event->y; |
6223 | |
6224 | if ((tree_view->priv->button_pressed_node == NULL((void*)0)) || |
6225 | (tree_view->priv->button_pressed_node == node)) |
6226 | prelight_or_select (tree_view, tree, node, event->x, event->y); |
6227 | |
6228 | return TRUE(!(0)); |
6229 | } |
6230 | |
6231 | static gboolean |
6232 | ctk_tree_view_leave_notify (CtkWidget *widget, |
6233 | CdkEventCrossing *event G_GNUC_UNUSED__attribute__ ((__unused__))) |
6234 | { |
6235 | CtkTreeView *tree_view; |
6236 | |
6237 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
6238 | |
6239 | if (tree_view->priv->prelight_node) |
6240 | _ctk_tree_view_queue_draw_node (tree_view, |
6241 | tree_view->priv->prelight_tree, |
6242 | tree_view->priv->prelight_node, |
6243 | NULL((void*)0)); |
6244 | |
6245 | tree_view->priv->event_last_x = -10000; |
6246 | tree_view->priv->event_last_y = -10000; |
6247 | |
6248 | prelight_or_select (tree_view, |
6249 | NULL((void*)0), NULL((void*)0), |
6250 | -1000, -1000); /* coords not possibly over an arrow */ |
6251 | |
6252 | return TRUE(!(0)); |
6253 | } |
6254 | |
6255 | |
6256 | static gint |
6257 | ctk_tree_view_focus_out (CtkWidget *widget, |
6258 | CdkEventFocus *event) |
6259 | { |
6260 | CtkTreeView *tree_view; |
6261 | |
6262 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
6263 | |
6264 | ctk_widget_queue_draw (widget); |
6265 | |
6266 | /* destroy interactive search dialog */ |
6267 | if (tree_view->priv->search_window) |
6268 | ctk_tree_view_search_window_hide (tree_view->priv->search_window, tree_view, |
6269 | cdk_event_get_device ((CdkEvent *) event)); |
6270 | return FALSE(0); |
6271 | } |
6272 | |
6273 | |
6274 | /* Incremental Reflow |
6275 | */ |
6276 | |
6277 | static void |
6278 | ctk_tree_view_node_queue_redraw (CtkTreeView *tree_view, |
6279 | CtkRBTree *tree, |
6280 | CtkRBNode *node) |
6281 | { |
6282 | CdkRectangle rect; |
6283 | |
6284 | rect.x = 0; |
6285 | rect.y = |
6286 | _ctk_rbtree_node_find_offset (tree, node) |
6287 | - ctk_adjustment_get_value (tree_view->priv->vadjustment); |
6288 | rect.width = ctk_widget_get_allocated_width (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
6289 | rect.height = CTK_RBNODE_GET_HEIGHT (node)(node->offset-(node->left->offset+node->right-> offset+(node->children?node->children->root->offset :0))); |
6290 | |
6291 | cdk_window_invalidate_rect (tree_view->priv->bin_window, |
6292 | &rect, TRUE(!(0))); |
6293 | } |
6294 | |
6295 | static gboolean |
6296 | node_is_visible (CtkTreeView *tree_view, |
6297 | CtkRBTree *tree, |
6298 | CtkRBNode *node) |
6299 | { |
6300 | int y; |
6301 | int height; |
6302 | |
6303 | y = _ctk_rbtree_node_find_offset (tree, node); |
6304 | height = ctk_tree_view_get_row_height (tree_view, node); |
6305 | |
6306 | if (y >= ctk_adjustment_get_value (tree_view->priv->vadjustment) && |
6307 | y + height <= (ctk_adjustment_get_value (tree_view->priv->vadjustment) |
6308 | + ctk_adjustment_get_page_size (tree_view->priv->vadjustment))) |
6309 | return TRUE(!(0)); |
6310 | |
6311 | return FALSE(0); |
6312 | } |
6313 | |
6314 | static gint |
6315 | get_separator_height (CtkTreeView *tree_view) |
6316 | { |
6317 | CtkStyleContext *context; |
6318 | CtkCssStyle *style; |
6319 | gdouble d; |
6320 | gint min_size; |
6321 | |
6322 | context = ctk_widget_get_style_context (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
6323 | ctk_style_context_save (context); |
6324 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_SEPARATOR"separator"); |
6325 | |
6326 | style = ctk_style_context_lookup_style (context); |
6327 | d = _ctk_css_number_value_get |
6328 | (ctk_css_style_get_value (style, CTK_CSS_PROPERTY_MIN_HEIGHT), 100); |
6329 | |
6330 | if (d < 1) |
6331 | min_size = ceil (d); |
6332 | else |
6333 | min_size = floor (d); |
6334 | |
6335 | ctk_style_context_restore (context); |
6336 | |
6337 | return min_size; |
6338 | } |
6339 | |
6340 | /* Returns TRUE if it updated the size |
6341 | */ |
6342 | static gboolean |
6343 | validate_row (CtkTreeView *tree_view, |
6344 | CtkRBTree *tree, |
6345 | CtkRBNode *node, |
6346 | CtkTreeIter *iter, |
6347 | CtkTreePath *path) |
6348 | { |
6349 | CtkTreeViewColumn *column; |
6350 | CtkStyleContext *context; |
6351 | GList *list, *first_column, *last_column; |
6352 | gint height = 0; |
6353 | gint horizontal_separator; |
6354 | gint vertical_separator; |
6355 | gint depth = ctk_tree_path_get_depth (path); |
6356 | gboolean retval = FALSE(0); |
6357 | gboolean is_separator = FALSE(0); |
6358 | gboolean draw_vgrid_lines, draw_hgrid_lines; |
6359 | gint grid_line_width; |
6360 | gint expander_size; |
6361 | |
6362 | /* double check the row needs validating */ |
6363 | if (! CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) && |
6364 | ! CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0))) |
6365 | return FALSE(0); |
6366 | |
6367 | is_separator = row_is_separator (tree_view, iter, NULL((void*)0)); |
6368 | |
6369 | ctk_widget_style_get (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
6370 | "horizontal-separator", &horizontal_separator, |
6371 | "vertical-separator", &vertical_separator, |
6372 | "grid-line-width", &grid_line_width, |
6373 | NULL((void*)0)); |
6374 | |
6375 | draw_vgrid_lines = |
6376 | tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_VERTICAL |
6377 | || tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_BOTH; |
6378 | draw_hgrid_lines = |
6379 | tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_HORIZONTAL |
6380 | || tree_view->priv->grid_lines == CTK_TREE_VIEW_GRID_LINES_BOTH; |
6381 | expander_size = ctk_tree_view_get_expander_size (tree_view); |
6382 | |
6383 | for (last_column = g_list_last (tree_view->priv->columns); |
6384 | last_column && |
6385 | !(ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (last_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((last_column->data)), ((ctk_tree_view_column_get_type ())))))))); |
6386 | last_column = last_column->prev) |
6387 | ; |
6388 | |
6389 | for (first_column = g_list_first (tree_view->priv->columns); |
6390 | first_column && |
6391 | !(ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (first_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((first_column->data)), ((ctk_tree_view_column_get_type ())))))))); |
6392 | first_column = first_column->next) |
6393 | ; |
6394 | |
6395 | context = ctk_widget_get_style_context (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
6396 | ctk_style_context_save (context); |
6397 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_CELL"cell"); |
6398 | |
6399 | for (list = tree_view->priv->columns; list; list = list->next) |
6400 | { |
6401 | gint padding = 0; |
6402 | gint original_width; |
6403 | gint new_width; |
6404 | gint row_height; |
6405 | |
6406 | column = list->data; |
6407 | |
6408 | if (!ctk_tree_view_column_get_visible (column)) |
6409 | continue; |
6410 | |
6411 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0)) && |
6412 | !_ctk_tree_view_column_cell_get_dirty (column)) |
6413 | continue; |
6414 | |
6415 | original_width = _ctk_tree_view_column_get_requested_width (column); |
6416 | |
6417 | ctk_tree_view_column_cell_set_cell_data (column, tree_view->priv->model, iter, |
6418 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
6419 | node->children?TRUE(!(0)):FALSE(0)); |
6420 | ctk_tree_view_column_cell_get_size (column, |
6421 | NULL((void*)0), NULL((void*)0), NULL((void*)0), |
6422 | NULL((void*)0), &row_height); |
6423 | |
6424 | if (is_separator) |
6425 | { |
6426 | height = get_separator_height (tree_view); |
6427 | /* ctk_tree_view_get_row_height() assumes separator nodes are > 0 */ |
6428 | height = MAX (height, 1)(((height) > (1)) ? (height) : (1)); |
6429 | } |
6430 | else |
6431 | { |
6432 | row_height += vertical_separator; |
6433 | height = MAX (height, row_height)(((height) > (row_height)) ? (height) : (row_height)); |
6434 | height = MAX (height, expander_size)(((height) > (expander_size)) ? (height) : (expander_size) ); |
6435 | } |
6436 | |
6437 | if (ctk_tree_view_is_expander_column (tree_view, column)) |
6438 | { |
6439 | padding += horizontal_separator + (depth - 1) * tree_view->priv->level_indentation; |
6440 | |
6441 | if (ctk_tree_view_draw_expanders (tree_view)) |
6442 | padding += depth * expander_size; |
6443 | } |
6444 | else |
6445 | padding += horizontal_separator; |
6446 | |
6447 | if (draw_vgrid_lines) |
6448 | { |
6449 | if (list->data == first_column || list->data == last_column) |
6450 | padding += grid_line_width / 2.0; |
6451 | else |
6452 | padding += grid_line_width; |
6453 | } |
6454 | |
6455 | /* Update the padding for the column */ |
6456 | _ctk_tree_view_column_push_padding (column, padding); |
6457 | new_width = _ctk_tree_view_column_get_requested_width (column); |
6458 | |
6459 | if (new_width > original_width) |
6460 | retval = TRUE(!(0)); |
6461 | } |
6462 | |
6463 | ctk_style_context_restore (context); |
6464 | |
6465 | if (draw_hgrid_lines) |
6466 | height += grid_line_width; |
6467 | |
6468 | if (height != CTK_RBNODE_GET_HEIGHT (node)(node->offset-(node->left->offset+node->right-> offset+(node->children?node->children->root->offset :0)))) |
6469 | { |
6470 | retval = TRUE(!(0)); |
6471 | _ctk_rbtree_node_set_height (tree, node, height); |
6472 | } |
6473 | _ctk_rbtree_node_mark_valid (tree, node); |
6474 | tree_view->priv->post_validation_flag = TRUE(!(0)); |
6475 | |
6476 | return retval; |
6477 | } |
6478 | |
6479 | |
6480 | static void |
6481 | validate_visible_area (CtkTreeView *tree_view) |
6482 | { |
6483 | CtkAllocation allocation; |
6484 | CtkTreePath *path = NULL((void*)0); |
6485 | CtkTreePath *above_path = NULL((void*)0); |
6486 | CtkTreeIter iter; |
6487 | CtkRBTree *tree = NULL((void*)0); |
6488 | CtkRBNode *node = NULL((void*)0); |
6489 | gboolean need_redraw = FALSE(0); |
6490 | gboolean size_changed = FALSE(0); |
6491 | gint total_height; |
6492 | gint area_above = 0; |
6493 | gint area_below = 0; |
6494 | |
6495 | if (tree_view->priv->tree == NULL((void*)0)) |
6496 | return; |
6497 | |
6498 | if (! CTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, CTK_RBNODE_DESCENDANTS_INVALID)(tree_view->priv->tree->root?(((tree_view->priv-> tree->root->flags&CTK_RBNODE_DESCENDANTS_INVALID)== CTK_RBNODE_DESCENDANTS_INVALID)?(!(0)):(0)):(0)) && |
6499 | tree_view->priv->scroll_to_path == NULL((void*)0)) |
6500 | return; |
6501 | |
6502 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
6503 | total_height = allocation.height - ctk_tree_view_get_effective_header_height (tree_view); |
6504 | |
6505 | if (total_height == 0) |
6506 | return; |
6507 | |
6508 | /* First, we check to see if we need to scroll anywhere |
6509 | */ |
6510 | if (tree_view->priv->scroll_to_path) |
6511 | { |
6512 | path = ctk_tree_row_reference_get_path (tree_view->priv->scroll_to_path); |
6513 | if (path && !_ctk_tree_view_find_node (tree_view, path, &tree, &node)) |
6514 | { |
6515 | /* we are going to scroll, and will update dy */ |
6516 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
6517 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) || |
6518 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0))) |
6519 | { |
6520 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
6521 | if (validate_row (tree_view, tree, node, &iter, path)) |
6522 | size_changed = TRUE(!(0)); |
6523 | } |
6524 | |
6525 | if (tree_view->priv->scroll_to_use_align) |
6526 | { |
6527 | gint height = ctk_tree_view_get_row_height (tree_view, node); |
6528 | area_above = (total_height - height) * |
6529 | tree_view->priv->scroll_to_row_align; |
6530 | area_below = total_height - area_above - height; |
6531 | area_above = MAX (area_above, 0)(((area_above) > (0)) ? (area_above) : (0)); |
6532 | area_below = MAX (area_below, 0)(((area_below) > (0)) ? (area_below) : (0)); |
6533 | } |
6534 | else |
6535 | { |
6536 | /* two cases: |
6537 | * 1) row not visible |
6538 | * 2) row visible |
6539 | */ |
6540 | gint dy; |
6541 | gint height = ctk_tree_view_get_row_height (tree_view, node); |
6542 | |
6543 | dy = _ctk_rbtree_node_find_offset (tree, node); |
6544 | |
6545 | if (dy >= ctk_adjustment_get_value (tree_view->priv->vadjustment) && |
6546 | dy + height <= (ctk_adjustment_get_value (tree_view->priv->vadjustment) |
6547 | + ctk_adjustment_get_page_size (tree_view->priv->vadjustment))) |
6548 | { |
6549 | /* row visible: keep the row at the same position */ |
6550 | area_above = dy - ctk_adjustment_get_value (tree_view->priv->vadjustment); |
6551 | area_below = (ctk_adjustment_get_value (tree_view->priv->vadjustment) + |
6552 | ctk_adjustment_get_page_size (tree_view->priv->vadjustment)) |
6553 | - dy - height; |
6554 | } |
6555 | else |
6556 | { |
6557 | /* row not visible */ |
6558 | if (dy >= 0 |
6559 | && dy + height <= ctk_adjustment_get_page_size (tree_view->priv->vadjustment)) |
6560 | { |
6561 | /* row at the beginning -- fixed */ |
6562 | area_above = dy; |
6563 | area_below = ctk_adjustment_get_page_size (tree_view->priv->vadjustment) |
6564 | - area_above - height; |
6565 | } |
6566 | else if (dy >= (ctk_adjustment_get_upper (tree_view->priv->vadjustment) - |
6567 | ctk_adjustment_get_page_size (tree_view->priv->vadjustment))) |
6568 | { |
6569 | /* row at the end -- fixed */ |
6570 | area_above = dy - (ctk_adjustment_get_upper (tree_view->priv->vadjustment) - |
6571 | ctk_adjustment_get_page_size (tree_view->priv->vadjustment)); |
6572 | area_below = ctk_adjustment_get_page_size (tree_view->priv->vadjustment) - |
6573 | area_above - height; |
6574 | |
6575 | if (area_below < 0) |
6576 | { |
6577 | area_above = ctk_adjustment_get_page_size (tree_view->priv->vadjustment) - height; |
6578 | area_below = 0; |
6579 | } |
6580 | } |
6581 | else |
6582 | { |
6583 | /* row somewhere in the middle, bring it to the top |
6584 | * of the view |
6585 | */ |
6586 | area_above = 0; |
6587 | area_below = total_height - height; |
6588 | } |
6589 | } |
6590 | } |
6591 | } |
6592 | else |
6593 | /* the scroll to isn't valid; ignore it. |
6594 | */ |
6595 | { |
6596 | if (tree_view->priv->scroll_to_path && !path) |
6597 | { |
6598 | ctk_tree_row_reference_free (tree_view->priv->scroll_to_path); |
6599 | tree_view->priv->scroll_to_path = NULL((void*)0); |
6600 | } |
6601 | if (path) |
6602 | ctk_tree_path_free (path); |
6603 | path = NULL((void*)0); |
6604 | } |
6605 | } |
6606 | |
6607 | /* We didn't have a scroll_to set, so we just handle things normally |
6608 | */ |
6609 | if (path == NULL((void*)0)) |
6610 | { |
6611 | gint offset; |
6612 | |
6613 | offset = _ctk_rbtree_find_offset (tree_view->priv->tree, |
6614 | TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, 0)((0) + tree_view->priv->dy), |
6615 | &tree, &node); |
6616 | if (node == NULL((void*)0)) |
6617 | { |
6618 | /* In this case, nothing has been validated */ |
6619 | path = ctk_tree_path_new_first (); |
6620 | _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
6621 | } |
6622 | else |
6623 | { |
6624 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
6625 | total_height += offset; |
6626 | } |
6627 | |
6628 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
6629 | |
6630 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) || |
6631 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0))) |
6632 | { |
6633 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
6634 | if (validate_row (tree_view, tree, node, &iter, path)) |
6635 | size_changed = TRUE(!(0)); |
6636 | } |
6637 | area_above = 0; |
6638 | area_below = total_height - ctk_tree_view_get_row_height (tree_view, node); |
6639 | } |
6640 | |
6641 | above_path = ctk_tree_path_copy (path); |
6642 | |
6643 | /* if we do not validate any row above the new top_row, we will make sure |
6644 | * that the row immediately above top_row has been validated. (if we do not |
6645 | * do this, _ctk_rbtree_find_offset will find the row above top_row, because |
6646 | * when invalidated that row's height will be zero. and this will mess up |
6647 | * scrolling). |
6648 | */ |
6649 | if (area_above == 0) |
6650 | { |
6651 | CtkRBTree *tmptree; |
6652 | CtkRBNode *tmpnode; |
6653 | |
6654 | _ctk_tree_view_find_node (tree_view, above_path, &tmptree, &tmpnode); |
6655 | _ctk_rbtree_prev_full (tmptree, tmpnode, &tmptree, &tmpnode); |
6656 | |
6657 | if (tmpnode) |
6658 | { |
6659 | CtkTreePath *tmppath; |
6660 | CtkTreeIter tmpiter; |
6661 | |
6662 | tmppath = _ctk_tree_path_new_from_rbtree (tmptree, tmpnode); |
6663 | ctk_tree_model_get_iter (tree_view->priv->model, &tmpiter, tmppath); |
6664 | |
6665 | if (CTK_RBNODE_FLAG_SET (tmpnode, CTK_RBNODE_INVALID)(tmpnode?(((tmpnode->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) || |
6666 | CTK_RBNODE_FLAG_SET (tmpnode, CTK_RBNODE_COLUMN_INVALID)(tmpnode?(((tmpnode->flags&CTK_RBNODE_COLUMN_INVALID)== CTK_RBNODE_COLUMN_INVALID)?(!(0)):(0)):(0))) |
6667 | { |
6668 | _ctk_tree_view_queue_draw_node (tree_view, tmptree, tmpnode, NULL((void*)0)); |
6669 | if (validate_row (tree_view, tmptree, tmpnode, &tmpiter, tmppath)) |
6670 | size_changed = TRUE(!(0)); |
6671 | } |
6672 | |
6673 | ctk_tree_path_free (tmppath); |
6674 | } |
6675 | } |
6676 | |
6677 | /* Now, we walk forwards and backwards, measuring rows. Unfortunately, |
6678 | * backwards is much slower then forward, as there is no iter_prev function. |
6679 | * We go forwards first in case we run out of tree. Then we go backwards to |
6680 | * fill out the top. |
6681 | */ |
6682 | while (node && area_below > 0) |
6683 | { |
6684 | if (node->children) |
6685 | { |
6686 | CtkTreeIter parent = iter; |
6687 | gboolean has_child; |
6688 | |
6689 | tree = node->children; |
6690 | node = _ctk_rbtree_first (tree); |
6691 | |
6692 | has_child = ctk_tree_model_iter_children (tree_view->priv->model, |
6693 | &iter, |
6694 | &parent); |
6695 | TREE_VIEW_INTERNAL_ASSERT_VOID (has_child)do{ if (!(has_child)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "6695", ((const char* ) (__func__)), "has_child"); return; }; }while (0); |
6696 | ctk_tree_path_down (path); |
6697 | } |
6698 | else |
6699 | { |
6700 | gboolean done = FALSE(0); |
6701 | do |
6702 | { |
6703 | node = _ctk_rbtree_next (tree, node); |
6704 | if (node != NULL((void*)0)) |
6705 | { |
6706 | gboolean has_next = ctk_tree_model_iter_next (tree_view->priv->model, &iter); |
6707 | done = TRUE(!(0)); |
6708 | ctk_tree_path_next (path); |
6709 | |
6710 | /* Sanity Check! */ |
6711 | TREE_VIEW_INTERNAL_ASSERT_VOID (has_next)do{ if (!(has_next)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "6711", ((const char* ) (__func__)), "has_next"); return; }; }while (0); |
6712 | } |
6713 | else |
6714 | { |
6715 | CtkTreeIter parent_iter = iter; |
6716 | gboolean has_parent; |
6717 | |
6718 | node = tree->parent_node; |
6719 | tree = tree->parent_tree; |
6720 | if (tree == NULL((void*)0)) |
6721 | break; |
6722 | has_parent = ctk_tree_model_iter_parent (tree_view->priv->model, |
6723 | &iter, |
6724 | &parent_iter); |
6725 | ctk_tree_path_up (path); |
6726 | |
6727 | /* Sanity check */ |
6728 | TREE_VIEW_INTERNAL_ASSERT_VOID (has_parent)do{ if (!(has_parent)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "6728", ((const char* ) (__func__)), "has_parent"); return; }; }while (0); |
6729 | } |
6730 | } |
6731 | while (!done); |
6732 | } |
6733 | |
6734 | if (!node) |
6735 | break; |
6736 | |
6737 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) || |
6738 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0))) |
6739 | { |
6740 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
6741 | if (validate_row (tree_view, tree, node, &iter, path)) |
6742 | size_changed = TRUE(!(0)); |
6743 | } |
6744 | |
6745 | area_below -= ctk_tree_view_get_row_height (tree_view, node); |
6746 | } |
6747 | ctk_tree_path_free (path); |
6748 | |
6749 | /* If we ran out of tree, and have extra area_below left, we need to add it |
6750 | * to area_above */ |
6751 | if (area_below > 0) |
6752 | area_above += area_below; |
6753 | |
6754 | _ctk_tree_view_find_node (tree_view, above_path, &tree, &node); |
6755 | |
6756 | /* We walk backwards */ |
6757 | while (area_above > 0) |
6758 | { |
6759 | _ctk_rbtree_prev_full (tree, node, &tree, &node); |
6760 | |
6761 | /* Always find the new path in the tree. We cannot just assume |
6762 | * a ctk_tree_path_prev() is enough here, as there might be children |
6763 | * in between this node and the previous sibling node. If this |
6764 | * appears to be a performance hotspot in profiles, we can look into |
6765 | * intrigate logic for keeping path, node and iter in sync like |
6766 | * we do for forward walks. (Which will be hard because of the lacking |
6767 | * iter_prev). |
6768 | */ |
6769 | |
6770 | if (node == NULL((void*)0)) |
6771 | break; |
6772 | |
6773 | ctk_tree_path_free (above_path); |
6774 | above_path = _ctk_tree_path_new_from_rbtree (tree, node); |
6775 | |
6776 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, above_path); |
6777 | |
6778 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) || |
6779 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0))) |
6780 | { |
6781 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
6782 | if (validate_row (tree_view, tree, node, &iter, above_path)) |
6783 | size_changed = TRUE(!(0)); |
6784 | } |
6785 | area_above -= ctk_tree_view_get_row_height (tree_view, node); |
6786 | } |
6787 | |
6788 | /* if we scrolled to a path, we need to set the dy here, |
6789 | * and sync the top row accordingly |
6790 | */ |
6791 | if (tree_view->priv->scroll_to_path) |
6792 | { |
6793 | ctk_tree_view_set_top_row (tree_view, above_path, -area_above); |
6794 | ctk_tree_view_top_row_to_dy (tree_view); |
6795 | |
6796 | need_redraw = TRUE(!(0)); |
6797 | } |
6798 | else if (ctk_tree_view_get_height (tree_view) <= ctk_adjustment_get_page_size (tree_view->priv->vadjustment)) |
6799 | { |
6800 | /* when we are not scrolling, we should never set dy to something |
6801 | * else than zero. we update top_row to be in sync with dy = 0. |
6802 | */ |
6803 | ctk_adjustment_set_value (CTK_ADJUSTMENT (tree_view->priv->vadjustment)((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->vadjustment)), ((ctk_adjustment_get_type ())))))), 0); |
6804 | ctk_tree_view_dy_to_top_row (tree_view); |
6805 | } |
6806 | else if (ctk_adjustment_get_value (tree_view->priv->vadjustment) + ctk_adjustment_get_page_size (tree_view->priv->vadjustment) > ctk_tree_view_get_height (tree_view)) |
6807 | { |
6808 | ctk_adjustment_set_value (CTK_ADJUSTMENT (tree_view->priv->vadjustment)((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->vadjustment)), ((ctk_adjustment_get_type ())))))), ctk_tree_view_get_height (tree_view) - ctk_adjustment_get_page_size (tree_view->priv->vadjustment)); |
6809 | ctk_tree_view_dy_to_top_row (tree_view); |
6810 | } |
6811 | else |
6812 | ctk_tree_view_top_row_to_dy (tree_view); |
6813 | |
6814 | /* update width/height and queue a resize */ |
6815 | if (size_changed) |
6816 | { |
6817 | CtkRequisition requisition; |
6818 | |
6819 | /* We temporarily guess a size, under the assumption that it will be the |
6820 | * same when we get our next size_allocate. If we don't do this, we'll be |
6821 | * in an inconsistent state if we call top_row_to_dy. */ |
6822 | |
6823 | ctk_widget_get_preferred_size (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
6824 | &requisition, NULL((void*)0)); |
6825 | ctk_adjustment_set_upper (tree_view->priv->hadjustment, |
6826 | MAX (ctk_adjustment_get_upper (tree_view->priv->hadjustment), requisition.width)(((ctk_adjustment_get_upper (tree_view->priv->hadjustment )) > (requisition.width)) ? (ctk_adjustment_get_upper (tree_view ->priv->hadjustment)) : (requisition.width))); |
6827 | ctk_adjustment_set_upper (tree_view->priv->vadjustment, |
6828 | MAX (ctk_adjustment_get_upper (tree_view->priv->vadjustment), requisition.height)(((ctk_adjustment_get_upper (tree_view->priv->vadjustment )) > (requisition.height)) ? (ctk_adjustment_get_upper (tree_view ->priv->vadjustment)) : (requisition.height))); |
6829 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
6830 | } |
6831 | |
6832 | if (tree_view->priv->scroll_to_path) |
6833 | { |
6834 | ctk_tree_row_reference_free (tree_view->priv->scroll_to_path); |
6835 | tree_view->priv->scroll_to_path = NULL((void*)0); |
6836 | } |
6837 | |
6838 | if (above_path) |
6839 | ctk_tree_path_free (above_path); |
6840 | |
6841 | if (tree_view->priv->scroll_to_column) |
6842 | { |
6843 | tree_view->priv->scroll_to_column = NULL((void*)0); |
6844 | } |
6845 | if (need_redraw) |
6846 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
6847 | } |
6848 | |
6849 | static void |
6850 | initialize_fixed_height_mode (CtkTreeView *tree_view) |
6851 | { |
6852 | if (!tree_view->priv->tree) |
6853 | return; |
6854 | |
6855 | if (tree_view->priv->fixed_height < 0) |
6856 | { |
6857 | CtkTreeIter iter; |
6858 | CtkTreePath *path; |
6859 | |
6860 | CtkRBTree *tree = NULL((void*)0); |
6861 | CtkRBNode *node = NULL((void*)0); |
6862 | |
6863 | tree = tree_view->priv->tree; |
6864 | node = tree->root; |
6865 | |
6866 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
6867 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
6868 | |
6869 | validate_row (tree_view, tree, node, &iter, path); |
6870 | |
6871 | ctk_tree_path_free (path); |
6872 | |
6873 | tree_view->priv->fixed_height = ctk_tree_view_get_row_height (tree_view, node); |
6874 | } |
6875 | |
6876 | _ctk_rbtree_set_fixed_height (tree_view->priv->tree, |
6877 | tree_view->priv->fixed_height, TRUE(!(0))); |
6878 | } |
6879 | |
6880 | /* Our strategy for finding nodes to validate is a little convoluted. We find |
6881 | * the left-most uninvalidated node. We then try walking right, validating |
6882 | * nodes. Once we find a valid node, we repeat the previous process of finding |
6883 | * the first invalid node. |
6884 | */ |
6885 | |
6886 | static gboolean |
6887 | do_validate_rows (CtkTreeView *tree_view, gboolean queue_resize) |
6888 | { |
6889 | static gboolean prevent_recursion_hack = FALSE(0); |
6890 | |
6891 | CtkRBTree *tree = NULL((void*)0); |
6892 | CtkRBNode *node = NULL((void*)0); |
6893 | gboolean validated_area = FALSE(0); |
6894 | gint retval = TRUE(!(0)); |
6895 | CtkTreePath *path = NULL((void*)0); |
6896 | CtkTreeIter iter; |
6897 | GTimer *timer; |
6898 | gint i = 0; |
6899 | |
6900 | gint y = -1; |
6901 | gint prev_height = -1; |
6902 | gboolean fixed_height = TRUE(!(0)); |
6903 | |
6904 | g_assert (tree_view)do { if (tree_view) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c" , 6904, ((const char*) (__func__)), "tree_view"); } while (0); |
6905 | |
6906 | /* prevent infinite recursion via get_preferred_width() */ |
6907 | if (prevent_recursion_hack) |
6908 | return FALSE(0); |
6909 | |
6910 | if (tree_view->priv->tree == NULL((void*)0)) |
6911 | return FALSE(0); |
6912 | |
6913 | if (tree_view->priv->fixed_height_mode) |
6914 | { |
6915 | if (tree_view->priv->fixed_height < 0) |
6916 | initialize_fixed_height_mode (tree_view); |
6917 | |
6918 | return FALSE(0); |
6919 | } |
6920 | |
6921 | timer = g_timer_new (); |
6922 | g_timer_start (timer); |
6923 | |
6924 | do |
6925 | { |
6926 | gboolean changed = FALSE(0); |
6927 | |
6928 | if (! CTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, CTK_RBNODE_DESCENDANTS_INVALID)(tree_view->priv->tree->root?(((tree_view->priv-> tree->root->flags&CTK_RBNODE_DESCENDANTS_INVALID)== CTK_RBNODE_DESCENDANTS_INVALID)?(!(0)):(0)):(0))) |
6929 | { |
6930 | retval = FALSE(0); |
6931 | goto done; |
6932 | } |
6933 | |
6934 | if (path != NULL((void*)0)) |
6935 | { |
6936 | node = _ctk_rbtree_next (tree, node); |
6937 | if (node != NULL((void*)0)) |
6938 | { |
6939 | TREE_VIEW_INTERNAL_ASSERT (ctk_tree_model_iter_next (tree_view->priv->model, &iter), FALSE)do{ if (!(ctk_tree_model_iter_next (tree_view->priv->model , &iter))) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "6939", ((const char* ) (__func__)), "ctk_tree_model_iter_next (tree_view->priv->model, &iter)" ); return (0); }; }while (0); |
6940 | ctk_tree_path_next (path); |
6941 | } |
6942 | else |
6943 | { |
6944 | ctk_tree_path_free (path); |
6945 | path = NULL((void*)0); |
6946 | } |
6947 | } |
6948 | |
6949 | if (path == NULL((void*)0)) |
6950 | { |
6951 | tree = tree_view->priv->tree; |
6952 | node = tree_view->priv->tree->root; |
6953 | |
6954 | g_assert (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_DESCENDANTS_INVALID))do { if ((node?(((node->flags&CTK_RBNODE_DESCENDANTS_INVALID )==CTK_RBNODE_DESCENDANTS_INVALID)?(!(0)):(0)):(0))) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c", 6954, ((const char*) (__func__)), "CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_DESCENDANTS_INVALID)" ); } while (0); |
6955 | |
6956 | do |
6957 | { |
6958 | if (!_ctk_rbtree_is_nil (node->left) && |
6959 | CTK_RBNODE_FLAG_SET (node->left, CTK_RBNODE_DESCENDANTS_INVALID)(node->left?(((node->left->flags&CTK_RBNODE_DESCENDANTS_INVALID )==CTK_RBNODE_DESCENDANTS_INVALID)?(!(0)):(0)):(0))) |
6960 | { |
6961 | node = node->left; |
6962 | } |
6963 | else if (!_ctk_rbtree_is_nil (node->right) && |
6964 | CTK_RBNODE_FLAG_SET (node->right, CTK_RBNODE_DESCENDANTS_INVALID)(node->right?(((node->right->flags&CTK_RBNODE_DESCENDANTS_INVALID )==CTK_RBNODE_DESCENDANTS_INVALID)?(!(0)):(0)):(0))) |
6965 | { |
6966 | node = node->right; |
6967 | } |
6968 | else if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) || |
6969 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_COLUMN_INVALID)(node?(((node->flags&CTK_RBNODE_COLUMN_INVALID)==CTK_RBNODE_COLUMN_INVALID )?(!(0)):(0)):(0))) |
6970 | { |
6971 | break; |
6972 | } |
6973 | else if (node->children != NULL((void*)0)) |
6974 | { |
6975 | tree = node->children; |
6976 | node = tree->root; |
6977 | } |
6978 | else |
6979 | /* RBTree corruption! All bad */ |
6980 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctktreeview.c", 6980, ( (const char*) (__func__)), ((void*)0)); } while (0); |
6981 | } |
6982 | while (TRUE(!(0))); |
6983 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
6984 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
6985 | } |
6986 | |
6987 | changed = validate_row (tree_view, tree, node, &iter, path); |
6988 | validated_area = changed || validated_area; |
6989 | |
6990 | if (changed) |
6991 | { |
6992 | gint offset = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
6993 | |
6994 | if (y == -1 || y > offset) |
6995 | y = offset; |
6996 | } |
6997 | |
6998 | if (!tree_view->priv->fixed_height_check) |
6999 | { |
7000 | gint height; |
7001 | |
7002 | height = ctk_tree_view_get_row_height (tree_view, node); |
7003 | if (prev_height < 0) |
7004 | prev_height = height; |
7005 | else if (prev_height != height) |
7006 | fixed_height = FALSE(0); |
7007 | } |
7008 | |
7009 | i++; |
7010 | } |
7011 | while (g_timer_elapsed (timer, NULL((void*)0)) < CTK_TREE_VIEW_TIME_MS_PER_IDLE10 / 1000.); |
7012 | |
7013 | if (!tree_view->priv->fixed_height_check) |
7014 | { |
7015 | if (fixed_height) |
7016 | _ctk_rbtree_set_fixed_height (tree_view->priv->tree, prev_height, FALSE(0)); |
7017 | |
7018 | tree_view->priv->fixed_height_check = 1; |
7019 | } |
7020 | |
7021 | done: |
7022 | if (validated_area) |
7023 | { |
7024 | CtkRequisition requisition; |
7025 | gint dummy; |
7026 | |
7027 | /* We temporarily guess a size, under the assumption that it will be the |
7028 | * same when we get our next size_allocate. If we don't do this, we'll be |
7029 | * in an inconsistent state when we call top_row_to_dy. */ |
7030 | |
7031 | /* FIXME: This is called from size_request, for some reason it is not infinitely |
7032 | * recursing, we cannot call ctk_widget_get_preferred_size() here because that's |
7033 | * not allowed (from inside ->get_preferred_width/height() implementations, one |
7034 | * should call the vfuncs directly). However what is desired here is the full |
7035 | * size including any margins and limited by any alignment (i.e. after |
7036 | * CtkWidget:adjust_size_request() is called). |
7037 | * |
7038 | * Currently bypassing this but the real solution is to not update the scroll adjustments |
7039 | * untill we've recieved an allocation (never update scroll adjustments from size-requests). |
7040 | */ |
7041 | prevent_recursion_hack = TRUE(!(0)); |
7042 | ctk_tree_view_get_preferred_width (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &requisition.width, &dummy); |
7043 | ctk_tree_view_get_preferred_height (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &requisition.height, &dummy); |
7044 | prevent_recursion_hack = FALSE(0); |
7045 | |
7046 | /* If rows above the current position have changed height, this has |
7047 | * affected the current view and thus needs a redraw. |
7048 | */ |
7049 | if (y != -1 && y < ctk_adjustment_get_value (tree_view->priv->vadjustment)) |
7050 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
7051 | |
7052 | ctk_adjustment_set_upper (tree_view->priv->hadjustment, |
7053 | MAX (ctk_adjustment_get_upper (tree_view->priv->hadjustment), requisition.width)(((ctk_adjustment_get_upper (tree_view->priv->hadjustment )) > (requisition.width)) ? (ctk_adjustment_get_upper (tree_view ->priv->hadjustment)) : (requisition.width))); |
7054 | ctk_adjustment_set_upper (tree_view->priv->vadjustment, |
7055 | MAX (ctk_adjustment_get_upper (tree_view->priv->vadjustment), requisition.height)(((ctk_adjustment_get_upper (tree_view->priv->vadjustment )) > (requisition.height)) ? (ctk_adjustment_get_upper (tree_view ->priv->vadjustment)) : (requisition.height))); |
7056 | |
7057 | if (queue_resize) |
7058 | ctk_widget_queue_resize_no_redraw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
7059 | } |
7060 | |
7061 | if (path) ctk_tree_path_free (path); |
7062 | g_timer_destroy (timer); |
7063 | |
7064 | if (!retval && ctk_widget_get_mapped (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
7065 | update_prelight (tree_view, |
7066 | tree_view->priv->event_last_x, |
7067 | tree_view->priv->event_last_y); |
7068 | |
7069 | return retval; |
7070 | } |
7071 | |
7072 | static void |
7073 | disable_adjustment_animation (CtkTreeView *tree_view) |
7074 | { |
7075 | ctk_adjustment_enable_animation (tree_view->priv->vadjustment, |
7076 | NULL((void*)0), |
7077 | ctk_adjustment_get_animation_duration (tree_view->priv->vadjustment)); |
7078 | } |
7079 | |
7080 | static void |
7081 | maybe_reenable_adjustment_animation (CtkTreeView *tree_view) |
7082 | { |
7083 | if (tree_view->priv->presize_handler_tick_cb != 0 || |
7084 | tree_view->priv->validate_rows_timer != 0) |
7085 | return; |
7086 | |
7087 | ctk_adjustment_enable_animation (tree_view->priv->vadjustment, |
7088 | ctk_widget_get_frame_clock (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))), |
7089 | ctk_adjustment_get_animation_duration (tree_view->priv->vadjustment)); |
7090 | } |
7091 | |
7092 | static gboolean |
7093 | do_presize_handler (CtkTreeView *tree_view) |
7094 | { |
7095 | if (tree_view->priv->mark_rows_col_dirty) |
7096 | { |
7097 | if (tree_view->priv->tree) |
7098 | _ctk_rbtree_column_invalid (tree_view->priv->tree); |
7099 | tree_view->priv->mark_rows_col_dirty = FALSE(0); |
7100 | } |
7101 | validate_visible_area (tree_view); |
7102 | if (tree_view->priv->presize_handler_tick_cb != 0) |
7103 | { |
7104 | ctk_widget_remove_tick_callback (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->presize_handler_tick_cb); |
7105 | tree_view->priv->presize_handler_tick_cb = 0; |
7106 | } |
7107 | |
7108 | if (tree_view->priv->fixed_height_mode) |
7109 | { |
7110 | CtkRequisition requisition; |
7111 | |
7112 | ctk_widget_get_preferred_size (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
7113 | &requisition, NULL((void*)0)); |
7114 | |
7115 | ctk_adjustment_set_upper (tree_view->priv->hadjustment, |
7116 | MAX (ctk_adjustment_get_upper (tree_view->priv->hadjustment), requisition.width)(((ctk_adjustment_get_upper (tree_view->priv->hadjustment )) > (requisition.width)) ? (ctk_adjustment_get_upper (tree_view ->priv->hadjustment)) : (requisition.width))); |
7117 | ctk_adjustment_set_upper (tree_view->priv->vadjustment, |
7118 | MAX (ctk_adjustment_get_upper (tree_view->priv->vadjustment), requisition.height)(((ctk_adjustment_get_upper (tree_view->priv->vadjustment )) > (requisition.height)) ? (ctk_adjustment_get_upper (tree_view ->priv->vadjustment)) : (requisition.height))); |
7119 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
7120 | } |
7121 | |
7122 | maybe_reenable_adjustment_animation (tree_view); |
7123 | |
7124 | return FALSE(0); |
7125 | } |
7126 | |
7127 | static gboolean |
7128 | presize_handler_callback (CtkWidget *widget, |
7129 | CdkFrameClock *clock G_GNUC_UNUSED__attribute__ ((__unused__)), |
7130 | gpointer unused G_GNUC_UNUSED__attribute__ ((__unused__))) |
7131 | { |
7132 | do_presize_handler (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
7133 | |
7134 | return G_SOURCE_REMOVE(0); |
7135 | } |
7136 | |
7137 | static gboolean |
7138 | validate_rows (CtkTreeView *tree_view) |
7139 | { |
7140 | gboolean retval; |
7141 | |
7142 | if (tree_view->priv->presize_handler_tick_cb) |
7143 | { |
7144 | do_presize_handler (tree_view); |
7145 | return G_SOURCE_CONTINUE(!(0)); |
7146 | } |
7147 | |
7148 | retval = do_validate_rows (tree_view, TRUE(!(0))); |
7149 | |
7150 | if (! retval && tree_view->priv->validate_rows_timer) |
7151 | { |
7152 | g_source_remove (tree_view->priv->validate_rows_timer); |
7153 | tree_view->priv->validate_rows_timer = 0; |
7154 | maybe_reenable_adjustment_animation (tree_view); |
7155 | } |
7156 | |
7157 | return retval; |
7158 | } |
7159 | |
7160 | static void |
7161 | install_presize_handler (CtkTreeView *tree_view) |
7162 | { |
7163 | if (! ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
7164 | return; |
7165 | |
7166 | disable_adjustment_animation (tree_view); |
7167 | |
7168 | if (! tree_view->priv->presize_handler_tick_cb) |
7169 | { |
7170 | tree_view->priv->presize_handler_tick_cb = |
7171 | ctk_widget_add_tick_callback (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), presize_handler_callback, NULL((void*)0), NULL((void*)0)); |
7172 | } |
7173 | if (! tree_view->priv->validate_rows_timer) |
7174 | { |
7175 | tree_view->priv->validate_rows_timer = |
7176 | cdk_threads_add_idle_full (CTK_TREE_VIEW_PRIORITY_VALIDATE((100 + 20) + 5), (GSourceFunc) validate_rows, tree_view, NULL((void*)0)); |
7177 | g_source_set_name_by_id (tree_view->priv->validate_rows_timer, "[ctk+] validate_rows"); |
7178 | } |
7179 | } |
7180 | |
7181 | static gboolean |
7182 | scroll_sync_handler (CtkTreeView *tree_view) |
7183 | { |
7184 | if (ctk_tree_view_get_height (tree_view) <= ctk_adjustment_get_page_size (tree_view->priv->vadjustment)) |
7185 | ctk_adjustment_set_value (CTK_ADJUSTMENT (tree_view->priv->vadjustment)((((CtkAdjustment*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->vadjustment)), ((ctk_adjustment_get_type ())))))), 0); |
7186 | else if (ctk_tree_row_reference_valid (tree_view->priv->top_row)) |
7187 | ctk_tree_view_top_row_to_dy (tree_view); |
7188 | else |
7189 | ctk_tree_view_dy_to_top_row (tree_view); |
7190 | |
7191 | tree_view->priv->scroll_sync_timer = 0; |
7192 | |
7193 | return FALSE(0); |
7194 | } |
7195 | |
7196 | static void |
7197 | install_scroll_sync_handler (CtkTreeView *tree_view) |
7198 | { |
7199 | if (!ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
7200 | return; |
7201 | |
7202 | if (!tree_view->priv->scroll_sync_timer) |
7203 | { |
7204 | tree_view->priv->scroll_sync_timer = |
7205 | cdk_threads_add_idle_full (CTK_TREE_VIEW_PRIORITY_SCROLL_SYNC(((100 + 20) + 5) + 2), (GSourceFunc) scroll_sync_handler, tree_view, NULL((void*)0)); |
7206 | g_source_set_name_by_id (tree_view->priv->scroll_sync_timer, "[ctk+] scroll_sync_handler"); |
7207 | } |
7208 | } |
7209 | |
7210 | static void |
7211 | ctk_tree_view_set_top_row (CtkTreeView *tree_view, |
7212 | CtkTreePath *path, |
7213 | gint offset) |
7214 | { |
7215 | ctk_tree_row_reference_free (tree_view->priv->top_row); |
7216 | |
7217 | if (!path) |
7218 | { |
7219 | tree_view->priv->top_row = NULL((void*)0); |
7220 | tree_view->priv->top_row_dy = 0; |
7221 | } |
7222 | else |
7223 | { |
7224 | tree_view->priv->top_row = ctk_tree_row_reference_new_proxy (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view->priv->model, path); |
7225 | tree_view->priv->top_row_dy = offset; |
7226 | } |
7227 | } |
7228 | |
7229 | /* Always call this iff dy is in the visible range. If the tree is empty, then |
7230 | * it’s set to be NULL, and top_row_dy is 0; |
7231 | */ |
7232 | static void |
7233 | ctk_tree_view_dy_to_top_row (CtkTreeView *tree_view) |
7234 | { |
7235 | gint offset; |
7236 | CtkTreePath *path; |
7237 | CtkRBTree *tree; |
7238 | CtkRBNode *node; |
7239 | |
7240 | if (tree_view->priv->tree == NULL((void*)0)) |
7241 | { |
7242 | ctk_tree_view_set_top_row (tree_view, NULL((void*)0), 0); |
7243 | } |
7244 | else |
7245 | { |
7246 | offset = _ctk_rbtree_find_offset (tree_view->priv->tree, |
7247 | tree_view->priv->dy, |
7248 | &tree, &node); |
7249 | |
7250 | if (tree == NULL((void*)0)) |
7251 | { |
7252 | ctk_tree_view_set_top_row (tree_view, NULL((void*)0), 0); |
7253 | } |
7254 | else |
7255 | { |
7256 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
7257 | ctk_tree_view_set_top_row (tree_view, path, offset); |
7258 | ctk_tree_path_free (path); |
7259 | } |
7260 | } |
7261 | } |
7262 | |
7263 | static void |
7264 | ctk_tree_view_top_row_to_dy (CtkTreeView *tree_view) |
7265 | { |
7266 | CtkTreePath *path; |
7267 | CtkRBTree *tree; |
7268 | CtkRBNode *node; |
7269 | int new_dy; |
7270 | |
7271 | /* Avoid recursive calls */ |
7272 | if (tree_view->priv->in_top_row_to_dy) |
7273 | return; |
7274 | |
7275 | if (tree_view->priv->top_row) |
7276 | path = ctk_tree_row_reference_get_path (tree_view->priv->top_row); |
7277 | else |
7278 | path = NULL((void*)0); |
7279 | |
7280 | if (!path) |
7281 | tree = NULL((void*)0); |
7282 | else |
7283 | _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
7284 | |
7285 | if (path) |
7286 | ctk_tree_path_free (path); |
7287 | |
7288 | if (tree == NULL((void*)0)) |
7289 | { |
7290 | /* keep dy and set new toprow */ |
7291 | ctk_tree_row_reference_free (tree_view->priv->top_row); |
7292 | tree_view->priv->top_row = NULL((void*)0); |
7293 | tree_view->priv->top_row_dy = 0; |
7294 | /* DO NOT install the idle handler */ |
7295 | ctk_tree_view_dy_to_top_row (tree_view); |
7296 | return; |
7297 | } |
7298 | |
7299 | if (ctk_tree_view_get_row_height (tree_view, node) |
7300 | < tree_view->priv->top_row_dy) |
7301 | { |
7302 | /* new top row -- do NOT install the idle handler */ |
7303 | ctk_tree_view_dy_to_top_row (tree_view); |
7304 | return; |
7305 | } |
7306 | |
7307 | new_dy = _ctk_rbtree_node_find_offset (tree, node); |
7308 | new_dy += tree_view->priv->top_row_dy; |
7309 | |
7310 | if (new_dy + ctk_adjustment_get_page_size (tree_view->priv->vadjustment) > ctk_tree_view_get_height (tree_view)) |
7311 | new_dy = ctk_tree_view_get_height (tree_view) - ctk_adjustment_get_page_size (tree_view->priv->vadjustment); |
7312 | |
7313 | new_dy = MAX (0, new_dy)(((0) > (new_dy)) ? (0) : (new_dy)); |
7314 | |
7315 | tree_view->priv->in_top_row_to_dy = TRUE(!(0)); |
7316 | ctk_adjustment_set_value (tree_view->priv->vadjustment, (gdouble)new_dy); |
7317 | tree_view->priv->in_top_row_to_dy = FALSE(0); |
7318 | } |
7319 | |
7320 | |
7321 | void |
7322 | _ctk_tree_view_install_mark_rows_col_dirty (CtkTreeView *tree_view, |
7323 | gboolean install_handler) |
7324 | { |
7325 | tree_view->priv->mark_rows_col_dirty = TRUE(!(0)); |
7326 | |
7327 | if (install_handler) |
7328 | install_presize_handler (tree_view); |
7329 | } |
7330 | |
7331 | /* |
7332 | * This function works synchronously (due to the while (validate_rows...) |
7333 | * loop). |
7334 | * |
7335 | * There was a check for column_type != CTK_TREE_VIEW_COLUMN_AUTOSIZE |
7336 | * here. You now need to check that yourself. |
7337 | */ |
7338 | void |
7339 | _ctk_tree_view_column_autosize (CtkTreeView *tree_view, |
7340 | CtkTreeViewColumn *column) |
7341 | { |
7342 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
7343 | g_return_if_fail (CTK_IS_TREE_VIEW_COLUMN (column))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((column)); GType __t = ((ctk_tree_view_column_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_TREE_VIEW_COLUMN (column)"); return ; } } while (0); |
7344 | |
7345 | _ctk_tree_view_column_cell_set_dirty (column, FALSE(0)); |
7346 | |
7347 | do_presize_handler (tree_view); |
7348 | while (validate_rows (tree_view)); |
7349 | |
7350 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
7351 | } |
7352 | |
7353 | /* Drag-and-drop */ |
7354 | |
7355 | static void |
7356 | set_source_row (CdkDragContext *context, |
7357 | CtkTreeModel *model, |
7358 | CtkTreePath *source_row) |
7359 | { |
7360 | g_object_set_data_full (G_OBJECT (context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((context)), (((GType) ((20) << (2)))))))), |
7361 | I_("ctk-tree-view-source-row")g_intern_static_string ("ctk-tree-view-source-row"), |
7362 | source_row ? ctk_tree_row_reference_new (model, source_row) : NULL((void*)0), |
7363 | (GDestroyNotify) (source_row ? ctk_tree_row_reference_free : NULL((void*)0))); |
7364 | } |
7365 | |
7366 | static CtkTreePath* |
7367 | get_source_row (CdkDragContext *context) |
7368 | { |
7369 | CtkTreeRowReference *ref = |
7370 | g_object_get_data (G_OBJECT (context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((context)), (((GType) ((20) << (2)))))))), "ctk-tree-view-source-row"); |
7371 | |
7372 | if (ref) |
7373 | return ctk_tree_row_reference_get_path (ref); |
7374 | else |
7375 | return NULL((void*)0); |
7376 | } |
7377 | |
7378 | typedef struct |
7379 | { |
7380 | CtkTreeRowReference *dest_row; |
7381 | guint path_down_mode : 1; |
7382 | guint empty_view_drop : 1; |
7383 | guint drop_append_mode : 1; |
7384 | } |
7385 | DestRow; |
7386 | |
7387 | static void |
7388 | dest_row_free (gpointer data) |
7389 | { |
7390 | DestRow *dr = (DestRow *)data; |
7391 | |
7392 | ctk_tree_row_reference_free (dr->dest_row); |
7393 | g_slice_free (DestRow, dr)do { if (1) g_slice_free1 (sizeof (DestRow), (dr)); else (void ) ((DestRow*) 0 == (dr)); } while (0); |
7394 | } |
7395 | |
7396 | static void |
7397 | set_dest_row (CdkDragContext *context, |
7398 | CtkTreeModel *model, |
7399 | CtkTreePath *dest_row, |
7400 | gboolean path_down_mode, |
7401 | gboolean empty_view_drop, |
7402 | gboolean drop_append_mode) |
7403 | { |
7404 | DestRow *dr; |
7405 | |
7406 | if (!dest_row) |
7407 | { |
7408 | g_object_set_data_full (G_OBJECT (context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((context)), (((GType) ((20) << (2)))))))), I_("ctk-tree-view-dest-row")g_intern_static_string ("ctk-tree-view-dest-row"), |
7409 | NULL((void*)0), NULL((void*)0)); |
7410 | return; |
7411 | } |
7412 | |
7413 | dr = g_slice_new (DestRow)((DestRow*) g_slice_alloc (sizeof (DestRow))); |
7414 | |
7415 | dr->dest_row = ctk_tree_row_reference_new (model, dest_row); |
7416 | dr->path_down_mode = path_down_mode != FALSE(0); |
7417 | dr->empty_view_drop = empty_view_drop != FALSE(0); |
7418 | dr->drop_append_mode = drop_append_mode != FALSE(0); |
7419 | |
7420 | g_object_set_data_full (G_OBJECT (context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((context)), (((GType) ((20) << (2)))))))), I_("ctk-tree-view-dest-row")g_intern_static_string ("ctk-tree-view-dest-row"), |
7421 | dr, (GDestroyNotify) dest_row_free); |
7422 | } |
7423 | |
7424 | static CtkTreePath* |
7425 | get_dest_row (CdkDragContext *context, |
7426 | gboolean *path_down_mode) |
7427 | { |
7428 | DestRow *dr = |
7429 | g_object_get_data (G_OBJECT (context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((context)), (((GType) ((20) << (2)))))))), "ctk-tree-view-dest-row"); |
7430 | |
7431 | if (dr) |
7432 | { |
7433 | CtkTreePath *path = NULL((void*)0); |
7434 | |
7435 | if (path_down_mode) |
7436 | *path_down_mode = dr->path_down_mode; |
7437 | |
7438 | if (dr->dest_row) |
7439 | path = ctk_tree_row_reference_get_path (dr->dest_row); |
7440 | else if (dr->empty_view_drop) |
7441 | path = ctk_tree_path_new_from_indices (0, -1); |
7442 | else |
7443 | path = NULL((void*)0); |
7444 | |
7445 | if (path && dr->drop_append_mode) |
7446 | ctk_tree_path_next (path); |
7447 | |
7448 | return path; |
7449 | } |
7450 | else |
7451 | return NULL((void*)0); |
7452 | } |
7453 | |
7454 | /* Get/set whether drag_motion requested the drag data and |
7455 | * drag_data_received should thus not actually insert the data, |
7456 | * since the data doesn’t result from a drop. |
7457 | */ |
7458 | static void |
7459 | set_status_pending (CdkDragContext *context, |
7460 | CdkDragAction suggested_action) |
7461 | { |
7462 | g_object_set_data (G_OBJECT (context)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((context)), (((GType) ((20) << (2)))))))), |
7463 | I_("ctk-tree-view-status-pending")g_intern_static_string ("ctk-tree-view-status-pending"), |
7464 | GINT_TO_POINTER (suggested_action)((gpointer) (glong) (suggested_action))); |
7465 | } |
7466 | |
7467 | static CdkDragAction |
7468 | get_status_pending (CdkDragContext *context) |
7469 | { |
7470 | return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (context),((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((context)), (((GType) ((20) << (2)) )))))), "ctk-tree-view-status-pending"))) |
7471 | "ctk-tree-view-status-pending"))((gint) (glong) (g_object_get_data (((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((context)), (((GType) ((20) << (2)) )))))), "ctk-tree-view-status-pending"))); |
7472 | } |
7473 | |
7474 | static TreeViewDragInfo* |
7475 | get_info (CtkTreeView *tree_view) |
7476 | { |
7477 | return g_object_get_data (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), "ctk-tree-view-drag-info"); |
7478 | } |
7479 | |
7480 | static void |
7481 | destroy_info (TreeViewDragInfo *di) |
7482 | { |
7483 | g_slice_free (TreeViewDragInfo, di)do { if (1) g_slice_free1 (sizeof (TreeViewDragInfo), (di)); else (void) ((TreeViewDragInfo*) 0 == (di)); } while (0); |
7484 | } |
7485 | |
7486 | static TreeViewDragInfo* |
7487 | ensure_info (CtkTreeView *tree_view) |
7488 | { |
7489 | TreeViewDragInfo *di; |
7490 | |
7491 | di = get_info (tree_view); |
7492 | |
7493 | if (di == NULL((void*)0)) |
7494 | { |
7495 | di = g_slice_new0 (TreeViewDragInfo)((TreeViewDragInfo*) g_slice_alloc0 (sizeof (TreeViewDragInfo ))); |
7496 | |
7497 | g_object_set_data_full (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), |
7498 | I_("ctk-tree-view-drag-info")g_intern_static_string ("ctk-tree-view-drag-info"), |
7499 | di, |
7500 | (GDestroyNotify) destroy_info); |
7501 | } |
7502 | |
7503 | return di; |
7504 | } |
7505 | |
7506 | static void |
7507 | remove_info (CtkTreeView *tree_view) |
7508 | { |
7509 | g_object_set_data (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), I_("ctk-tree-view-drag-info")g_intern_static_string ("ctk-tree-view-drag-info"), NULL((void*)0)); |
7510 | } |
7511 | |
7512 | #if 0 |
7513 | static gint |
7514 | drag_scan_timeout (gpointer data) |
7515 | { |
7516 | CtkTreeView *tree_view; |
7517 | gint x, y; |
7518 | CdkModifierType state; |
7519 | CtkTreePath *path = NULL((void*)0); |
7520 | CtkTreeViewColumn *column = NULL((void*)0); |
7521 | CdkRectangle visible_rect; |
7522 | CdkSeat *seat; |
7523 | |
7524 | cdk_threads_enter (); |
7525 | |
7526 | tree_view = CTK_TREE_VIEW (data)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_view_get_type ())))))); |
7527 | |
7528 | seat = cdk_display_get_default_seat (ctk_widget_get_display (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))); |
7529 | cdk_window_get_device_position (tree_view->priv->bin_window, |
7530 | cdk_seat_get_pointer (seat), |
7531 | &x, &y, &state); |
7532 | |
7533 | ctk_tree_view_get_visible_rect (tree_view, &visible_rect); |
7534 | |
7535 | /* See if we are near the edge. */ |
7536 | if ((x - visible_rect.x) < SCROLL_EDGE_SIZE15 || |
7537 | (visible_rect.x + visible_rect.width - x) < SCROLL_EDGE_SIZE15 || |
7538 | (y - visible_rect.y) < SCROLL_EDGE_SIZE15 || |
7539 | (visible_rect.y + visible_rect.height - y) < SCROLL_EDGE_SIZE15) |
7540 | { |
7541 | ctk_tree_view_get_path_at_pos (tree_view, |
7542 | tree_view->priv->bin_window, |
7543 | x, y, |
7544 | &path, |
7545 | &column, |
7546 | NULL((void*)0), |
7547 | NULL((void*)0)); |
7548 | |
7549 | if (path != NULL((void*)0)) |
7550 | { |
7551 | ctk_tree_view_scroll_to_cell (tree_view, |
7552 | path, |
7553 | column, |
7554 | TRUE(!(0)), |
7555 | 0.5, 0.5); |
7556 | |
7557 | ctk_tree_path_free (path); |
7558 | } |
7559 | } |
7560 | |
7561 | cdk_threads_leave (); |
7562 | |
7563 | return TRUE(!(0)); |
7564 | } |
7565 | #endif /* 0 */ |
7566 | |
7567 | static void |
7568 | add_scroll_timeout (CtkTreeView *tree_view) |
7569 | { |
7570 | if (tree_view->priv->scroll_timeout == 0) |
7571 | { |
7572 | tree_view->priv->scroll_timeout = |
7573 | cdk_threads_add_timeout (150, scroll_row_timeout, tree_view); |
7574 | g_source_set_name_by_id (tree_view->priv->scroll_timeout, "[ctk+] scroll_row_timeout"); |
7575 | } |
7576 | } |
7577 | |
7578 | static void |
7579 | remove_scroll_timeout (CtkTreeView *tree_view) |
7580 | { |
7581 | if (tree_view->priv->scroll_timeout != 0) |
7582 | { |
7583 | g_source_remove (tree_view->priv->scroll_timeout); |
7584 | tree_view->priv->scroll_timeout = 0; |
7585 | } |
7586 | } |
7587 | |
7588 | static gboolean |
7589 | check_model_dnd (CtkTreeModel *model, |
7590 | GType required_iface, |
7591 | const gchar *signal) |
7592 | { |
7593 | if (model == NULL((void*)0) || !G_TYPE_CHECK_INSTANCE_TYPE ((model), required_iface)((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (model)); GType __t = (required_iface); gboolean __r; if (!__inst ) __r = (0); else if (__inst->g_class && __inst-> g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) |
7594 | { |
7595 | g_warning ("You must override the default '%s' handler " |
7596 | "on CtkTreeView when using models that don't support " |
7597 | "the %s interface and enabling drag-and-drop. The simplest way to do this " |
7598 | "is to connect to '%s' and call " |
7599 | "g_signal_stop_emission_by_name() in your signal handler to prevent " |
7600 | "the default handler from running. Look at the source code " |
7601 | "for the default handler in ctktreeview.c to get an idea what " |
7602 | "your handler should do. (ctktreeview.c is in the CTK source " |
7603 | "code.) If you're using CTK from a language other than C, " |
7604 | "there may be a more natural way to override default handlers, e.g. via derivation.", |
7605 | signal, g_type_name (required_iface), signal); |
7606 | return FALSE(0); |
7607 | } |
7608 | else |
7609 | return TRUE(!(0)); |
7610 | } |
7611 | |
7612 | static void |
7613 | remove_open_timeout (CtkTreeView *tree_view) |
7614 | { |
7615 | if (tree_view->priv->open_dest_timeout != 0) |
7616 | { |
7617 | g_source_remove (tree_view->priv->open_dest_timeout); |
7618 | tree_view->priv->open_dest_timeout = 0; |
7619 | } |
7620 | } |
7621 | |
7622 | |
7623 | static gint |
7624 | open_row_timeout (gpointer data) |
7625 | { |
7626 | CtkTreeView *tree_view = data; |
7627 | CtkTreePath *dest_path = NULL((void*)0); |
7628 | CtkTreeViewDropPosition pos; |
7629 | gboolean result = FALSE(0); |
7630 | |
7631 | ctk_tree_view_get_drag_dest_row (tree_view, |
7632 | &dest_path, |
7633 | &pos); |
7634 | |
7635 | if (dest_path && |
7636 | (pos == CTK_TREE_VIEW_DROP_INTO_OR_AFTER || |
7637 | pos == CTK_TREE_VIEW_DROP_INTO_OR_BEFORE)) |
7638 | { |
7639 | ctk_tree_view_expand_row (tree_view, dest_path, FALSE(0)); |
7640 | tree_view->priv->open_dest_timeout = 0; |
7641 | |
7642 | ctk_tree_path_free (dest_path); |
7643 | } |
7644 | else |
7645 | { |
7646 | if (dest_path) |
7647 | ctk_tree_path_free (dest_path); |
7648 | |
7649 | result = TRUE(!(0)); |
7650 | } |
7651 | |
7652 | return result; |
7653 | } |
7654 | |
7655 | static gboolean |
7656 | scroll_row_timeout (gpointer data) |
7657 | { |
7658 | CtkTreeView *tree_view = data; |
7659 | |
7660 | ctk_tree_view_vertical_autoscroll (tree_view); |
7661 | |
7662 | if (tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE) |
7663 | ctk_tree_view_update_rubber_band (tree_view); |
7664 | |
7665 | return TRUE(!(0)); |
7666 | } |
7667 | |
7668 | /* Returns TRUE if event should not be propagated to parent widgets */ |
7669 | static gboolean |
7670 | set_destination_row (CtkTreeView *tree_view, |
7671 | CdkDragContext *context, |
7672 | /* coordinates relative to the widget */ |
7673 | gint x, |
7674 | gint y, |
7675 | CdkDragAction *suggested_action, |
7676 | CdkAtom *target) |
7677 | { |
7678 | CtkTreePath *path = NULL((void*)0); |
7679 | CtkTreeViewDropPosition pos; |
7680 | CtkTreeViewDropPosition old_pos; |
7681 | TreeViewDragInfo *di; |
7682 | CtkWidget *widget; |
7683 | CtkTreePath *old_dest_path = NULL((void*)0); |
7684 | gboolean can_drop = FALSE(0); |
7685 | |
7686 | *suggested_action = 0; |
7687 | *target = CDK_NONE((CdkAtom)((gpointer) (gulong) (0))); |
7688 | |
7689 | widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
7690 | |
7691 | di = get_info (tree_view); |
7692 | |
7693 | if (di == NULL((void*)0) || y - ctk_tree_view_get_effective_header_height (tree_view) < 0) |
7694 | { |
7695 | /* someone unset us as a drag dest, note that if |
7696 | * we return FALSE drag_leave isn't called |
7697 | */ |
7698 | |
7699 | ctk_tree_view_set_drag_dest_row (tree_view, |
7700 | NULL((void*)0), |
7701 | CTK_TREE_VIEW_DROP_BEFORE); |
7702 | |
7703 | remove_scroll_timeout (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
7704 | remove_open_timeout (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
7705 | |
7706 | return FALSE(0); /* no longer a drop site */ |
7707 | } |
7708 | |
7709 | *target = ctk_drag_dest_find_target (widget, context, |
7710 | ctk_drag_dest_get_target_list (widget)); |
7711 | if (*target == CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) |
7712 | { |
7713 | return FALSE(0); |
7714 | } |
7715 | |
7716 | if (!ctk_tree_view_get_dest_row_at_pos (tree_view, |
7717 | x, y, |
7718 | &path, |
7719 | &pos)) |
7720 | { |
7721 | gint n_children; |
7722 | CtkTreeModel *model; |
7723 | |
7724 | remove_open_timeout (tree_view); |
7725 | |
7726 | /* the row got dropped on empty space, let's setup a special case |
7727 | */ |
7728 | |
7729 | if (path) |
7730 | ctk_tree_path_free (path); |
7731 | |
7732 | model = ctk_tree_view_get_model (tree_view); |
7733 | |
7734 | n_children = ctk_tree_model_iter_n_children (model, NULL((void*)0)); |
7735 | if (n_children) |
7736 | { |
7737 | pos = CTK_TREE_VIEW_DROP_AFTER; |
7738 | path = ctk_tree_path_new_from_indices (n_children - 1, -1); |
7739 | } |
7740 | else |
7741 | { |
7742 | pos = CTK_TREE_VIEW_DROP_BEFORE; |
7743 | path = ctk_tree_path_new_from_indices (0, -1); |
7744 | } |
7745 | |
7746 | can_drop = TRUE(!(0)); |
7747 | |
7748 | goto out; |
7749 | } |
7750 | |
7751 | g_assert (path)do { if (path) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c" , 7751, ((const char*) (__func__)), "path"); } while (0); |
7752 | |
7753 | /* If we left the current row's "open" zone, unset the timeout for |
7754 | * opening the row |
7755 | */ |
7756 | ctk_tree_view_get_drag_dest_row (tree_view, |
7757 | &old_dest_path, |
7758 | &old_pos); |
7759 | |
7760 | if (old_dest_path && |
7761 | (ctk_tree_path_compare (path, old_dest_path) != 0 || |
7762 | !(pos == CTK_TREE_VIEW_DROP_INTO_OR_AFTER || |
7763 | pos == CTK_TREE_VIEW_DROP_INTO_OR_BEFORE))) |
7764 | remove_open_timeout (tree_view); |
7765 | |
7766 | if (old_dest_path) |
7767 | ctk_tree_path_free (old_dest_path); |
7768 | |
7769 | if (TRUE(!(0)) /* FIXME if the location droppable predicate */) |
7770 | { |
7771 | can_drop = TRUE(!(0)); |
7772 | } |
7773 | |
7774 | out: |
7775 | if (can_drop) |
7776 | { |
7777 | CtkWidget *source_widget; |
7778 | |
7779 | *suggested_action = cdk_drag_context_get_suggested_action (context); |
7780 | source_widget = ctk_drag_get_source_widget (context); |
7781 | |
7782 | if (source_widget == widget) |
7783 | { |
7784 | /* Default to MOVE, unless the user has |
7785 | * pressed ctrl or shift to affect available actions |
7786 | */ |
7787 | if ((cdk_drag_context_get_actions (context) & CDK_ACTION_MOVE) != 0) |
7788 | *suggested_action = CDK_ACTION_MOVE; |
7789 | } |
7790 | |
7791 | ctk_tree_view_set_drag_dest_row (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
7792 | path, pos); |
7793 | } |
7794 | else |
7795 | { |
7796 | /* can't drop here */ |
7797 | remove_open_timeout (tree_view); |
7798 | |
7799 | ctk_tree_view_set_drag_dest_row (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
7800 | NULL((void*)0), |
7801 | CTK_TREE_VIEW_DROP_BEFORE); |
7802 | } |
7803 | |
7804 | if (path) |
7805 | ctk_tree_path_free (path); |
7806 | |
7807 | return TRUE(!(0)); |
7808 | } |
7809 | |
7810 | static CtkTreePath* |
7811 | get_logical_dest_row (CtkTreeView *tree_view, |
7812 | gboolean *path_down_mode, |
7813 | gboolean *drop_append_mode) |
7814 | { |
7815 | /* adjust path to point to the row the drop goes in front of */ |
7816 | CtkTreePath *path = NULL((void*)0); |
7817 | CtkTreeViewDropPosition pos; |
7818 | |
7819 | g_return_val_if_fail (path_down_mode != NULL, NULL)do { if ((path_down_mode != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path_down_mode != NULL" ); return (((void*)0)); } } while (0); |
7820 | g_return_val_if_fail (drop_append_mode != NULL, NULL)do { if ((drop_append_mode != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "drop_append_mode != NULL" ); return (((void*)0)); } } while (0); |
7821 | |
7822 | *path_down_mode = FALSE(0); |
7823 | *drop_append_mode = 0; |
7824 | |
7825 | ctk_tree_view_get_drag_dest_row (tree_view, &path, &pos); |
7826 | |
7827 | if (path == NULL((void*)0)) |
7828 | return NULL((void*)0); |
7829 | |
7830 | if (pos == CTK_TREE_VIEW_DROP_BEFORE) |
7831 | ; /* do nothing */ |
7832 | else if (pos == CTK_TREE_VIEW_DROP_INTO_OR_BEFORE || |
7833 | pos == CTK_TREE_VIEW_DROP_INTO_OR_AFTER) |
7834 | *path_down_mode = TRUE(!(0)); |
7835 | else |
7836 | { |
7837 | CtkTreeIter iter; |
7838 | CtkTreeModel *model = ctk_tree_view_get_model (tree_view); |
7839 | |
7840 | g_assert (pos == CTK_TREE_VIEW_DROP_AFTER)do { if (pos == CTK_TREE_VIEW_DROP_AFTER) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c", 7840, ((const char*) (__func__)), "pos == CTK_TREE_VIEW_DROP_AFTER" ); } while (0); |
7841 | |
7842 | if (!ctk_tree_model_get_iter (model, &iter, path) || |
7843 | !ctk_tree_model_iter_next (model, &iter)) |
7844 | *drop_append_mode = 1; |
7845 | else |
7846 | { |
7847 | *drop_append_mode = 0; |
7848 | ctk_tree_path_next (path); |
7849 | } |
7850 | } |
7851 | |
7852 | return path; |
7853 | } |
7854 | |
7855 | static gboolean |
7856 | ctk_tree_view_maybe_begin_dragging_row (CtkTreeView *tree_view) |
7857 | { |
7858 | CtkWidget *widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
7859 | gdouble start_x, start_y, offset_x, offset_y; |
7860 | CdkEventSequence *sequence; |
7861 | const CdkEvent *event; |
7862 | CdkDragContext *context; |
7863 | TreeViewDragInfo *di; |
7864 | CtkTreePath *path = NULL((void*)0); |
7865 | gint button; |
7866 | CtkTreeModel *model; |
7867 | gboolean retval = FALSE(0); |
7868 | gint bin_x, bin_y; |
7869 | |
7870 | di = get_info (tree_view); |
7871 | |
7872 | if (di == NULL((void*)0) || !di->source_set) |
7873 | goto out; |
7874 | |
7875 | if (!ctk_gesture_is_recognized (tree_view->priv->drag_gesture)) |
7876 | goto out; |
7877 | |
7878 | ctk_gesture_drag_get_start_point (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
7879 | &start_x, &start_y); |
7880 | ctk_gesture_drag_get_offset (CTK_GESTURE_DRAG (tree_view->priv->drag_gesture)((((CtkGestureDrag*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_drag_get_type ())))))), |
7881 | &offset_x, &offset_y); |
7882 | |
7883 | if (!ctk_drag_check_threshold (widget, 0, 0, offset_x, offset_y)) |
7884 | goto out; |
7885 | |
7886 | model = ctk_tree_view_get_model (tree_view); |
7887 | |
7888 | if (model == NULL((void*)0)) |
7889 | goto out; |
7890 | |
7891 | button = ctk_gesture_single_get_current_button (CTK_GESTURE_SINGLE (tree_view->priv->drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((tree_view->priv->drag_gesture)), ((ctk_gesture_single_get_type ()))))))); |
7892 | |
7893 | /* Deny the multipress gesture */ |
7894 | ctk_gesture_set_state (CTK_GESTURE (tree_view->priv->multipress_gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->multipress_gesture)), ((ctk_gesture_get_type ())))))), |
7895 | CTK_EVENT_SEQUENCE_DENIED); |
7896 | |
7897 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, start_x, start_y, |
7898 | &bin_x, &bin_y); |
7899 | ctk_tree_view_get_path_at_pos (tree_view, bin_x, bin_y, &path, |
7900 | NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
7901 | |
7902 | if (path == NULL((void*)0)) |
7903 | goto out; |
7904 | |
7905 | if (!CTK_IS_TREE_DRAG_SOURCE (model)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (model)); GType __t = ((ctk_tree_drag_source_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) || |
7906 | !ctk_tree_drag_source_row_draggable (CTK_TREE_DRAG_SOURCE (model)((((CtkTreeDragSource*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_drag_source_get_type ( ))))))), |
7907 | path)) |
7908 | goto out; |
7909 | |
7910 | if (!(CDK_BUTTON1_MASK << (button - 1) & di->start_button_mask)) |
7911 | goto out; |
7912 | |
7913 | retval = TRUE(!(0)); |
7914 | |
7915 | /* Now we can begin the drag */ |
7916 | ctk_gesture_set_state (CTK_GESTURE (tree_view->priv->drag_gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_get_type ())))))), |
7917 | CTK_EVENT_SEQUENCE_CLAIMED); |
7918 | sequence = ctk_gesture_single_get_current_sequence (CTK_GESTURE_SINGLE (tree_view->priv->drag_gesture)((((CtkGestureSingle*) (void *) g_type_check_instance_cast (( GTypeInstance*) ((tree_view->priv->drag_gesture)), ((ctk_gesture_single_get_type ()))))))); |
7919 | event = ctk_gesture_get_last_event (CTK_GESTURE (tree_view->priv->drag_gesture)((((CtkGesture*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->drag_gesture)), ((ctk_gesture_get_type ())))))), sequence); |
7920 | |
7921 | context = ctk_drag_begin_with_coordinates (widget, |
7922 | ctk_drag_source_get_target_list (widget), |
7923 | di->source_actions, |
7924 | button, |
7925 | (CdkEvent*)event, |
7926 | start_x, start_y); |
7927 | |
7928 | set_source_row (context, model, path); |
7929 | |
7930 | out: |
7931 | if (path) |
7932 | ctk_tree_path_free (path); |
7933 | |
7934 | return retval; |
7935 | } |
7936 | |
7937 | |
7938 | static void |
7939 | ctk_tree_view_drag_begin (CtkWidget *widget, |
7940 | CdkDragContext *context) |
7941 | { |
7942 | CtkTreeView *tree_view; |
7943 | CtkTreePath *path = NULL((void*)0); |
7944 | gint cell_x, cell_y; |
7945 | cairo_surface_t *row_pix; |
7946 | TreeViewDragInfo *di; |
7947 | double sx, sy; |
7948 | |
7949 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
7950 | |
7951 | /* if the user uses a custom DND source impl, we don't set the icon here */ |
7952 | di = get_info (tree_view); |
7953 | |
7954 | if (di == NULL((void*)0) || !di->source_set) |
7955 | return; |
7956 | |
7957 | ctk_tree_view_get_path_at_pos (tree_view, |
7958 | tree_view->priv->press_start_x, |
7959 | tree_view->priv->press_start_y, |
7960 | &path, |
7961 | NULL((void*)0), |
7962 | &cell_x, |
7963 | &cell_y); |
7964 | |
7965 | /* If path is NULL, there's nothing we can drag. For now, we silently |
7966 | * bail out. Actually, dragging should not be possible from an empty |
7967 | * tree view, but there's no way we can cancel that from here. |
7968 | * Automatically unsetting the tree view as drag source for empty models |
7969 | * is something that would likely break other people's code ... |
7970 | */ |
7971 | if (!path) |
7972 | return; |
7973 | |
7974 | row_pix = ctk_tree_view_create_row_drag_icon (tree_view, |
7975 | path); |
7976 | cairo_surface_get_device_scale (row_pix, &sx, &sy); |
7977 | cairo_surface_set_device_offset (row_pix, |
7978 | /* the + 1 is for the black border in the icon */ |
7979 | - (tree_view->priv->press_start_x + 1) * sx, |
7980 | - (cell_y + 1) * sy); |
7981 | |
7982 | ctk_drag_set_icon_surface (context, row_pix); |
7983 | |
7984 | cairo_surface_destroy (row_pix); |
7985 | ctk_tree_path_free (path); |
7986 | } |
7987 | |
7988 | static void |
7989 | ctk_tree_view_drag_end (CtkWidget *widget, |
7990 | CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__))) |
7991 | { |
7992 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
7993 | |
7994 | tree_view->priv->event_last_x = -10000; |
7995 | tree_view->priv->event_last_y = -10000; |
7996 | } |
7997 | |
7998 | /* Default signal implementations for the drag signals */ |
7999 | static void |
8000 | ctk_tree_view_drag_data_get (CtkWidget *widget, |
8001 | CdkDragContext *context, |
8002 | CtkSelectionData *selection_data, |
8003 | guint info G_GNUC_UNUSED__attribute__ ((__unused__)), |
8004 | guint time G_GNUC_UNUSED__attribute__ ((__unused__))) |
8005 | { |
8006 | CtkTreeView *tree_view; |
8007 | CtkTreeModel *model; |
8008 | TreeViewDragInfo *di; |
8009 | CtkTreePath *source_row; |
8010 | |
8011 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8012 | |
8013 | model = ctk_tree_view_get_model (tree_view); |
8014 | |
8015 | if (model == NULL((void*)0)) |
8016 | return; |
8017 | |
8018 | di = get_info (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
8019 | |
8020 | if (di == NULL((void*)0)) |
8021 | return; |
8022 | |
8023 | source_row = get_source_row (context); |
8024 | |
8025 | if (source_row == NULL((void*)0)) |
8026 | return; |
8027 | |
8028 | /* We can implement the CTK_TREE_MODEL_ROW target generically for |
8029 | * any model; for DragSource models there are some other targets |
8030 | * we also support. |
8031 | */ |
8032 | |
8033 | if (CTK_IS_TREE_DRAG_SOURCE (model)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (model)); GType __t = ((ctk_tree_drag_source_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))) && |
8034 | ctk_tree_drag_source_drag_data_get (CTK_TREE_DRAG_SOURCE (model)((((CtkTreeDragSource*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_drag_source_get_type ( ))))))), |
8035 | source_row, |
8036 | selection_data)) |
8037 | goto done; |
8038 | |
8039 | /* If drag_data_get does nothing, try providing row data. */ |
8040 | if (ctk_selection_data_get_target (selection_data) == cdk_atom_intern_static_string ("CTK_TREE_MODEL_ROW")) |
8041 | { |
8042 | ctk_tree_set_row_drag_data (selection_data, |
8043 | model, |
8044 | source_row); |
8045 | } |
8046 | |
8047 | done: |
8048 | ctk_tree_path_free (source_row); |
8049 | } |
8050 | |
8051 | |
8052 | static void |
8053 | ctk_tree_view_drag_data_delete (CtkWidget *widget, |
8054 | CdkDragContext *context) |
8055 | { |
8056 | TreeViewDragInfo *di; |
8057 | CtkTreeModel *model; |
8058 | CtkTreeView *tree_view; |
8059 | CtkTreePath *source_row; |
8060 | |
8061 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8062 | model = ctk_tree_view_get_model (tree_view); |
8063 | |
8064 | if (!check_model_dnd (model, CTK_TYPE_TREE_DRAG_SOURCE(ctk_tree_drag_source_get_type ()), "drag_data_delete")) |
8065 | return; |
8066 | |
8067 | di = get_info (tree_view); |
8068 | |
8069 | if (di == NULL((void*)0)) |
8070 | return; |
8071 | |
8072 | source_row = get_source_row (context); |
8073 | |
8074 | if (source_row == NULL((void*)0)) |
8075 | return; |
8076 | |
8077 | ctk_tree_drag_source_drag_data_delete (CTK_TREE_DRAG_SOURCE (model)((((CtkTreeDragSource*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((model)), ((ctk_tree_drag_source_get_type ( ))))))), |
8078 | source_row); |
8079 | |
8080 | ctk_tree_path_free (source_row); |
8081 | |
8082 | set_source_row (context, NULL((void*)0), NULL((void*)0)); |
8083 | } |
8084 | |
8085 | static void |
8086 | ctk_tree_view_drag_leave (CtkWidget *widget, |
8087 | CdkDragContext *context G_GNUC_UNUSED__attribute__ ((__unused__)), |
8088 | guint time G_GNUC_UNUSED__attribute__ ((__unused__))) |
8089 | { |
8090 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8091 | |
8092 | /* unset any highlight row */ |
8093 | ctk_tree_view_set_drag_dest_row (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
8094 | NULL((void*)0), |
8095 | CTK_TREE_VIEW_DROP_BEFORE); |
8096 | |
8097 | remove_scroll_timeout (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
8098 | remove_open_timeout (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
8099 | |
8100 | tree_view->priv->event_last_x = -10000; |
8101 | tree_view->priv->event_last_y = -10000; |
8102 | } |
8103 | |
8104 | |
8105 | static gboolean |
8106 | ctk_tree_view_drag_motion (CtkWidget *widget, |
8107 | CdkDragContext *context, |
8108 | /* coordinates relative to the widget */ |
8109 | gint x, |
8110 | gint y, |
8111 | guint time) |
8112 | { |
8113 | gboolean empty; |
8114 | CtkTreePath *path = NULL((void*)0); |
8115 | CtkTreeViewDropPosition pos; |
8116 | CtkTreeView *tree_view; |
8117 | CdkDragAction suggested_action = 0; |
8118 | CdkAtom target; |
8119 | |
8120 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8121 | |
8122 | if (!set_destination_row (tree_view, context, x, y, &suggested_action, &target)) |
8123 | return FALSE(0); |
8124 | |
8125 | tree_view->priv->event_last_x = x; |
8126 | tree_view->priv->event_last_y = y; |
8127 | |
8128 | ctk_tree_view_get_drag_dest_row (tree_view, &path, &pos); |
8129 | |
8130 | /* we only know this *after* set_desination_row */ |
8131 | empty = tree_view->priv->empty_view_drop; |
8132 | |
8133 | if (path == NULL((void*)0) && !empty) |
8134 | { |
8135 | /* Can't drop here. */ |
8136 | cdk_drag_status (context, 0, time); |
8137 | } |
8138 | else |
8139 | { |
8140 | if (tree_view->priv->open_dest_timeout == 0 && |
8141 | (pos == CTK_TREE_VIEW_DROP_INTO_OR_AFTER || |
8142 | pos == CTK_TREE_VIEW_DROP_INTO_OR_BEFORE)) |
8143 | { |
8144 | tree_view->priv->open_dest_timeout = |
8145 | cdk_threads_add_timeout (AUTO_EXPAND_TIMEOUT500, open_row_timeout, tree_view); |
8146 | g_source_set_name_by_id (tree_view->priv->open_dest_timeout, "[ctk+] open_row_timeout"); |
8147 | } |
8148 | else |
8149 | { |
8150 | add_scroll_timeout (tree_view); |
8151 | } |
8152 | |
8153 | if (target == cdk_atom_intern_static_string ("CTK_TREE_MODEL_ROW")) |
8154 | { |
8155 | /* Request data so we can use the source row when |
8156 | * determining whether to accept the drop |
8157 | */ |
8158 | set_status_pending (context, suggested_action); |
8159 | ctk_drag_get_data (widget, context, target, time); |
8160 | } |
8161 | else |
8162 | { |
8163 | set_status_pending (context, 0); |
8164 | cdk_drag_status (context, suggested_action, time); |
8165 | } |
8166 | } |
8167 | |
8168 | if (path) |
8169 | ctk_tree_path_free (path); |
8170 | |
8171 | return TRUE(!(0)); |
8172 | } |
8173 | |
8174 | |
8175 | static gboolean |
8176 | ctk_tree_view_drag_drop (CtkWidget *widget, |
8177 | CdkDragContext *context, |
8178 | /* coordinates relative to the widget */ |
8179 | gint x, |
8180 | gint y, |
8181 | guint time) |
8182 | { |
8183 | CtkTreeView *tree_view; |
8184 | CtkTreePath *path; |
8185 | CdkDragAction suggested_action = 0; |
8186 | CdkAtom target = CDK_NONE((CdkAtom)((gpointer) (gulong) (0))); |
8187 | TreeViewDragInfo *di; |
8188 | CtkTreeModel *model; |
8189 | gboolean path_down_mode; |
8190 | gboolean drop_append_mode; |
8191 | |
8192 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8193 | |
8194 | model = ctk_tree_view_get_model (tree_view); |
8195 | |
8196 | remove_scroll_timeout (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
8197 | remove_open_timeout (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
8198 | |
8199 | di = get_info (tree_view); |
8200 | |
8201 | if (di == NULL((void*)0)) |
8202 | return FALSE(0); |
8203 | |
8204 | if (!check_model_dnd (model, CTK_TYPE_TREE_DRAG_DEST(ctk_tree_drag_dest_get_type ()), "drag_drop")) |
8205 | return FALSE(0); |
8206 | |
8207 | if (!set_destination_row (tree_view, context, x, y, &suggested_action, &target)) |
8208 | return FALSE(0); |
8209 | |
8210 | path = get_logical_dest_row (tree_view, &path_down_mode, &drop_append_mode); |
8211 | |
8212 | if (target != CDK_NONE((CdkAtom)((gpointer) (gulong) (0))) && path != NULL((void*)0)) |
8213 | { |
8214 | /* in case a motion had requested drag data, change things so we |
8215 | * treat drag data receives as a drop. |
8216 | */ |
8217 | set_status_pending (context, 0); |
8218 | set_dest_row (context, model, path, |
8219 | path_down_mode, tree_view->priv->empty_view_drop, |
8220 | drop_append_mode); |
8221 | } |
8222 | |
8223 | if (path) |
8224 | ctk_tree_path_free (path); |
8225 | |
8226 | /* Unset this thing */ |
8227 | ctk_tree_view_set_drag_dest_row (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
8228 | NULL((void*)0), |
8229 | CTK_TREE_VIEW_DROP_BEFORE); |
8230 | |
8231 | if (target != CDK_NONE((CdkAtom)((gpointer) (gulong) (0)))) |
8232 | { |
8233 | ctk_drag_get_data (widget, context, target, time); |
8234 | return TRUE(!(0)); |
8235 | } |
8236 | else |
8237 | return FALSE(0); |
8238 | } |
8239 | |
8240 | static void |
8241 | ctk_tree_view_drag_data_received (CtkWidget *widget, |
8242 | CdkDragContext *context, |
8243 | /* coordinates relative to the widget */ |
8244 | gint x G_GNUC_UNUSED__attribute__ ((__unused__)), |
8245 | gint y G_GNUC_UNUSED__attribute__ ((__unused__)), |
8246 | CtkSelectionData *selection_data, |
8247 | guint info G_GNUC_UNUSED__attribute__ ((__unused__)), |
8248 | guint time) |
8249 | { |
8250 | CtkTreePath *path; |
8251 | TreeViewDragInfo *di; |
8252 | gboolean accepted = FALSE(0); |
8253 | CtkTreeModel *model; |
8254 | CtkTreeView *tree_view; |
8255 | CtkTreePath *dest_row; |
8256 | CdkDragAction suggested_action; |
8257 | gboolean path_down_mode; |
8258 | gboolean drop_append_mode; |
8259 | |
8260 | tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8261 | |
8262 | model = ctk_tree_view_get_model (tree_view); |
8263 | |
8264 | if (!check_model_dnd (model, CTK_TYPE_TREE_DRAG_DEST(ctk_tree_drag_dest_get_type ()), "drag_data_received")) |
8265 | return; |
8266 | |
8267 | di = get_info (tree_view); |
8268 | |
8269 | if (di == NULL((void*)0)) |
8270 | return; |
8271 | |
8272 | suggested_action = get_status_pending (context); |
8273 | |
8274 | if (suggested_action) |
8275 | { |
8276 | /* We are getting this data due to a request in drag_motion, |
8277 | * rather than due to a request in drag_drop, so we are just |
8278 | * supposed to call drag_status, not actually paste in the |
8279 | * data. |
8280 | */ |
8281 | path = get_logical_dest_row (tree_view, &path_down_mode, |
8282 | &drop_append_mode); |
8283 | |
8284 | if (path == NULL((void*)0)) |
8285 | suggested_action = 0; |
8286 | else if (path_down_mode) |
8287 | ctk_tree_path_down (path); |
8288 | |
8289 | if (suggested_action) |
8290 | { |
8291 | if (!ctk_tree_drag_dest_row_drop_possible (CTK_TREE_DRAG_DEST (model)((((CtkTreeDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_drag_dest_get_type ())))))), |
8292 | path, |
8293 | selection_data)) |
8294 | { |
8295 | if (path_down_mode) |
8296 | { |
8297 | path_down_mode = FALSE(0); |
8298 | ctk_tree_path_up (path); |
8299 | |
8300 | if (!ctk_tree_drag_dest_row_drop_possible (CTK_TREE_DRAG_DEST (model)((((CtkTreeDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_drag_dest_get_type ())))))), |
8301 | path, |
8302 | selection_data)) |
8303 | suggested_action = 0; |
8304 | } |
8305 | else |
8306 | suggested_action = 0; |
8307 | } |
8308 | } |
8309 | |
8310 | cdk_drag_status (context, suggested_action, time); |
8311 | |
8312 | if (path) |
8313 | ctk_tree_path_free (path); |
8314 | |
8315 | /* If you can't drop, remove user drop indicator until the next motion */ |
8316 | if (suggested_action == 0) |
8317 | ctk_tree_view_set_drag_dest_row (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
8318 | NULL((void*)0), |
8319 | CTK_TREE_VIEW_DROP_BEFORE); |
8320 | |
8321 | return; |
8322 | } |
8323 | |
8324 | dest_row = get_dest_row (context, &path_down_mode); |
8325 | |
8326 | if (dest_row == NULL((void*)0)) |
8327 | return; |
8328 | |
8329 | if (ctk_selection_data_get_length (selection_data) >= 0) |
8330 | { |
8331 | if (path_down_mode) |
8332 | { |
8333 | ctk_tree_path_down (dest_row); |
8334 | if (!ctk_tree_drag_dest_row_drop_possible (CTK_TREE_DRAG_DEST (model)((((CtkTreeDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_drag_dest_get_type ())))))), |
8335 | dest_row, selection_data)) |
8336 | ctk_tree_path_up (dest_row); |
8337 | } |
8338 | } |
8339 | |
8340 | if (ctk_selection_data_get_length (selection_data) >= 0) |
8341 | { |
8342 | if (ctk_tree_drag_dest_drag_data_received (CTK_TREE_DRAG_DEST (model)((((CtkTreeDragDest*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((model)), ((ctk_tree_drag_dest_get_type ())))))), |
8343 | dest_row, |
8344 | selection_data)) |
8345 | accepted = TRUE(!(0)); |
8346 | } |
8347 | |
8348 | ctk_drag_finish (context, |
8349 | accepted, |
8350 | (cdk_drag_context_get_selected_action (context) == CDK_ACTION_MOVE), |
8351 | time); |
8352 | |
8353 | if (ctk_tree_path_get_depth (dest_row) == 1 && |
8354 | ctk_tree_path_get_indices (dest_row)[0] == 0 && |
8355 | ctk_tree_model_iter_n_children (tree_view->priv->model, NULL((void*)0)) != 0) |
8356 | { |
8357 | /* special special case drag to "0", scroll to first item */ |
8358 | if (!tree_view->priv->scroll_to_path) |
8359 | ctk_tree_view_scroll_to_cell (tree_view, dest_row, NULL((void*)0), FALSE(0), 0.0, 0.0); |
8360 | } |
8361 | |
8362 | ctk_tree_path_free (dest_row); |
8363 | |
8364 | /* drop dest_row */ |
8365 | set_dest_row (context, NULL((void*)0), NULL((void*)0), FALSE(0), FALSE(0), FALSE(0)); |
8366 | } |
8367 | |
8368 | |
8369 | |
8370 | /* CtkContainer Methods |
8371 | */ |
8372 | |
8373 | |
8374 | static void |
8375 | ctk_tree_view_remove (CtkContainer *container, |
8376 | CtkWidget *widget) |
8377 | { |
8378 | CtkTreeView *tree_view = CTK_TREE_VIEW (container)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_tree_view_get_type ())))))); |
8379 | CtkTreeViewChild *child = NULL((void*)0); |
8380 | GList *tmp_list; |
8381 | |
8382 | tmp_list = tree_view->priv->children; |
8383 | while (tmp_list) |
8384 | { |
8385 | child = tmp_list->data; |
8386 | if (child->widget == widget) |
8387 | { |
8388 | ctk_widget_unparent (widget); |
8389 | |
8390 | tree_view->priv->children = g_list_remove_link (tree_view->priv->children, tmp_list); |
8391 | g_list_free_1 (tmp_list); |
8392 | g_slice_free (CtkTreeViewChild, child)do { if (1) g_slice_free1 (sizeof (CtkTreeViewChild), (child) ); else (void) ((CtkTreeViewChild*) 0 == (child)); } while (0 ); |
8393 | return; |
8394 | } |
8395 | |
8396 | tmp_list = tmp_list->next; |
8397 | } |
8398 | |
8399 | tmp_list = tree_view->priv->columns; |
8400 | |
8401 | while (tmp_list) |
8402 | { |
8403 | CtkTreeViewColumn *column; |
8404 | CtkWidget *button; |
8405 | |
8406 | column = tmp_list->data; |
8407 | button = ctk_tree_view_column_get_button (column); |
8408 | |
8409 | if (button == widget) |
8410 | { |
8411 | ctk_widget_unparent (widget); |
8412 | return; |
8413 | } |
8414 | tmp_list = tmp_list->next; |
8415 | } |
8416 | } |
8417 | |
8418 | static void |
8419 | ctk_tree_view_forall (CtkContainer *container, |
8420 | gboolean include_internals, |
8421 | CtkCallback callback, |
8422 | gpointer callback_data) |
8423 | { |
8424 | CtkTreeView *tree_view = CTK_TREE_VIEW (container)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_tree_view_get_type ())))))); |
8425 | CtkTreeViewChild *child = NULL((void*)0); |
8426 | CtkTreeViewColumn *column; |
8427 | CtkWidget *button; |
8428 | GList *tmp_list; |
8429 | |
8430 | tmp_list = tree_view->priv->children; |
8431 | while (tmp_list) |
8432 | { |
8433 | child = tmp_list->data; |
8434 | tmp_list = tmp_list->next; |
8435 | |
8436 | (* callback) (child->widget, callback_data); |
8437 | } |
8438 | if (include_internals == FALSE(0)) |
8439 | return; |
8440 | |
8441 | for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) |
8442 | { |
8443 | column = tmp_list->data; |
8444 | button = ctk_tree_view_column_get_button (column); |
8445 | |
8446 | if (button) |
8447 | (* callback) (button, callback_data); |
8448 | } |
8449 | } |
8450 | |
8451 | /* Returns TRUE is any of the columns contains a cell that can-focus. |
8452 | * If this is not the case, a column-spanning focus rectangle will be |
8453 | * drawn. |
8454 | */ |
8455 | static gboolean |
8456 | ctk_tree_view_has_can_focus_cell (CtkTreeView *tree_view) |
8457 | { |
8458 | GList *list; |
8459 | |
8460 | for (list = tree_view->priv->columns; list; list = list->next) |
8461 | { |
8462 | CtkTreeViewColumn *column = list->data; |
8463 | |
8464 | if (!ctk_tree_view_column_get_visible (column)) |
8465 | continue; |
8466 | if (ctk_cell_area_is_activatable (ctk_cell_layout_get_area (CTK_CELL_LAYOUT (column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((column)), ((ctk_cell_layout_get_type ()))))))))) |
8467 | return TRUE(!(0)); |
8468 | } |
8469 | |
8470 | return FALSE(0); |
8471 | } |
8472 | |
8473 | static void |
8474 | column_sizing_notify (GObject *object, |
8475 | GParamSpec *pspec G_GNUC_UNUSED__attribute__ ((__unused__)), |
8476 | gpointer data) |
8477 | { |
8478 | CtkTreeViewColumn *c = CTK_TREE_VIEW_COLUMN (object)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((object)), ((ctk_tree_view_column_get_type ( ))))))); |
8479 | |
8480 | if (ctk_tree_view_column_get_sizing (c) != CTK_TREE_VIEW_COLUMN_FIXED) |
8481 | /* disable fixed height mode */ |
8482 | g_object_set (data, "fixed-height-mode", FALSE(0), NULL((void*)0)); |
8483 | } |
8484 | |
8485 | /** |
8486 | * ctk_tree_view_set_fixed_height_mode: |
8487 | * @tree_view: a #CtkTreeView |
8488 | * @enable: %TRUE to enable fixed height mode |
8489 | * |
8490 | * Enables or disables the fixed height mode of @tree_view. |
8491 | * Fixed height mode speeds up #CtkTreeView by assuming that all |
8492 | * rows have the same height. |
8493 | * Only enable this option if all rows are the same height and all |
8494 | * columns are of type %CTK_TREE_VIEW_COLUMN_FIXED. |
8495 | * |
8496 | * Since: 2.6 |
8497 | **/ |
8498 | void |
8499 | ctk_tree_view_set_fixed_height_mode (CtkTreeView *tree_view, |
8500 | gboolean enable) |
8501 | { |
8502 | GList *l; |
8503 | |
8504 | enable = enable != FALSE(0); |
8505 | |
8506 | if (enable == tree_view->priv->fixed_height_mode) |
8507 | return; |
8508 | |
8509 | if (!enable) |
8510 | { |
8511 | tree_view->priv->fixed_height_mode = 0; |
8512 | tree_view->priv->fixed_height = -1; |
8513 | } |
8514 | else |
8515 | { |
8516 | /* make sure all columns are of type FIXED */ |
8517 | for (l = tree_view->priv->columns; l; l = l->next) |
8518 | { |
8519 | CtkTreeViewColumn *c = l->data; |
8520 | |
8521 | g_return_if_fail (ctk_tree_view_column_get_sizing (c) == CTK_TREE_VIEW_COLUMN_FIXED)do { if ((ctk_tree_view_column_get_sizing (c) == CTK_TREE_VIEW_COLUMN_FIXED )) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "ctk_tree_view_column_get_sizing (c) == CTK_TREE_VIEW_COLUMN_FIXED" ); return; } } while (0); |
8522 | } |
8523 | |
8524 | /* yes, we really have to do this is in a separate loop */ |
8525 | for (l = tree_view->priv->columns; l; l = l->next) |
8526 | g_signal_connect (l->data, "notify::sizing",g_signal_connect_data ((l->data), ("notify::sizing"), (((GCallback ) (column_sizing_notify))), (tree_view), ((void*)0), (GConnectFlags ) 0) |
8527 | G_CALLBACK (column_sizing_notify), tree_view)g_signal_connect_data ((l->data), ("notify::sizing"), (((GCallback ) (column_sizing_notify))), (tree_view), ((void*)0), (GConnectFlags ) 0); |
8528 | |
8529 | tree_view->priv->fixed_height_mode = 1; |
8530 | tree_view->priv->fixed_height = -1; |
8531 | } |
8532 | |
8533 | /* force a revalidation */ |
8534 | install_presize_handler (tree_view); |
8535 | |
8536 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_FIXED_HEIGHT_MODE]); |
8537 | } |
8538 | |
8539 | /** |
8540 | * ctk_tree_view_get_fixed_height_mode: |
8541 | * @tree_view: a #CtkTreeView |
8542 | * |
8543 | * Returns whether fixed height mode is turned on for @tree_view. |
8544 | * |
8545 | * Returns: %TRUE if @tree_view is in fixed height mode |
8546 | * |
8547 | * Since: 2.6 |
8548 | **/ |
8549 | gboolean |
8550 | ctk_tree_view_get_fixed_height_mode (CtkTreeView *tree_view) |
8551 | { |
8552 | return tree_view->priv->fixed_height_mode; |
8553 | } |
8554 | |
8555 | /* Returns TRUE if the focus is within the headers, after the focus operation is |
8556 | * done |
8557 | */ |
8558 | static gboolean |
8559 | ctk_tree_view_header_focus (CtkTreeView *tree_view, |
8560 | CtkDirectionType dir, |
8561 | gboolean clamp_column_visible) |
8562 | { |
8563 | CtkTreeViewColumn *column; |
8564 | CtkWidget *button; |
8565 | CtkWidget *focus_child; |
8566 | GList *last_column, *first_column; |
8567 | GList *tmp_list; |
8568 | gboolean rtl; |
8569 | |
8570 | if (! tree_view->priv->headers_visible) |
8571 | return FALSE(0); |
8572 | |
8573 | focus_child = ctk_container_get_focus_child (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ()))))))); |
8574 | |
8575 | first_column = tree_view->priv->columns; |
8576 | while (first_column) |
8577 | { |
8578 | column = CTK_TREE_VIEW_COLUMN (first_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((first_column->data)), ((ctk_tree_view_column_get_type ())))))); |
8579 | button = ctk_tree_view_column_get_button (column); |
8580 | |
8581 | if (ctk_widget_get_can_focus (button) && |
8582 | ctk_tree_view_column_get_visible (column) && |
8583 | (ctk_tree_view_column_get_clickable (column) || |
8584 | ctk_tree_view_column_get_reorderable (column))) |
8585 | break; |
8586 | first_column = first_column->next; |
8587 | } |
8588 | |
8589 | /* No headers are visible, or are focusable. We can't focus in or out. |
8590 | */ |
8591 | if (first_column == NULL((void*)0)) |
8592 | return FALSE(0); |
8593 | |
8594 | last_column = g_list_last (tree_view->priv->columns); |
8595 | while (last_column) |
8596 | { |
8597 | column = CTK_TREE_VIEW_COLUMN (last_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((last_column->data)), ((ctk_tree_view_column_get_type ())))))); |
8598 | button = ctk_tree_view_column_get_button (column); |
8599 | |
8600 | if (ctk_widget_get_can_focus (button) && |
8601 | ctk_tree_view_column_get_visible (column) && |
8602 | (ctk_tree_view_column_get_clickable (column) || |
8603 | ctk_tree_view_column_get_reorderable (column))) |
8604 | break; |
8605 | last_column = last_column->prev; |
8606 | } |
8607 | |
8608 | |
8609 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
8610 | |
8611 | switch (dir) |
8612 | { |
8613 | case CTK_DIR_TAB_BACKWARD: |
8614 | case CTK_DIR_TAB_FORWARD: |
8615 | case CTK_DIR_UP: |
8616 | case CTK_DIR_DOWN: |
8617 | if (focus_child == NULL((void*)0)) |
8618 | { |
8619 | if (tree_view->priv->focus_column != NULL((void*)0)) |
8620 | button = ctk_tree_view_column_get_button (tree_view->priv->focus_column); |
8621 | else |
8622 | button = NULL((void*)0); |
8623 | |
8624 | if (button && ctk_widget_get_can_focus (button)) |
8625 | focus_child = button; |
8626 | else |
8627 | focus_child = ctk_tree_view_column_get_button (CTK_TREE_VIEW_COLUMN (first_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((first_column->data)), ((ctk_tree_view_column_get_type ()))))))); |
8628 | |
8629 | ctk_widget_grab_focus (focus_child); |
8630 | break; |
8631 | } |
8632 | return FALSE(0); |
8633 | |
8634 | case CTK_DIR_LEFT: |
8635 | case CTK_DIR_RIGHT: |
8636 | if (focus_child == NULL((void*)0)) |
8637 | { |
8638 | if (tree_view->priv->focus_column != NULL((void*)0)) |
8639 | focus_child = ctk_tree_view_column_get_button (tree_view->priv->focus_column); |
8640 | else if (dir == CTK_DIR_LEFT) |
8641 | focus_child = ctk_tree_view_column_get_button (CTK_TREE_VIEW_COLUMN (last_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((last_column->data)), ((ctk_tree_view_column_get_type ()))))))); |
8642 | else |
8643 | focus_child = ctk_tree_view_column_get_button (CTK_TREE_VIEW_COLUMN (first_column->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((first_column->data)), ((ctk_tree_view_column_get_type ()))))))); |
8644 | |
8645 | ctk_widget_grab_focus (focus_child); |
8646 | break; |
8647 | } |
8648 | |
8649 | if (ctk_widget_child_focus (focus_child, dir)) |
8650 | { |
8651 | /* The focus moves inside the button. */ |
8652 | /* This is probably a great example of bad UI */ |
8653 | break; |
8654 | } |
8655 | |
8656 | /* We need to move the focus among the row of buttons. */ |
8657 | for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) |
8658 | if (ctk_tree_view_column_get_button (CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ()))))))) == focus_child) |
8659 | break; |
8660 | |
8661 | if ((tmp_list == first_column && dir == (rtl ? CTK_DIR_RIGHT : CTK_DIR_LEFT)) |
8662 | || (tmp_list == last_column && dir == (rtl ? CTK_DIR_LEFT : CTK_DIR_RIGHT))) |
8663 | { |
8664 | ctk_widget_error_bell (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
8665 | break; |
8666 | } |
8667 | |
8668 | while (tmp_list) |
8669 | { |
8670 | if (dir == (rtl ? CTK_DIR_LEFT : CTK_DIR_RIGHT)) |
8671 | tmp_list = tmp_list->next; |
8672 | else |
8673 | tmp_list = tmp_list->prev; |
8674 | |
8675 | if (tmp_list == NULL((void*)0)) |
8676 | { |
8677 | g_warning ("Internal button not found"); |
8678 | break; |
8679 | } |
8680 | column = tmp_list->data; |
8681 | button = ctk_tree_view_column_get_button (column); |
8682 | if (button && |
8683 | ctk_tree_view_column_get_visible (column) && |
8684 | ctk_widget_get_can_focus (button)) |
8685 | { |
8686 | focus_child = button; |
8687 | ctk_widget_grab_focus (button); |
8688 | break; |
8689 | } |
8690 | } |
8691 | break; |
8692 | default: |
8693 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctktreeview.c", 8693, ( (const char*) (__func__)), ((void*)0)); } while (0); |
8694 | break; |
8695 | } |
8696 | |
8697 | /* if focus child is non-null, we assume it's been set to the current focus child |
8698 | */ |
8699 | if (focus_child) |
8700 | { |
8701 | for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next) |
8702 | if (ctk_tree_view_column_get_button (CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ()))))))) == focus_child) |
8703 | { |
8704 | _ctk_tree_view_set_focus_column (tree_view, CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ()))))))); |
8705 | break; |
8706 | } |
8707 | |
8708 | if (clamp_column_visible) |
8709 | { |
8710 | ctk_tree_view_clamp_column_visible (tree_view, |
8711 | tree_view->priv->focus_column, |
8712 | FALSE(0)); |
8713 | } |
8714 | } |
8715 | |
8716 | return (focus_child != NULL((void*)0)); |
8717 | } |
8718 | |
8719 | /* This function returns in 'path' the first focusable path, if the given path |
8720 | * is already focusable, it’s the returned one. |
8721 | */ |
8722 | static gboolean |
8723 | search_first_focusable_path (CtkTreeView *tree_view, |
8724 | CtkTreePath **path, |
8725 | gboolean search_forward, |
8726 | CtkRBTree **new_tree, |
8727 | CtkRBNode **new_node) |
8728 | { |
8729 | CtkRBTree *tree = NULL((void*)0); |
8730 | CtkRBNode *node = NULL((void*)0); |
8731 | |
8732 | if (!path || !*path) |
8733 | return FALSE(0); |
8734 | |
8735 | _ctk_tree_view_find_node (tree_view, *path, &tree, &node); |
8736 | |
8737 | if (!tree || !node) |
8738 | return FALSE(0); |
8739 | |
8740 | while (node && row_is_separator (tree_view, NULL((void*)0), *path)) |
8741 | { |
8742 | if (search_forward) |
8743 | _ctk_rbtree_next_full (tree, node, &tree, &node); |
8744 | else |
8745 | _ctk_rbtree_prev_full (tree, node, &tree, &node); |
8746 | |
8747 | if (*path) |
8748 | ctk_tree_path_free (*path); |
8749 | |
8750 | if (node) |
8751 | *path = _ctk_tree_path_new_from_rbtree (tree, node); |
8752 | else |
8753 | *path = NULL((void*)0); |
8754 | } |
8755 | |
8756 | if (new_tree) |
8757 | *new_tree = tree; |
8758 | |
8759 | if (new_node) |
8760 | *new_node = node; |
8761 | |
8762 | return (*path != NULL((void*)0)); |
8763 | } |
8764 | |
8765 | static gint |
8766 | ctk_tree_view_focus (CtkWidget *widget, |
8767 | CtkDirectionType direction) |
8768 | { |
8769 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8770 | CtkContainer *container = CTK_CONTAINER (widget)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_container_get_type ())))))); |
8771 | CtkWidget *focus_child; |
8772 | |
8773 | if (!ctk_widget_is_sensitive (widget) || !ctk_widget_get_can_focus (widget)) |
8774 | return FALSE(0); |
8775 | |
8776 | focus_child = ctk_container_get_focus_child (container); |
8777 | |
8778 | ctk_tree_view_stop_editing (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), FALSE(0)); |
8779 | /* Case 1. Headers currently have focus. */ |
8780 | if (focus_child) |
8781 | { |
8782 | switch (direction) |
8783 | { |
8784 | case CTK_DIR_LEFT: |
8785 | case CTK_DIR_RIGHT: |
8786 | ctk_tree_view_header_focus (tree_view, direction, TRUE(!(0))); |
8787 | return TRUE(!(0)); |
8788 | case CTK_DIR_TAB_BACKWARD: |
8789 | case CTK_DIR_UP: |
8790 | return FALSE(0); |
8791 | case CTK_DIR_TAB_FORWARD: |
8792 | case CTK_DIR_DOWN: |
8793 | ctk_widget_grab_focus (widget); |
8794 | return TRUE(!(0)); |
8795 | default: |
8796 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctktreeview.c", 8796, ( (const char*) (__func__)), ((void*)0)); } while (0); |
8797 | return FALSE(0); |
8798 | } |
8799 | } |
8800 | |
8801 | /* Case 2. We don't have focus at all. */ |
8802 | if (!ctk_widget_has_focus (widget)) |
8803 | { |
8804 | ctk_widget_grab_focus (widget); |
8805 | return TRUE(!(0)); |
8806 | } |
8807 | |
8808 | /* Case 3. We have focus already. */ |
8809 | if (direction == CTK_DIR_TAB_BACKWARD) |
8810 | return (ctk_tree_view_header_focus (tree_view, direction, FALSE(0))); |
8811 | else if (direction == CTK_DIR_TAB_FORWARD) |
8812 | return FALSE(0); |
8813 | |
8814 | /* Other directions caught by the keybindings */ |
8815 | ctk_widget_grab_focus (widget); |
8816 | return TRUE(!(0)); |
8817 | } |
8818 | |
8819 | static void |
8820 | ctk_tree_view_grab_focus (CtkWidget *widget) |
8821 | { |
8822 | CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->grab_focus (widget); |
8823 | |
8824 | ctk_tree_view_focus_to_cursor (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ()))))))); |
8825 | } |
8826 | |
8827 | static void |
8828 | ctk_tree_view_style_updated (CtkWidget *widget) |
8829 | { |
8830 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
8831 | GList *list; |
8832 | CtkTreeViewColumn *column; |
8833 | CtkStyleContext *style_context; |
8834 | CtkCssStyleChange *change; |
8835 | |
8836 | CTK_WIDGET_CLASS (ctk_tree_view_parent_class)((((CtkWidgetClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_widget_get_type ())) ))))->style_updated (widget); |
8837 | |
8838 | if (ctk_widget_get_realized (widget)) |
8839 | { |
8840 | ctk_tree_view_set_grid_lines (tree_view, tree_view->priv->grid_lines); |
8841 | ctk_tree_view_set_enable_tree_lines (tree_view, tree_view->priv->tree_lines_enabled); |
8842 | } |
8843 | |
8844 | style_context = ctk_widget_get_style_context (widget); |
8845 | change = ctk_style_context_get_change (style_context); |
8846 | |
8847 | if (change == NULL((void*)0) || ctk_css_style_change_affects (change, CTK_CSS_AFFECTS_SIZE | CTK_CSS_AFFECTS_CLIP)) |
8848 | { |
8849 | for (list = tree_view->priv->columns; list; list = list->next) |
8850 | { |
8851 | column = list->data; |
8852 | _ctk_tree_view_column_cell_set_dirty (column, TRUE(!(0))); |
8853 | } |
8854 | |
8855 | tree_view->priv->fixed_height = -1; |
8856 | _ctk_rbtree_mark_invalid (tree_view->priv->tree); |
8857 | } |
8858 | } |
8859 | |
8860 | |
8861 | static void |
8862 | ctk_tree_view_set_focus_child (CtkContainer *container, |
8863 | CtkWidget *child) |
8864 | { |
8865 | CtkTreeView *tree_view = CTK_TREE_VIEW (container)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((container)), ((ctk_tree_view_get_type ())))))); |
8866 | GList *list; |
8867 | |
8868 | for (list = tree_view->priv->columns; list; list = list->next) |
8869 | { |
8870 | if (ctk_tree_view_column_get_button (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))) == child) |
8871 | { |
8872 | _ctk_tree_view_set_focus_column (tree_view, CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))); |
8873 | break; |
8874 | } |
8875 | } |
8876 | |
8877 | CTK_CONTAINER_CLASS (ctk_tree_view_parent_class)((((CtkContainerClass*) (void *) g_type_check_class_cast ((GTypeClass *) ((ctk_tree_view_parent_class)), ((ctk_container_get_type ( )))))))->set_focus_child (container, child); |
8878 | } |
8879 | |
8880 | static gboolean |
8881 | ctk_tree_view_real_move_cursor (CtkTreeView *tree_view, |
8882 | CtkMovementStep step, |
8883 | gint count) |
8884 | { |
8885 | CdkModifierType state; |
8886 | |
8887 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
8888 | g_return_val_if_fail (step == CTK_MOVEMENT_LOGICAL_POSITIONS ||do { if ((step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS" ); return ((0)); } } while (0) |
8889 | step == CTK_MOVEMENT_VISUAL_POSITIONS ||do { if ((step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS" ); return ((0)); } } while (0) |
8890 | step == CTK_MOVEMENT_DISPLAY_LINES ||do { if ((step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS" ); return ((0)); } } while (0) |
8891 | step == CTK_MOVEMENT_PAGES ||do { if ((step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS" ); return ((0)); } } while (0) |
8892 | step == CTK_MOVEMENT_BUFFER_ENDS, FALSE)do { if ((step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "step == CTK_MOVEMENT_LOGICAL_POSITIONS || step == CTK_MOVEMENT_VISUAL_POSITIONS || step == CTK_MOVEMENT_DISPLAY_LINES || step == CTK_MOVEMENT_PAGES || step == CTK_MOVEMENT_BUFFER_ENDS" ); return ((0)); } } while (0); |
8893 | |
8894 | if (tree_view->priv->tree == NULL((void*)0)) |
8895 | return FALSE(0); |
8896 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
8897 | return FALSE(0); |
8898 | |
8899 | ctk_tree_view_stop_editing (tree_view, FALSE(0)); |
8900 | tree_view->priv->draw_keyfocus = TRUE(!(0)); |
8901 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
8902 | |
8903 | if (ctk_get_current_event_state (&state)) |
8904 | { |
8905 | CdkModifierType extend_mod_mask; |
8906 | CdkModifierType modify_mod_mask; |
8907 | |
8908 | extend_mod_mask = |
8909 | ctk_widget_get_modifier_mask (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
8910 | CDK_MODIFIER_INTENT_EXTEND_SELECTION); |
8911 | |
8912 | modify_mod_mask = |
8913 | ctk_widget_get_modifier_mask (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
8914 | CDK_MODIFIER_INTENT_MODIFY_SELECTION); |
8915 | |
8916 | if ((state & modify_mod_mask) == modify_mod_mask) |
8917 | tree_view->priv->modify_selection_pressed = TRUE(!(0)); |
8918 | if ((state & extend_mod_mask) == extend_mod_mask) |
8919 | tree_view->priv->extend_selection_pressed = TRUE(!(0)); |
8920 | } |
8921 | /* else we assume not pressed */ |
8922 | |
8923 | switch (step) |
8924 | { |
8925 | /* currently we make no distinction. When we go bi-di, we need to */ |
8926 | case CTK_MOVEMENT_LOGICAL_POSITIONS: |
8927 | case CTK_MOVEMENT_VISUAL_POSITIONS: |
8928 | ctk_tree_view_move_cursor_left_right (tree_view, count); |
8929 | break; |
8930 | case CTK_MOVEMENT_DISPLAY_LINES: |
8931 | ctk_tree_view_move_cursor_up_down (tree_view, count); |
8932 | break; |
8933 | case CTK_MOVEMENT_PAGES: |
8934 | ctk_tree_view_move_cursor_page_up_down (tree_view, count); |
8935 | break; |
8936 | case CTK_MOVEMENT_BUFFER_ENDS: |
8937 | ctk_tree_view_move_cursor_start_end (tree_view, count); |
8938 | break; |
8939 | default: |
8940 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctktreeview.c", 8940, ( (const char*) (__func__)), ((void*)0)); } while (0); |
8941 | } |
8942 | |
8943 | tree_view->priv->modify_selection_pressed = FALSE(0); |
8944 | tree_view->priv->extend_selection_pressed = FALSE(0); |
8945 | |
8946 | return TRUE(!(0)); |
8947 | } |
8948 | |
8949 | static void |
8950 | ctk_tree_view_put (CtkTreeView *tree_view, |
8951 | CtkWidget *child_widget, |
8952 | CtkTreePath *path, |
8953 | CtkTreeViewColumn *column, |
8954 | const CtkBorder *border) |
8955 | { |
8956 | CtkTreeViewChild *child; |
8957 | |
8958 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
8959 | g_return_if_fail (CTK_IS_WIDGET (child_widget))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((child_widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (child_widget)"); return; } } while (0); |
8960 | |
8961 | child = g_slice_new (CtkTreeViewChild)((CtkTreeViewChild*) g_slice_alloc (sizeof (CtkTreeViewChild) )); |
8962 | |
8963 | child->widget = child_widget; |
8964 | if (_ctk_tree_view_find_node (tree_view, |
8965 | path, |
8966 | &child->tree, |
8967 | &child->node)) |
8968 | { |
8969 | g_assert_not_reached ()do { g_assertion_message_expr ("Ctk", "ctktreeview.c", 8969, ( (const char*) (__func__)), ((void*)0)); } while (0); |
8970 | } |
8971 | child->column = column; |
8972 | child->border = *border; |
8973 | |
8974 | tree_view->priv->children = g_list_append (tree_view->priv->children, child); |
8975 | |
8976 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
8977 | ctk_widget_set_parent_window (child->widget, tree_view->priv->bin_window); |
8978 | |
8979 | ctk_widget_set_parent (child_widget, CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
8980 | } |
8981 | |
8982 | /* TreeModel Callbacks |
8983 | */ |
8984 | |
8985 | static void |
8986 | ctk_tree_view_row_changed (CtkTreeModel *model, |
8987 | CtkTreePath *path, |
8988 | CtkTreeIter *iter, |
8989 | gpointer data) |
8990 | { |
8991 | CtkTreeView *tree_view = (CtkTreeView *)data; |
8992 | CtkRBTree *tree; |
8993 | CtkRBNode *node; |
8994 | gboolean free_path = FALSE(0); |
8995 | GList *list; |
8996 | CtkTreePath *cursor_path; |
8997 | |
8998 | g_return_if_fail (path != NULL || iter != NULL)do { if ((path != ((void*)0) || iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "path != NULL || iter != NULL"); return; } } while (0); |
8999 | |
9000 | if (tree_view->priv->cursor_node != NULL((void*)0)) |
9001 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
9002 | tree_view->priv->cursor_node); |
9003 | else |
9004 | cursor_path = NULL((void*)0); |
9005 | |
9006 | if (tree_view->priv->edited_column && |
9007 | (cursor_path == NULL((void*)0) || ctk_tree_path_compare (cursor_path, path) == 0)) |
9008 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
9009 | |
9010 | if (cursor_path != NULL((void*)0)) |
9011 | ctk_tree_path_free (cursor_path); |
9012 | |
9013 | if (path == NULL((void*)0)) |
9014 | { |
9015 | path = ctk_tree_model_get_path (model, iter); |
9016 | free_path = TRUE(!(0)); |
9017 | } |
9018 | else if (iter == NULL((void*)0)) |
9019 | ctk_tree_model_get_iter (model, iter, path); |
9020 | |
9021 | if (_ctk_tree_view_find_node (tree_view, |
9022 | path, |
9023 | &tree, |
9024 | &node)) |
9025 | /* We aren't actually showing the node */ |
9026 | goto done; |
9027 | |
9028 | if (tree == NULL((void*)0)) |
9029 | goto done; |
9030 | |
9031 | _ctk_tree_view_accessible_changed (tree_view, tree, node); |
9032 | |
9033 | if (tree_view->priv->fixed_height_mode |
9034 | && tree_view->priv->fixed_height >= 0) |
9035 | { |
9036 | _ctk_rbtree_node_set_height (tree, node, tree_view->priv->fixed_height); |
9037 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
9038 | ctk_tree_view_node_queue_redraw (tree_view, tree, node); |
9039 | } |
9040 | else |
9041 | { |
9042 | _ctk_rbtree_node_mark_invalid (tree, node); |
9043 | for (list = tree_view->priv->columns; list; list = list->next) |
9044 | { |
9045 | CtkTreeViewColumn *column; |
9046 | |
9047 | column = list->data; |
9048 | if (!ctk_tree_view_column_get_visible (column)) |
9049 | continue; |
9050 | |
9051 | if (ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_AUTOSIZE) |
9052 | { |
9053 | _ctk_tree_view_column_cell_set_dirty (column, TRUE(!(0))); |
9054 | } |
9055 | } |
9056 | } |
9057 | |
9058 | done: |
9059 | if (!tree_view->priv->fixed_height_mode && |
9060 | ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
9061 | install_presize_handler (tree_view); |
9062 | if (free_path) |
9063 | ctk_tree_path_free (path); |
9064 | } |
9065 | |
9066 | static void |
9067 | ctk_tree_view_row_inserted (CtkTreeModel *model, |
9068 | CtkTreePath *path, |
9069 | CtkTreeIter *iter, |
9070 | gpointer data) |
9071 | { |
9072 | CtkTreeView *tree_view = (CtkTreeView *) data; |
9073 | gint *indices; |
9074 | CtkRBTree *tree; |
9075 | CtkRBNode *tmpnode = NULL((void*)0); |
9076 | gint depth; |
9077 | gint i = 0; |
9078 | gint height; |
9079 | gboolean free_path = FALSE(0); |
9080 | gboolean node_visible = TRUE(!(0)); |
9081 | |
9082 | g_return_if_fail (path != NULL || iter != NULL)do { if ((path != ((void*)0) || iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "path != NULL || iter != NULL"); return; } } while (0); |
9083 | |
9084 | if (tree_view->priv->fixed_height_mode |
9085 | && tree_view->priv->fixed_height >= 0) |
9086 | height = tree_view->priv->fixed_height; |
9087 | else |
9088 | height = 0; |
9089 | |
9090 | if (path == NULL((void*)0)) |
9091 | { |
9092 | path = ctk_tree_model_get_path (model, iter); |
9093 | free_path = TRUE(!(0)); |
9094 | } |
9095 | else if (iter == NULL((void*)0)) |
9096 | ctk_tree_model_get_iter (model, iter, path); |
9097 | |
9098 | if (tree_view->priv->tree == NULL((void*)0)) |
9099 | tree_view->priv->tree = _ctk_rbtree_new (); |
9100 | |
9101 | tree = tree_view->priv->tree; |
9102 | |
9103 | /* Update all row-references */ |
9104 | ctk_tree_row_reference_inserted (G_OBJECT (data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), (((GType) ((20) << (2)))))))), path); |
9105 | depth = ctk_tree_path_get_depth (path); |
9106 | indices = ctk_tree_path_get_indices (path); |
9107 | |
9108 | /* First, find the parent tree */ |
9109 | while (i < depth - 1) |
9110 | { |
9111 | if (tree == NULL((void*)0)) |
9112 | { |
9113 | /* We aren't showing the node */ |
9114 | node_visible = FALSE(0); |
9115 | goto done; |
9116 | } |
9117 | |
9118 | tmpnode = _ctk_rbtree_find_count (tree, indices[i] + 1); |
9119 | if (tmpnode == NULL((void*)0)) |
9120 | { |
9121 | g_warning ("A node was inserted with a parent that's not in the tree.\n" \ |
9122 | "This possibly means that a CtkTreeModel inserted a child node\n" \ |
9123 | "before the parent was inserted."); |
9124 | goto done; |
9125 | } |
9126 | else if (!CTK_RBNODE_FLAG_SET (tmpnode, CTK_RBNODE_IS_PARENT)(tmpnode?(((tmpnode->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0))) |
9127 | { |
9128 | /* FIXME enforce correct behavior on model, probably */ |
9129 | /* In theory, the model should have emitted has_child_toggled here. We |
9130 | * try to catch it anyway, just to be safe, in case the model hasn't. |
9131 | */ |
9132 | CtkTreePath *tmppath = _ctk_tree_path_new_from_rbtree (tree, tmpnode); |
9133 | ctk_tree_view_row_has_child_toggled (model, tmppath, NULL((void*)0), data); |
9134 | ctk_tree_path_free (tmppath); |
9135 | goto done; |
9136 | } |
9137 | |
9138 | tree = tmpnode->children; |
9139 | i++; |
9140 | } |
9141 | |
9142 | if (tree == NULL((void*)0)) |
9143 | { |
9144 | node_visible = FALSE(0); |
9145 | goto done; |
9146 | } |
9147 | |
9148 | /* ref the node */ |
9149 | ctk_tree_model_ref_node (tree_view->priv->model, iter); |
9150 | if (indices[depth - 1] == 0) |
9151 | { |
9152 | tmpnode = _ctk_rbtree_find_count (tree, 1); |
9153 | tmpnode = _ctk_rbtree_insert_before (tree, tmpnode, height, FALSE(0)); |
9154 | } |
9155 | else |
9156 | { |
9157 | tmpnode = _ctk_rbtree_find_count (tree, indices[depth - 1]); |
9158 | tmpnode = _ctk_rbtree_insert_after (tree, tmpnode, height, FALSE(0)); |
9159 | } |
9160 | |
9161 | _ctk_tree_view_accessible_add (tree_view, tree, tmpnode); |
9162 | |
9163 | done: |
9164 | if (height > 0) |
9165 | { |
9166 | if (tree) |
9167 | _ctk_rbtree_node_mark_valid (tree, tmpnode); |
9168 | |
9169 | if (node_visible && node_is_visible (tree_view, tree, tmpnode)) |
9170 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
9171 | else |
9172 | ctk_widget_queue_resize_no_redraw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
9173 | } |
9174 | else |
9175 | install_presize_handler (tree_view); |
9176 | if (free_path) |
9177 | ctk_tree_path_free (path); |
9178 | } |
9179 | |
9180 | static void |
9181 | ctk_tree_view_row_has_child_toggled (CtkTreeModel *model, |
9182 | CtkTreePath *path, |
9183 | CtkTreeIter *iter, |
9184 | gpointer data) |
9185 | { |
9186 | CtkTreeView *tree_view = (CtkTreeView *)data; |
9187 | CtkTreeIter real_iter; |
9188 | gboolean has_child; |
9189 | CtkRBTree *tree; |
9190 | CtkRBNode *node; |
9191 | gboolean free_path = FALSE(0); |
9192 | |
9193 | g_return_if_fail (path != NULL || iter != NULL)do { if ((path != ((void*)0) || iter != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "path != NULL || iter != NULL"); return; } } while (0); |
9194 | |
9195 | if (iter) |
9196 | real_iter = *iter; |
9197 | |
9198 | if (path == NULL((void*)0)) |
9199 | { |
9200 | path = ctk_tree_model_get_path (model, iter); |
9201 | free_path = TRUE(!(0)); |
9202 | } |
9203 | else if (iter == NULL((void*)0)) |
9204 | ctk_tree_model_get_iter (model, &real_iter, path); |
9205 | |
9206 | if (_ctk_tree_view_find_node (tree_view, |
9207 | path, |
9208 | &tree, |
9209 | &node)) |
9210 | /* We aren't actually showing the node */ |
9211 | goto done; |
9212 | |
9213 | if (tree == NULL((void*)0)) |
9214 | goto done; |
9215 | |
9216 | has_child = ctk_tree_model_iter_has_child (model, &real_iter); |
9217 | /* Sanity check. |
9218 | */ |
9219 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)) == has_child) |
9220 | goto done; |
9221 | |
9222 | if (has_child) |
9223 | { |
9224 | CTK_RBNODE_SET_FLAG (node, CTK_RBNODE_IS_PARENT)do{ (node->flags|=CTK_RBNODE_IS_PARENT); }while (0); |
9225 | _ctk_tree_view_accessible_add_state (tree_view, tree, node, CTK_CELL_RENDERER_EXPANDABLE); |
9226 | } |
9227 | else |
9228 | { |
9229 | CTK_RBNODE_UNSET_FLAG (node, CTK_RBNODE_IS_PARENT)do{ (node->flags&=~(CTK_RBNODE_IS_PARENT)); }while (0); |
9230 | _ctk_tree_view_accessible_remove_state (tree_view, tree, node, CTK_CELL_RENDERER_EXPANDABLE); |
9231 | } |
9232 | |
9233 | if (has_child && tree_view->priv->is_list) |
9234 | { |
9235 | tree_view->priv->is_list = FALSE(0); |
9236 | if (tree_view->priv->show_expanders) |
9237 | { |
9238 | GList *list; |
9239 | |
9240 | for (list = tree_view->priv->columns; list; list = list->next) |
9241 | if (ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))))) |
9242 | { |
9243 | _ctk_tree_view_column_cell_set_dirty (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))), TRUE(!(0))); |
9244 | break; |
9245 | } |
9246 | } |
9247 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
9248 | } |
9249 | else |
9250 | { |
9251 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
9252 | } |
9253 | |
9254 | done: |
9255 | if (free_path) |
9256 | ctk_tree_path_free (path); |
9257 | } |
9258 | |
9259 | static void |
9260 | count_children_helper (CtkRBTree *tree G_GNUC_UNUSED__attribute__ ((__unused__)), |
9261 | CtkRBNode *node, |
9262 | gpointer data) |
9263 | { |
9264 | if (node->children) |
9265 | _ctk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, count_children_helper, data); |
9266 | (*((gint *)data))++; |
9267 | } |
9268 | |
9269 | static void |
9270 | check_selection_helper (CtkRBTree *tree G_GNUC_UNUSED__attribute__ ((__unused__)), |
9271 | CtkRBNode *node, |
9272 | gpointer data) |
9273 | { |
9274 | gint *value = (gint *)data; |
9275 | |
9276 | *value |= CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0)); |
9277 | |
9278 | if (node->children && !*value) |
9279 | _ctk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, check_selection_helper, data); |
9280 | } |
9281 | |
9282 | static void |
9283 | ctk_tree_view_row_deleted (CtkTreeModel *model G_GNUC_UNUSED__attribute__ ((__unused__)), |
9284 | CtkTreePath *path, |
9285 | gpointer data) |
9286 | { |
9287 | CtkTreeView *tree_view = (CtkTreeView *)data; |
9288 | CtkRBTree *tree; |
9289 | CtkRBNode *node; |
9290 | GList *list; |
9291 | gboolean selection_changed = FALSE(0), cursor_changed = FALSE(0); |
9292 | CtkRBTree *cursor_tree = NULL((void*)0); |
9293 | CtkRBNode *cursor_node = NULL((void*)0); |
9294 | |
9295 | g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return; } } while (0); |
9296 | |
9297 | ctk_tree_row_reference_deleted (G_OBJECT (data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), (((GType) ((20) << (2)))))))), path); |
9298 | |
9299 | if (_ctk_tree_view_find_node (tree_view, path, &tree, &node)) |
9300 | return; |
9301 | |
9302 | if (tree == NULL((void*)0)) |
9303 | return; |
9304 | |
9305 | /* check if the selection has been changed */ |
9306 | _ctk_rbtree_traverse (tree, node, G_POST_ORDER, |
9307 | check_selection_helper, &selection_changed); |
9308 | |
9309 | for (list = tree_view->priv->columns; list; list = list->next) |
9310 | if (ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))) && |
9311 | ctk_tree_view_column_get_sizing (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))) == CTK_TREE_VIEW_COLUMN_AUTOSIZE) |
9312 | _ctk_tree_view_column_cell_set_dirty ((CtkTreeViewColumn *)list->data, TRUE(!(0))); |
9313 | |
9314 | /* Ensure we don't have a dangling pointer to a dead node */ |
9315 | ensure_unprelighted (tree_view); |
9316 | |
9317 | /* Cancel editting if we've started */ |
9318 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
9319 | |
9320 | /* If the cursor row got deleted, move the cursor to the next row */ |
9321 | if (tree_view->priv->cursor_node && |
9322 | (tree_view->priv->cursor_node == node || |
9323 | (node->children && (tree_view->priv->cursor_tree == node->children || |
9324 | _ctk_rbtree_contains (node->children, tree_view->priv->cursor_tree))))) |
9325 | { |
9326 | CtkTreePath *cursor_path; |
9327 | |
9328 | cursor_tree = tree; |
9329 | cursor_node = _ctk_rbtree_next (tree, node); |
9330 | /* find the first node that is not going to be deleted */ |
9331 | while (cursor_node == NULL((void*)0) && cursor_tree->parent_tree) |
9332 | { |
9333 | cursor_node = _ctk_rbtree_next (cursor_tree->parent_tree, |
9334 | cursor_tree->parent_node); |
9335 | cursor_tree = cursor_tree->parent_tree; |
9336 | } |
9337 | |
9338 | if (cursor_node != NULL((void*)0)) |
9339 | cursor_path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
9340 | else |
9341 | cursor_path = NULL((void*)0); |
9342 | |
9343 | if (cursor_path == NULL((void*)0) || |
9344 | ! search_first_focusable_path (tree_view, &cursor_path, TRUE(!(0)), |
9345 | &cursor_tree, &cursor_node)) |
9346 | { |
9347 | /* It looks like we reached the end of the view without finding |
9348 | * a focusable row. We will step backwards to find the last |
9349 | * focusable row. |
9350 | */ |
9351 | _ctk_rbtree_prev_full (tree, node, &cursor_tree, &cursor_node); |
9352 | if (cursor_node) |
9353 | { |
9354 | cursor_path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
9355 | if (! search_first_focusable_path (tree_view, &cursor_path, FALSE(0), |
9356 | &cursor_tree, &cursor_node)) |
9357 | cursor_node = NULL((void*)0); |
9358 | ctk_tree_path_free (cursor_path); |
9359 | } |
9360 | } |
9361 | else if (cursor_path) |
9362 | ctk_tree_path_free (cursor_path); |
9363 | |
9364 | cursor_changed = TRUE(!(0)); |
9365 | } |
9366 | |
9367 | if (tree_view->priv->destroy_count_func) |
9368 | { |
9369 | gint child_count = 0; |
9370 | if (node->children) |
9371 | _ctk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, count_children_helper, &child_count); |
9372 | tree_view->priv->destroy_count_func (tree_view, path, child_count, tree_view->priv->destroy_count_data); |
9373 | } |
9374 | |
9375 | if (tree->root->count == 1) |
9376 | { |
9377 | if (tree_view->priv->tree == tree) |
9378 | tree_view->priv->tree = NULL((void*)0); |
9379 | |
9380 | _ctk_tree_view_accessible_remove_state (tree_view, |
9381 | tree->parent_tree, tree->parent_node, |
9382 | CTK_CELL_RENDERER_EXPANDED); |
9383 | _ctk_tree_view_accessible_remove (tree_view, tree, NULL((void*)0)); |
9384 | _ctk_rbtree_remove (tree); |
9385 | } |
9386 | else |
9387 | { |
9388 | _ctk_tree_view_accessible_remove (tree_view, tree, node); |
9389 | _ctk_rbtree_remove_node (tree, node); |
9390 | } |
9391 | |
9392 | if (! ctk_tree_row_reference_valid (tree_view->priv->top_row)) |
9393 | { |
9394 | ctk_tree_row_reference_free (tree_view->priv->top_row); |
9395 | tree_view->priv->top_row = NULL((void*)0); |
9396 | } |
9397 | |
9398 | install_scroll_sync_handler (tree_view); |
9399 | |
9400 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
9401 | |
9402 | if (cursor_changed) |
9403 | { |
9404 | if (cursor_node) |
9405 | { |
9406 | CtkTreePath *cursor_path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
9407 | ctk_tree_view_real_set_cursor (tree_view, cursor_path, CLEAR_AND_SELECT | CURSOR_INVALID); |
9408 | ctk_tree_path_free (cursor_path); |
9409 | } |
9410 | else |
9411 | ctk_tree_view_real_set_cursor (tree_view, NULL((void*)0), CLEAR_AND_SELECT | CURSOR_INVALID); |
9412 | } |
9413 | if (selection_changed) |
9414 | g_signal_emit_by_name (tree_view->priv->selection, "changed"); |
9415 | } |
9416 | |
9417 | static void |
9418 | ctk_tree_view_rows_reordered (CtkTreeModel *model, |
9419 | CtkTreePath *parent, |
9420 | CtkTreeIter *iter, |
9421 | gint *new_order, |
9422 | gpointer data) |
9423 | { |
9424 | CtkTreeView *tree_view = CTK_TREE_VIEW (data)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), ((ctk_tree_view_get_type ())))))); |
9425 | CtkRBTree *tree; |
9426 | CtkRBNode *node; |
9427 | gint len; |
9428 | |
9429 | len = ctk_tree_model_iter_n_children (model, iter); |
9430 | |
9431 | if (len < 2) |
9432 | return; |
9433 | |
9434 | ctk_tree_row_reference_reordered (G_OBJECT (data)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((data)), (((GType) ((20) << (2)))))))), |
9435 | parent, |
9436 | iter, |
9437 | new_order); |
9438 | |
9439 | if (_ctk_tree_view_find_node (tree_view, |
9440 | parent, |
9441 | &tree, |
9442 | &node)) |
9443 | return; |
9444 | |
9445 | /* We need to special case the parent path */ |
9446 | if (tree == NULL((void*)0)) |
9447 | tree = tree_view->priv->tree; |
9448 | else |
9449 | tree = node->children; |
9450 | |
9451 | if (tree == NULL((void*)0)) |
9452 | return; |
9453 | |
9454 | if (tree_view->priv->edited_column) |
9455 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
9456 | |
9457 | /* we need to be unprelighted */ |
9458 | ensure_unprelighted (tree_view); |
9459 | |
9460 | _ctk_rbtree_reorder (tree, new_order, len); |
9461 | |
9462 | _ctk_tree_view_accessible_reorder (tree_view); |
9463 | |
9464 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
9465 | |
9466 | ctk_tree_view_dy_to_top_row (tree_view); |
9467 | } |
9468 | |
9469 | |
9470 | /* Internal tree functions |
9471 | */ |
9472 | |
9473 | |
9474 | static void |
9475 | ctk_tree_view_get_background_xrange (CtkTreeView *tree_view, |
9476 | CtkRBTree *tree G_GNUC_UNUSED__attribute__ ((__unused__)), |
9477 | CtkTreeViewColumn *column, |
9478 | gint *x1, |
9479 | gint *x2) |
9480 | { |
9481 | CtkTreeViewColumn *tmp_column = NULL((void*)0); |
9482 | gint total_width; |
9483 | GList *list; |
9484 | gboolean rtl; |
9485 | |
9486 | if (x1) |
9487 | *x1 = 0; |
9488 | |
9489 | if (x2) |
9490 | *x2 = 0; |
9491 | |
9492 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
9493 | |
9494 | total_width = 0; |
9495 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
9496 | list; |
9497 | list = (rtl ? list->prev : list->next)) |
9498 | { |
9499 | tmp_column = list->data; |
9500 | |
9501 | if (tmp_column == column) |
9502 | break; |
9503 | |
9504 | if (ctk_tree_view_column_get_visible (tmp_column)) |
9505 | total_width += ctk_tree_view_column_get_width (tmp_column); |
9506 | } |
9507 | |
9508 | if (tmp_column != column) |
9509 | { |
9510 | g_warning (G_STRLOC"ctktreeview.c" ":" "9510"": passed-in column isn't in the tree"); |
9511 | return; |
9512 | } |
9513 | |
9514 | if (x1) |
9515 | *x1 = total_width; |
9516 | |
9517 | if (x2) |
9518 | { |
9519 | if (ctk_tree_view_column_get_visible (column)) |
9520 | *x2 = total_width + ctk_tree_view_column_get_width (column); |
9521 | else |
9522 | *x2 = total_width; /* width of 0 */ |
9523 | } |
9524 | } |
9525 | |
9526 | static void |
9527 | ctk_tree_view_get_arrow_xrange (CtkTreeView *tree_view, |
9528 | CtkRBTree *tree, |
9529 | gint *x1, |
9530 | gint *x2) |
9531 | { |
9532 | gint x_offset = 0; |
9533 | GList *list; |
9534 | CtkTreeViewColumn *tmp_column = NULL((void*)0); |
9535 | gint total_width; |
9536 | gint expander_size, expander_render_size; |
9537 | gint horizontal_separator; |
9538 | gboolean indent_expanders; |
9539 | gboolean rtl; |
9540 | |
9541 | ctk_widget_style_get (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
9542 | "indent-expanders", &indent_expanders, |
9543 | "horizontal-separator", &horizontal_separator, |
9544 | NULL((void*)0)); |
9545 | |
9546 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
9547 | expander_size = ctk_tree_view_get_expander_size (tree_view); |
9548 | expander_render_size = expander_size - (horizontal_separator / 2); |
9549 | |
9550 | total_width = 0; |
9551 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
9552 | list; |
9553 | list = (rtl ? list->prev : list->next)) |
9554 | { |
9555 | tmp_column = list->data; |
9556 | |
9557 | if (ctk_tree_view_is_expander_column (tree_view, tmp_column)) |
9558 | { |
9559 | if (rtl) |
9560 | x_offset = total_width + ctk_tree_view_column_get_width (tmp_column) - expander_size; |
9561 | else |
9562 | x_offset = total_width; |
9563 | break; |
9564 | } |
9565 | |
9566 | if (ctk_tree_view_column_get_visible (tmp_column)) |
9567 | total_width += ctk_tree_view_column_get_width (tmp_column); |
9568 | } |
9569 | |
9570 | x_offset += (expander_size - expander_render_size); |
9571 | |
9572 | if (indent_expanders) |
9573 | { |
9574 | if (rtl) |
9575 | x_offset -= expander_size * _ctk_rbtree_get_depth (tree); |
9576 | else |
9577 | x_offset += expander_size * _ctk_rbtree_get_depth (tree); |
9578 | } |
9579 | |
9580 | *x1 = x_offset; |
9581 | |
9582 | if (tmp_column && |
9583 | ctk_tree_view_column_get_visible (tmp_column)) |
9584 | *x2 = *x1 + expander_render_size; |
9585 | else |
9586 | *x2 = *x1; |
9587 | } |
9588 | |
9589 | static void |
9590 | ctk_tree_view_build_tree (CtkTreeView *tree_view, |
9591 | CtkRBTree *tree, |
9592 | CtkTreeIter *iter, |
9593 | gint depth, |
9594 | gboolean recurse) |
9595 | { |
9596 | CtkRBNode *temp = NULL((void*)0); |
9597 | CtkTreePath *path = NULL((void*)0); |
9598 | |
9599 | do |
9600 | { |
9601 | ctk_tree_model_ref_node (tree_view->priv->model, iter); |
9602 | temp = _ctk_rbtree_insert_after (tree, temp, 0, FALSE(0)); |
9603 | |
9604 | if (tree_view->priv->fixed_height > 0) |
9605 | { |
9606 | if (CTK_RBNODE_FLAG_SET (temp, CTK_RBNODE_INVALID)(temp?(((temp->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0))) |
9607 | { |
9608 | _ctk_rbtree_node_set_height (tree, temp, tree_view->priv->fixed_height); |
9609 | _ctk_rbtree_node_mark_valid (tree, temp); |
9610 | } |
9611 | } |
9612 | |
9613 | if (tree_view->priv->is_list) |
9614 | continue; |
9615 | |
9616 | if (recurse) |
9617 | { |
9618 | CtkTreeIter child; |
9619 | |
9620 | if (!path) |
9621 | path = ctk_tree_model_get_path (tree_view->priv->model, iter); |
9622 | else |
9623 | ctk_tree_path_next (path); |
9624 | |
9625 | if (ctk_tree_model_iter_has_child (tree_view->priv->model, iter)) |
9626 | { |
9627 | gboolean expand; |
9628 | |
9629 | g_signal_emit (tree_view, tree_view_signals[TEST_EXPAND_ROW], 0, iter, path, &expand); |
9630 | |
9631 | if (ctk_tree_model_iter_children (tree_view->priv->model, &child, iter) |
9632 | && !expand) |
9633 | { |
9634 | temp->children = _ctk_rbtree_new (); |
9635 | temp->children->parent_tree = tree; |
9636 | temp->children->parent_node = temp; |
9637 | ctk_tree_view_build_tree (tree_view, temp->children, &child, depth + 1, recurse); |
9638 | } |
9639 | } |
9640 | } |
9641 | |
9642 | if (ctk_tree_model_iter_has_child (tree_view->priv->model, iter)) |
9643 | { |
9644 | if ((temp->flags&CTK_RBNODE_IS_PARENT) != CTK_RBNODE_IS_PARENT) |
9645 | temp->flags ^= CTK_RBNODE_IS_PARENT; |
9646 | } |
9647 | } |
9648 | while (ctk_tree_model_iter_next (tree_view->priv->model, iter)); |
9649 | |
9650 | if (path) |
9651 | ctk_tree_path_free (path); |
9652 | } |
9653 | |
9654 | /* Make sure the node is visible vertically */ |
9655 | static void |
9656 | ctk_tree_view_clamp_node_visible (CtkTreeView *tree_view, |
9657 | CtkRBTree *tree, |
9658 | CtkRBNode *node) |
9659 | { |
9660 | gint node_dy, height; |
9661 | CtkTreePath *path = NULL((void*)0); |
9662 | |
9663 | if (!ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
9664 | return; |
9665 | |
9666 | /* just return if the node is visible, avoiding a costly expose */ |
9667 | node_dy = _ctk_rbtree_node_find_offset (tree, node); |
9668 | height = ctk_tree_view_get_row_height (tree_view, node); |
9669 | if (! CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_INVALID)(node?(((node->flags&CTK_RBNODE_INVALID)==CTK_RBNODE_INVALID )?(!(0)):(0)):(0)) |
9670 | && node_dy >= ctk_adjustment_get_value (tree_view->priv->vadjustment) |
9671 | && node_dy + height <= (ctk_adjustment_get_value (tree_view->priv->vadjustment) |
9672 | + ctk_adjustment_get_page_size (tree_view->priv->vadjustment))) |
9673 | return; |
9674 | |
9675 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
9676 | if (path) |
9677 | { |
9678 | ctk_tree_view_scroll_to_cell (tree_view, path, NULL((void*)0), FALSE(0), 0.0, 0.0); |
9679 | ctk_tree_path_free (path); |
9680 | } |
9681 | } |
9682 | |
9683 | static void |
9684 | ctk_tree_view_clamp_column_visible (CtkTreeView *tree_view, |
9685 | CtkTreeViewColumn *column, |
9686 | gboolean focus_to_cell) |
9687 | { |
9688 | CtkAllocation allocation; |
9689 | gint x, width; |
9690 | |
9691 | if (column == NULL((void*)0)) |
9692 | return; |
9693 | |
9694 | ctk_widget_get_allocation (ctk_tree_view_column_get_button (column), &allocation); |
9695 | x = allocation.x; |
9696 | width = allocation.width; |
9697 | |
9698 | if (width > ctk_adjustment_get_page_size (tree_view->priv->hadjustment)) |
9699 | { |
9700 | /* The column is larger than the horizontal page size. If the |
9701 | * column has cells which can be focused individually, then we make |
9702 | * sure the cell which gets focus is fully visible (if even the |
9703 | * focus cell is bigger than the page size, we make sure the |
9704 | * left-hand side of the cell is visible). |
9705 | * |
9706 | * If the column does not have an activatable cell, we |
9707 | * make sure the left-hand side of the column is visible. |
9708 | */ |
9709 | |
9710 | if (focus_to_cell && ctk_tree_view_has_can_focus_cell (tree_view)) |
9711 | { |
9712 | CtkCellArea *cell_area; |
9713 | CtkCellRenderer *focus_cell; |
9714 | |
9715 | cell_area = ctk_cell_layout_get_area (CTK_CELL_LAYOUT (column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((column)), ((ctk_cell_layout_get_type ()))))))); |
9716 | focus_cell = ctk_cell_area_get_focus_cell (cell_area); |
9717 | |
9718 | if (ctk_tree_view_column_cell_get_position (column, focus_cell, |
9719 | &x, &width)) |
9720 | { |
9721 | if (width < ctk_adjustment_get_page_size (tree_view->priv->hadjustment)) |
9722 | { |
9723 | if (ctk_adjustment_get_value (tree_view->priv->hadjustment) + ctk_adjustment_get_page_size (tree_view->priv->hadjustment) < x + width) |
9724 | ctk_adjustment_set_value (tree_view->priv->hadjustment, |
9725 | x + width - ctk_adjustment_get_page_size (tree_view->priv->hadjustment)); |
9726 | else if (ctk_adjustment_get_value (tree_view->priv->hadjustment) > x) |
9727 | ctk_adjustment_set_value (tree_view->priv->hadjustment, x); |
9728 | } |
9729 | } |
9730 | } |
9731 | |
9732 | ctk_adjustment_set_value (tree_view->priv->hadjustment, x); |
9733 | } |
9734 | else |
9735 | { |
9736 | if ((ctk_adjustment_get_value (tree_view->priv->hadjustment) + ctk_adjustment_get_page_size (tree_view->priv->hadjustment)) < (x + width)) |
9737 | ctk_adjustment_set_value (tree_view->priv->hadjustment, |
9738 | x + width - ctk_adjustment_get_page_size (tree_view->priv->hadjustment)); |
9739 | else if (ctk_adjustment_get_value (tree_view->priv->hadjustment) > x) |
9740 | ctk_adjustment_set_value (tree_view->priv->hadjustment, x); |
9741 | } |
9742 | } |
9743 | |
9744 | /* This function could be more efficient. I'll optimize it if profiling seems |
9745 | * to imply that it is important */ |
9746 | CtkTreePath * |
9747 | _ctk_tree_path_new_from_rbtree (CtkRBTree *tree, |
9748 | CtkRBNode *node) |
9749 | { |
9750 | CtkTreePath *path; |
9751 | CtkRBTree *tmp_tree; |
9752 | CtkRBNode *tmp_node, *last; |
9753 | gint count; |
9754 | |
9755 | path = ctk_tree_path_new (); |
9756 | |
9757 | g_return_val_if_fail (node != NULL, path)do { if ((node != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "node != NULL"); return ( path); } } while (0); |
9758 | |
9759 | count = 1 + node->left->count; |
9760 | |
9761 | last = node; |
9762 | tmp_node = node->parent; |
9763 | tmp_tree = tree; |
9764 | while (tmp_tree) |
9765 | { |
9766 | while (!_ctk_rbtree_is_nil (tmp_node)) |
9767 | { |
9768 | if (tmp_node->right == last) |
9769 | count += 1 + tmp_node->left->count; |
9770 | last = tmp_node; |
9771 | tmp_node = tmp_node->parent; |
9772 | } |
9773 | ctk_tree_path_prepend_index (path, count - 1); |
9774 | last = tmp_tree->parent_node; |
9775 | tmp_tree = tmp_tree->parent_tree; |
9776 | if (last) |
9777 | { |
9778 | count = 1 + last->left->count; |
9779 | tmp_node = last->parent; |
9780 | } |
9781 | } |
9782 | return path; |
9783 | } |
9784 | |
9785 | /* Returns TRUE if we ran out of tree before finding the path. If the path is |
9786 | * invalid (ie. points to a node that’s not in the tree), *tree and *node are |
9787 | * both set to NULL. |
9788 | */ |
9789 | gboolean |
9790 | _ctk_tree_view_find_node (CtkTreeView *tree_view, |
9791 | CtkTreePath *path, |
9792 | CtkRBTree **tree, |
9793 | CtkRBNode **node) |
9794 | { |
9795 | CtkRBNode *tmpnode = NULL((void*)0); |
9796 | CtkRBTree *tmptree = tree_view->priv->tree; |
9797 | gint *indices = ctk_tree_path_get_indices (path); |
9798 | gint depth = ctk_tree_path_get_depth (path); |
9799 | gint i = 0; |
9800 | |
9801 | *node = NULL((void*)0); |
9802 | *tree = NULL((void*)0); |
9803 | |
9804 | if (depth == 0 || tmptree == NULL((void*)0)) |
9805 | return FALSE(0); |
9806 | do |
9807 | { |
9808 | tmpnode = _ctk_rbtree_find_count (tmptree, indices[i] + 1); |
9809 | ++i; |
9810 | if (tmpnode == NULL((void*)0)) |
9811 | { |
9812 | *tree = NULL((void*)0); |
9813 | *node = NULL((void*)0); |
9814 | return FALSE(0); |
9815 | } |
9816 | if (i >= depth) |
9817 | { |
9818 | *tree = tmptree; |
9819 | *node = tmpnode; |
9820 | return FALSE(0); |
9821 | } |
9822 | *tree = tmptree; |
9823 | *node = tmpnode; |
9824 | tmptree = tmpnode->children; |
9825 | if (tmptree == NULL((void*)0)) |
9826 | return TRUE(!(0)); |
9827 | } |
9828 | while (1); |
9829 | } |
9830 | |
9831 | static gboolean |
9832 | ctk_tree_view_is_expander_column (CtkTreeView *tree_view, |
9833 | CtkTreeViewColumn *column) |
9834 | { |
9835 | GList *list; |
9836 | |
9837 | if (tree_view->priv->is_list) |
9838 | return FALSE(0); |
9839 | |
9840 | if (tree_view->priv->expander_column != NULL((void*)0)) |
9841 | { |
9842 | if (tree_view->priv->expander_column == column) |
9843 | return TRUE(!(0)); |
9844 | return FALSE(0); |
9845 | } |
9846 | else |
9847 | { |
9848 | for (list = tree_view->priv->columns; |
9849 | list; |
9850 | list = list->next) |
9851 | if (ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))))) |
9852 | break; |
9853 | if (list && list->data == column) |
9854 | return TRUE(!(0)); |
9855 | } |
9856 | return FALSE(0); |
9857 | } |
9858 | |
9859 | static inline gboolean |
9860 | ctk_tree_view_draw_expanders (CtkTreeView *tree_view) |
9861 | { |
9862 | if (!tree_view->priv->is_list && tree_view->priv->show_expanders) |
9863 | return TRUE(!(0)); |
9864 | /* else */ |
9865 | return FALSE(0); |
9866 | } |
9867 | |
9868 | static void |
9869 | ctk_tree_view_add_move_binding (CtkBindingSet *binding_set, |
9870 | guint keyval, |
9871 | guint modmask, |
9872 | gboolean add_shifted_binding, |
9873 | CtkMovementStep step, |
9874 | gint count) |
9875 | { |
9876 | |
9877 | ctk_binding_entry_add_signal (binding_set, keyval, modmask, |
9878 | "move-cursor", 2, |
9879 | G_TYPE_ENUM((GType) ((12) << (2))), step, |
9880 | G_TYPE_INT((GType) ((6) << (2))), count); |
9881 | |
9882 | if (add_shifted_binding) |
9883 | ctk_binding_entry_add_signal (binding_set, keyval, CDK_SHIFT_MASK, |
9884 | "move-cursor", 2, |
9885 | G_TYPE_ENUM((GType) ((12) << (2))), step, |
9886 | G_TYPE_INT((GType) ((6) << (2))), count); |
9887 | |
9888 | if ((modmask & CDK_CONTROL_MASK) == CDK_CONTROL_MASK) |
9889 | return; |
9890 | |
9891 | ctk_binding_entry_add_signal (binding_set, keyval, CDK_CONTROL_MASK | CDK_SHIFT_MASK, |
9892 | "move-cursor", 2, |
9893 | G_TYPE_ENUM((GType) ((12) << (2))), step, |
9894 | G_TYPE_INT((GType) ((6) << (2))), count); |
9895 | |
9896 | ctk_binding_entry_add_signal (binding_set, keyval, CDK_CONTROL_MASK, |
9897 | "move-cursor", 2, |
9898 | G_TYPE_ENUM((GType) ((12) << (2))), step, |
9899 | G_TYPE_INT((GType) ((6) << (2))), count); |
9900 | } |
9901 | |
9902 | static gint |
9903 | ctk_tree_view_unref_tree_helper (CtkTreeModel *model, |
9904 | CtkTreeIter *iter, |
9905 | CtkRBTree *tree, |
9906 | CtkRBNode *node) |
9907 | { |
9908 | gint retval = FALSE(0); |
9909 | do |
9910 | { |
9911 | g_return_val_if_fail (node != NULL, FALSE)do { if ((node != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "node != NULL"); return ( (0)); } } while (0); |
9912 | |
9913 | if (node->children) |
9914 | { |
9915 | CtkTreeIter child; |
9916 | CtkRBTree *new_tree; |
9917 | CtkRBNode *new_node; |
9918 | |
9919 | new_tree = node->children; |
9920 | new_node = _ctk_rbtree_first (new_tree); |
9921 | |
9922 | if (!ctk_tree_model_iter_children (model, &child, iter)) |
9923 | return FALSE(0); |
9924 | |
9925 | retval = ctk_tree_view_unref_tree_helper (model, &child, new_tree, new_node) | retval; |
9926 | } |
9927 | |
9928 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
9929 | retval = TRUE(!(0)); |
9930 | ctk_tree_model_unref_node (model, iter); |
9931 | node = _ctk_rbtree_next (tree, node); |
9932 | } |
9933 | while (ctk_tree_model_iter_next (model, iter)); |
9934 | |
9935 | return retval; |
9936 | } |
9937 | |
9938 | static gint |
9939 | ctk_tree_view_unref_and_check_selection_tree (CtkTreeView *tree_view, |
9940 | CtkRBTree *tree) |
9941 | { |
9942 | CtkTreeIter iter; |
9943 | CtkTreePath *path; |
9944 | CtkRBNode *node; |
9945 | gint retval; |
9946 | |
9947 | if (!tree) |
9948 | return FALSE(0); |
9949 | |
9950 | node = _ctk_rbtree_first (tree); |
9951 | |
9952 | g_return_val_if_fail (node != NULL, FALSE)do { if ((node != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "node != NULL"); return ( (0)); } } while (0); |
9953 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
9954 | ctk_tree_model_get_iter (CTK_TREE_MODEL (tree_view->priv->model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->model)), ((ctk_tree_model_get_type ())))))), |
9955 | &iter, path); |
9956 | retval = ctk_tree_view_unref_tree_helper (CTK_TREE_MODEL (tree_view->priv->model)((((CtkTreeModel*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->model)), ((ctk_tree_model_get_type ())))))), &iter, tree, node); |
9957 | ctk_tree_path_free (path); |
9958 | |
9959 | return retval; |
9960 | } |
9961 | |
9962 | static void |
9963 | ctk_tree_view_set_column_drag_info (CtkTreeView *tree_view, |
9964 | CtkTreeViewColumn *column) |
9965 | { |
9966 | CtkTreeViewColumn *left_column; |
9967 | CtkTreeViewColumn *cur_column = NULL((void*)0); |
9968 | CtkTreeViewColumnReorder *reorder; |
9969 | gboolean rtl; |
9970 | GList *tmp_list; |
9971 | gint left; |
9972 | |
9973 | /* We want to precalculate the motion list such that we know what column slots |
9974 | * are available. |
9975 | */ |
9976 | left_column = NULL((void*)0); |
9977 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
9978 | |
9979 | /* First, identify all possible drop spots */ |
9980 | if (rtl) |
9981 | tmp_list = g_list_last (tree_view->priv->columns); |
9982 | else |
9983 | tmp_list = g_list_first (tree_view->priv->columns); |
9984 | |
9985 | while (tmp_list) |
9986 | { |
9987 | cur_column = CTK_TREE_VIEW_COLUMN (tmp_list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tmp_list->data)), ((ctk_tree_view_column_get_type ())))))); |
9988 | tmp_list = rtl ? tmp_list->prev : tmp_list->next; |
9989 | |
9990 | if (ctk_tree_view_column_get_visible (cur_column) == FALSE(0)) |
9991 | continue; |
9992 | |
9993 | /* If it's not the column moving and func tells us to skip over the column, we continue. */ |
9994 | if (left_column != column && cur_column != column && |
9995 | tree_view->priv->column_drop_func && |
9996 | ! tree_view->priv->column_drop_func (tree_view, column, left_column, cur_column, tree_view->priv->column_drop_func_data)) |
9997 | { |
9998 | left_column = cur_column; |
9999 | continue; |
10000 | } |
10001 | reorder = g_slice_new0 (CtkTreeViewColumnReorder)((CtkTreeViewColumnReorder*) g_slice_alloc0 (sizeof (CtkTreeViewColumnReorder ))); |
10002 | reorder->left_column = left_column; |
10003 | left_column = reorder->right_column = cur_column; |
10004 | |
10005 | tree_view->priv->column_drag_info = g_list_append (tree_view->priv->column_drag_info, reorder); |
10006 | } |
10007 | |
10008 | /* Add the last one */ |
10009 | if (tree_view->priv->column_drop_func == NULL((void*)0) || |
10010 | ((left_column != column) && |
10011 | tree_view->priv->column_drop_func (tree_view, column, left_column, NULL((void*)0), tree_view->priv->column_drop_func_data))) |
10012 | { |
10013 | reorder = g_slice_new0 (CtkTreeViewColumnReorder)((CtkTreeViewColumnReorder*) g_slice_alloc0 (sizeof (CtkTreeViewColumnReorder ))); |
10014 | reorder->left_column = left_column; |
10015 | reorder->right_column = NULL((void*)0); |
10016 | tree_view->priv->column_drag_info = g_list_append (tree_view->priv->column_drag_info, reorder); |
10017 | } |
10018 | |
10019 | /* We quickly check to see if it even makes sense to reorder columns. */ |
10020 | /* If there is nothing that can be moved, then we return */ |
10021 | |
10022 | if (tree_view->priv->column_drag_info == NULL((void*)0)) |
10023 | return; |
10024 | |
10025 | /* We know there are always 2 slots possbile, as you can always return column. */ |
10026 | /* If that's all there is, return */ |
10027 | if (tree_view->priv->column_drag_info->next == NULL((void*)0) || |
10028 | (tree_view->priv->column_drag_info->next->next == NULL((void*)0) && |
10029 | ((CtkTreeViewColumnReorder *)tree_view->priv->column_drag_info->data)->right_column == column && |
10030 | ((CtkTreeViewColumnReorder *)tree_view->priv->column_drag_info->next->data)->left_column == column)) |
10031 | { |
10032 | for (tmp_list = tree_view->priv->column_drag_info; tmp_list; tmp_list = tmp_list->next) |
10033 | g_slice_free (CtkTreeViewColumnReorder, tmp_list->data)do { if (1) g_slice_free1 (sizeof (CtkTreeViewColumnReorder), (tmp_list->data)); else (void) ((CtkTreeViewColumnReorder *) 0 == (tmp_list->data)); } while (0); |
10034 | g_list_free (tree_view->priv->column_drag_info); |
10035 | tree_view->priv->column_drag_info = NULL((void*)0); |
10036 | return; |
10037 | } |
10038 | /* We fill in the ranges for the columns, now that we've isolated them */ |
10039 | left = - TREE_VIEW_COLUMN_DRAG_DEAD_MULTIPLIER (tree_view)(10*ctk_tree_view_get_effective_header_height(tree_view)); |
10040 | |
10041 | for (tmp_list = tree_view->priv->column_drag_info; tmp_list; tmp_list = tmp_list->next) |
10042 | { |
10043 | reorder = (CtkTreeViewColumnReorder *) tmp_list->data; |
10044 | |
10045 | reorder->left_align = left; |
10046 | if (tmp_list->next != NULL((void*)0)) |
10047 | { |
10048 | CtkAllocation right_allocation, left_allocation; |
10049 | CtkWidget *left_button, *right_button; |
10050 | |
10051 | g_assert (tmp_list->next->data)do { if (tmp_list->next->data) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c", 10051, ((const char*) (__func__)), "tmp_list->next->data" ); } while (0); |
10052 | |
10053 | right_button = ctk_tree_view_column_get_button (reorder->right_column); |
10054 | left_button = ctk_tree_view_column_get_button |
10055 | (((CtkTreeViewColumnReorder *)tmp_list->next->data)->left_column); |
10056 | |
10057 | ctk_widget_get_allocation (right_button, &right_allocation); |
10058 | ctk_widget_get_allocation (left_button, &left_allocation); |
10059 | left = reorder->right_align = (right_allocation.x + right_allocation.width + left_allocation.x) / 2; |
10060 | } |
10061 | else |
10062 | { |
10063 | reorder->right_align = cdk_window_get_width (tree_view->priv->header_window) |
10064 | + TREE_VIEW_COLUMN_DRAG_DEAD_MULTIPLIER (tree_view)(10*ctk_tree_view_get_effective_header_height(tree_view)); |
10065 | } |
10066 | } |
10067 | } |
10068 | |
10069 | void |
10070 | _ctk_tree_view_column_start_drag (CtkTreeView *tree_view, |
10071 | CtkTreeViewColumn *column, |
10072 | CdkDevice *device) |
10073 | { |
10074 | CtkAllocation allocation; |
10075 | CtkAllocation button_allocation; |
10076 | CtkWidget *button; |
10077 | CdkWindowAttr attributes; |
10078 | guint attributes_mask; |
10079 | CtkStyleContext *context; |
10080 | |
10081 | g_return_if_fail (tree_view->priv->column_drag_info == NULL)do { if ((tree_view->priv->column_drag_info == ((void*) 0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "tree_view->priv->column_drag_info == NULL" ); return; } } while (0); |
10082 | g_return_if_fail (tree_view->priv->cur_reorder == NULL)do { if ((tree_view->priv->cur_reorder == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "tree_view->priv->cur_reorder == NULL"); return; } } while (0); |
10083 | g_return_if_fail (tree_view->priv->drag_window == NULL)do { if ((tree_view->priv->drag_window == ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "tree_view->priv->drag_window == NULL"); return; } } while (0); |
10084 | |
10085 | ctk_tree_view_set_column_drag_info (tree_view, column); |
10086 | |
10087 | if (tree_view->priv->column_drag_info == NULL((void*)0)) |
10088 | return; |
10089 | |
10090 | button = ctk_tree_view_column_get_button (column); |
10091 | |
10092 | context = ctk_widget_get_style_context (button); |
10093 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_DND"dnd"); |
10094 | |
10095 | ctk_widget_get_allocation (button, &button_allocation); |
10096 | |
10097 | attributes.window_type = CDK_WINDOW_CHILD; |
10098 | attributes.wclass = CDK_INPUT_OUTPUT; |
10099 | attributes.x = button_allocation.x; |
10100 | attributes.y = 0; |
10101 | attributes.width = button_allocation.width; |
10102 | attributes.height = button_allocation.height; |
10103 | attributes.visual = ctk_widget_get_visual (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10104 | attributes.event_mask = CDK_VISIBILITY_NOTIFY_MASK | CDK_POINTER_MOTION_MASK; |
10105 | attributes_mask = CDK_WA_X | CDK_WA_Y | CDK_WA_VISUAL; |
10106 | |
10107 | tree_view->priv->drag_window = cdk_window_new (tree_view->priv->header_window, |
10108 | &attributes, |
10109 | attributes_mask); |
10110 | ctk_widget_register_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), tree_view->priv->drag_window); |
10111 | |
10112 | /* Kids, don't try this at home */ |
10113 | g_object_ref (button)((__typeof__ (button)) (g_object_ref) (button)); |
10114 | ctk_container_remove (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ())))))), button); |
10115 | ctk_widget_set_parent_window (button, tree_view->priv->drag_window); |
10116 | ctk_widget_set_parent (button, CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10117 | g_object_unref (button); |
10118 | |
10119 | ctk_widget_get_allocation (button, &button_allocation); |
10120 | tree_view->priv->drag_column_x = button_allocation.x; |
10121 | allocation = button_allocation; |
10122 | allocation.x = 0; |
10123 | ctk_widget_size_allocate (button, &allocation); |
10124 | |
10125 | tree_view->priv->drag_column = column; |
10126 | cdk_window_show (tree_view->priv->drag_window); |
10127 | |
10128 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10129 | |
10130 | tree_view->priv->in_column_drag = TRUE(!(0)); |
10131 | |
10132 | /* Widget reparenting above unmaps and indirectly breaks |
10133 | * the implicit grab, replace it with an active one. |
10134 | */ |
10135 | cdk_seat_grab (cdk_device_get_seat (device), |
10136 | tree_view->priv->drag_window, |
10137 | CDK_SEAT_CAPABILITY_ALL, FALSE(0), |
10138 | NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0)); |
10139 | |
10140 | ctk_gesture_set_state (tree_view->priv->column_drag_gesture, |
10141 | CTK_EVENT_SEQUENCE_CLAIMED); |
10142 | } |
10143 | |
10144 | static void |
10145 | ctk_tree_view_queue_draw_arrow (CtkTreeView *tree_view, |
10146 | CtkRBTree *tree, |
10147 | CtkRBNode *node) |
10148 | { |
10149 | CtkAllocation allocation; |
10150 | CdkRectangle rect; |
10151 | |
10152 | if (!ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10153 | return; |
10154 | |
10155 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
10156 | rect.x = 0; |
10157 | rect.width = ctk_tree_view_get_expander_size (tree_view); |
10158 | rect.width = MAX (rect.width, MAX (tree_view->priv->width, allocation.width))(((rect.width) > ((((tree_view->priv->width) > (allocation .width)) ? (tree_view->priv->width) : (allocation.width )))) ? (rect.width) : ((((tree_view->priv->width) > ( allocation.width)) ? (tree_view->priv->width) : (allocation .width)))); |
10159 | |
10160 | rect.y = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
10161 | rect.height = ctk_tree_view_get_row_height (tree_view, node); |
10162 | |
10163 | cdk_window_invalidate_rect (tree_view->priv->bin_window, &rect, TRUE(!(0))); |
10164 | } |
10165 | |
10166 | void |
10167 | _ctk_tree_view_queue_draw_node (CtkTreeView *tree_view, |
10168 | CtkRBTree *tree, |
10169 | CtkRBNode *node, |
10170 | const CdkRectangle *clip_rect) |
10171 | { |
10172 | CtkAllocation allocation; |
10173 | CdkRectangle rect; |
10174 | |
10175 | if (!ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10176 | return; |
10177 | |
10178 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
10179 | rect.x = 0; |
10180 | rect.width = MAX (tree_view->priv->width, allocation.width)(((tree_view->priv->width) > (allocation.width)) ? ( tree_view->priv->width) : (allocation.width)); |
10181 | |
10182 | rect.y = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
10183 | rect.height = ctk_tree_view_get_row_height (tree_view, node); |
10184 | |
10185 | if (clip_rect) |
10186 | { |
10187 | CdkRectangle new_rect; |
10188 | |
10189 | cdk_rectangle_intersect (clip_rect, &rect, &new_rect); |
10190 | |
10191 | cdk_window_invalidate_rect (tree_view->priv->bin_window, &new_rect, TRUE(!(0))); |
10192 | } |
10193 | else |
10194 | { |
10195 | cdk_window_invalidate_rect (tree_view->priv->bin_window, &rect, TRUE(!(0))); |
10196 | } |
10197 | } |
10198 | |
10199 | static inline gint |
10200 | ctk_tree_view_get_effective_header_height (CtkTreeView *tree_view) |
10201 | { |
10202 | if (tree_view->priv->headers_visible) |
10203 | return tree_view->priv->header_height; |
10204 | /* else */ |
10205 | return 0; |
10206 | } |
10207 | |
10208 | gint |
10209 | _ctk_tree_view_get_header_height (CtkTreeView *tree_view) |
10210 | { |
10211 | return tree_view->priv->header_height; |
10212 | } |
10213 | |
10214 | void |
10215 | _ctk_tree_view_get_row_separator_func (CtkTreeView *tree_view, |
10216 | CtkTreeViewRowSeparatorFunc *func, |
10217 | gpointer *data) |
10218 | { |
10219 | *func = tree_view->priv->row_separator_func; |
10220 | *data = tree_view->priv->row_separator_data; |
10221 | } |
10222 | |
10223 | CtkTreePath * |
10224 | _ctk_tree_view_get_anchor_path (CtkTreeView *tree_view) |
10225 | { |
10226 | if (tree_view->priv->anchor) |
10227 | return ctk_tree_row_reference_get_path (tree_view->priv->anchor); |
10228 | |
10229 | return NULL((void*)0); |
10230 | } |
10231 | |
10232 | void |
10233 | _ctk_tree_view_set_anchor_path (CtkTreeView *tree_view, |
10234 | CtkTreePath *anchor_path) |
10235 | { |
10236 | if (tree_view->priv->anchor) |
10237 | { |
10238 | ctk_tree_row_reference_free (tree_view->priv->anchor); |
10239 | tree_view->priv->anchor = NULL((void*)0); |
10240 | } |
10241 | |
10242 | if (anchor_path && tree_view->priv->model) |
10243 | tree_view->priv->anchor = |
10244 | ctk_tree_row_reference_new_proxy (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), |
10245 | tree_view->priv->model, anchor_path); |
10246 | } |
10247 | |
10248 | CtkRBTree * |
10249 | _ctk_tree_view_get_rbtree (CtkTreeView *tree_view) |
10250 | { |
10251 | return tree_view->priv->tree; |
10252 | } |
10253 | |
10254 | gboolean |
10255 | _ctk_tree_view_get_cursor_node (CtkTreeView *tree_view, |
10256 | CtkRBTree **tree, |
10257 | CtkRBNode **node) |
10258 | { |
10259 | CtkTreeViewPrivate *priv; |
10260 | |
10261 | priv = tree_view->priv; |
10262 | |
10263 | if (priv->cursor_node == NULL((void*)0)) |
10264 | return FALSE(0); |
10265 | |
10266 | *tree = priv->cursor_tree; |
10267 | *node = priv->cursor_node; |
10268 | |
10269 | return TRUE(!(0)); |
10270 | } |
10271 | |
10272 | CdkWindow * |
10273 | _ctk_tree_view_get_header_window (CtkTreeView *tree_view) |
10274 | { |
10275 | return tree_view->priv->header_window; |
10276 | } |
10277 | |
10278 | CtkTreeViewColumn * |
10279 | _ctk_tree_view_get_focus_column (CtkTreeView *tree_view) |
10280 | { |
10281 | return tree_view->priv->focus_column; |
10282 | } |
10283 | |
10284 | void |
10285 | _ctk_tree_view_set_focus_column (CtkTreeView *tree_view, |
10286 | CtkTreeViewColumn *column) |
10287 | { |
10288 | CtkTreeViewColumn *old_column = tree_view->priv->focus_column; |
10289 | |
10290 | if (old_column == column) |
10291 | return; |
10292 | |
10293 | tree_view->priv->focus_column = column; |
10294 | |
10295 | _ctk_tree_view_accessible_update_focus_column (tree_view, |
10296 | old_column, |
10297 | column); |
10298 | } |
10299 | |
10300 | |
10301 | static void |
10302 | ctk_tree_view_queue_draw_path (CtkTreeView *tree_view, |
10303 | CtkTreePath *path, |
10304 | const CdkRectangle *clip_rect) |
10305 | { |
10306 | CtkRBTree *tree = NULL((void*)0); |
10307 | CtkRBNode *node = NULL((void*)0); |
10308 | |
10309 | _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
10310 | |
10311 | if (tree) |
10312 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, clip_rect); |
10313 | } |
10314 | |
10315 | /* x and y are the mouse position |
10316 | */ |
10317 | static void |
10318 | ctk_tree_view_draw_arrow (CtkTreeView *tree_view, |
10319 | cairo_t *cr, |
10320 | CtkRBTree *tree, |
10321 | CtkRBNode *node) |
10322 | { |
10323 | CdkRectangle area; |
10324 | CtkStateFlags state = 0; |
10325 | CtkStyleContext *context; |
10326 | CtkWidget *widget; |
10327 | gint x_offset = 0; |
10328 | gint x2; |
10329 | gint vertical_separator; |
10330 | CtkCellRendererState flags = 0; |
10331 | |
10332 | widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
10333 | context = ctk_widget_get_style_context (widget); |
10334 | |
10335 | ctk_widget_style_get (widget, |
10336 | "vertical-separator", &vertical_separator, |
10337 | NULL((void*)0)); |
10338 | |
10339 | if (! CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0))) |
10340 | return; |
10341 | |
10342 | ctk_tree_view_get_arrow_xrange (tree_view, tree, &x_offset, &x2); |
10343 | |
10344 | area.x = x_offset; |
10345 | area.y = ctk_tree_view_get_cell_area_y_offset (tree_view, tree, node, |
10346 | vertical_separator); |
10347 | area.width = x2 - x_offset; |
10348 | area.height = ctk_tree_view_get_cell_area_height (tree_view, node, |
10349 | vertical_separator); |
10350 | |
10351 | if (CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_SELECTED)(node?(((node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
10352 | flags |= CTK_CELL_RENDERER_SELECTED; |
10353 | |
10354 | if (node == tree_view->priv->prelight_node && |
10355 | tree_view->priv->arrow_prelit) |
10356 | flags |= CTK_CELL_RENDERER_PRELIT; |
10357 | |
10358 | state = ctk_cell_renderer_get_state (NULL((void*)0), widget, flags); |
10359 | |
10360 | if (node->children != NULL((void*)0)) |
10361 | state |= CTK_STATE_FLAG_CHECKED; |
10362 | else |
10363 | state &= ~(CTK_STATE_FLAG_CHECKED); |
10364 | |
10365 | ctk_style_context_save (context); |
10366 | |
10367 | ctk_style_context_set_state (context, state); |
10368 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_EXPANDER"expander"); |
10369 | |
10370 | /* Make sure area.height has the same parity as the "expander-size" style |
10371 | * property (which area.width is assumed to be exactly equal to). This is done |
10372 | * to avoid the arrow being vertically centered in a half-pixel, which would |
10373 | * result in a fuzzy rendering. |
10374 | */ |
10375 | if (area.height % 2 != area.width % 2) |
10376 | { |
10377 | area.y += 1; |
10378 | area.height -= 1; |
10379 | } |
10380 | |
10381 | ctk_render_expander (context, cr, |
10382 | area.x, area.y, |
10383 | area.width, area.height); |
10384 | |
10385 | ctk_style_context_restore (context); |
10386 | } |
10387 | |
10388 | static void |
10389 | ctk_tree_view_focus_to_cursor (CtkTreeView *tree_view) |
10390 | |
10391 | { |
10392 | CtkTreePath *cursor_path; |
10393 | |
10394 | if ((tree_view->priv->tree == NULL((void*)0)) || |
10395 | (! ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))))) |
10396 | return; |
10397 | |
10398 | cursor_path = NULL((void*)0); |
10399 | if (tree_view->priv->cursor_node) |
10400 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
10401 | tree_view->priv->cursor_node); |
10402 | |
10403 | if (cursor_path == NULL((void*)0)) |
10404 | { |
10405 | /* Consult the selection before defaulting to the |
10406 | * first focusable element |
10407 | */ |
10408 | GList *selected_rows; |
10409 | CtkTreeModel *model; |
10410 | CtkTreeSelection *selection; |
10411 | |
10412 | selection = ctk_tree_view_get_selection (tree_view); |
10413 | selected_rows = ctk_tree_selection_get_selected_rows (selection, &model); |
10414 | |
10415 | if (selected_rows) |
10416 | { |
10417 | cursor_path = ctk_tree_path_copy((const CtkTreePath *)(selected_rows->data)); |
10418 | g_list_free_full (selected_rows, (GDestroyNotify) ctk_tree_path_free); |
10419 | } |
10420 | else |
10421 | { |
10422 | cursor_path = ctk_tree_path_new_first (); |
10423 | search_first_focusable_path (tree_view, &cursor_path, |
10424 | TRUE(!(0)), NULL((void*)0), NULL((void*)0)); |
10425 | } |
10426 | |
10427 | if (cursor_path) |
10428 | { |
10429 | if (ctk_tree_selection_get_mode (tree_view->priv->selection) == CTK_SELECTION_MULTIPLE) |
10430 | ctk_tree_view_real_set_cursor (tree_view, cursor_path, 0); |
10431 | else |
10432 | ctk_tree_view_real_set_cursor (tree_view, cursor_path, CLEAR_AND_SELECT); |
10433 | } |
10434 | } |
10435 | |
10436 | if (cursor_path) |
10437 | { |
10438 | tree_view->priv->draw_keyfocus = TRUE(!(0)); |
10439 | |
10440 | ctk_tree_view_queue_draw_path (tree_view, cursor_path, NULL((void*)0)); |
10441 | ctk_tree_path_free (cursor_path); |
10442 | |
10443 | if (tree_view->priv->focus_column == NULL((void*)0)) |
10444 | { |
10445 | GList *list; |
10446 | for (list = tree_view->priv->columns; list; list = list->next) |
10447 | { |
10448 | if (ctk_tree_view_column_get_visible (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))))) |
10449 | { |
10450 | CtkCellArea *cell_area; |
10451 | |
10452 | _ctk_tree_view_set_focus_column (tree_view, CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))); |
10453 | |
10454 | /* This happens when the treeview initially grabs focus and there |
10455 | * is no column in focus, here we explicitly focus into the first cell */ |
10456 | cell_area = ctk_cell_layout_get_area (CTK_CELL_LAYOUT (tree_view->priv->focus_column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->focus_column)), ((ctk_cell_layout_get_type ()))))))); |
10457 | if (!ctk_cell_area_get_focus_cell (cell_area)) |
10458 | { |
10459 | gboolean rtl; |
10460 | |
10461 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
10462 | ctk_cell_area_focus (cell_area, |
10463 | rtl ? CTK_DIR_LEFT : CTK_DIR_RIGHT); |
10464 | } |
10465 | |
10466 | break; |
10467 | } |
10468 | } |
10469 | } |
10470 | } |
10471 | } |
10472 | |
10473 | static void |
10474 | ctk_tree_view_move_cursor_up_down (CtkTreeView *tree_view, |
10475 | gint count) |
10476 | { |
10477 | gint selection_count; |
10478 | CtkRBTree *new_cursor_tree = NULL((void*)0); |
10479 | CtkRBNode *new_cursor_node = NULL((void*)0); |
10480 | CtkTreePath *cursor_path = NULL((void*)0); |
10481 | gboolean grab_focus = TRUE(!(0)); |
10482 | gboolean selectable; |
10483 | CtkDirectionType direction; |
10484 | CtkCellArea *cell_area = NULL((void*)0); |
10485 | CtkCellRenderer *last_focus_cell = NULL((void*)0); |
10486 | CtkTreeIter iter; |
10487 | |
10488 | if (! ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10489 | return; |
10490 | |
10491 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
10492 | return; |
10493 | |
10494 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
10495 | tree_view->priv->cursor_node); |
10496 | |
10497 | direction = count < 0 ? CTK_DIR_UP : CTK_DIR_DOWN; |
10498 | |
10499 | if (tree_view->priv->focus_column) |
10500 | cell_area = ctk_cell_layout_get_area (CTK_CELL_LAYOUT (tree_view->priv->focus_column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->focus_column)), ((ctk_cell_layout_get_type ()))))))); |
10501 | |
10502 | /* If focus stays in the area for this row, then just return for this round */ |
10503 | if (cell_area && (count == -1 || count == 1) && |
10504 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path)) |
10505 | { |
10506 | ctk_tree_view_column_cell_set_cell_data (tree_view->priv->focus_column, |
10507 | tree_view->priv->model, |
10508 | &iter, |
10509 | CTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, CTK_RBNODE_IS_PARENT)(tree_view->priv->cursor_node?(((tree_view->priv-> cursor_node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
10510 | tree_view->priv->cursor_node->children ? TRUE(!(0)) : FALSE(0)); |
10511 | |
10512 | /* Save the last cell that had focus, if we hit the end of the view we'll give |
10513 | * focus back to it. */ |
10514 | last_focus_cell = ctk_cell_area_get_focus_cell (cell_area); |
10515 | |
10516 | /* If focus stays in the area, no need to change the cursor row */ |
10517 | if (ctk_cell_area_focus (cell_area, direction)) |
10518 | return; |
10519 | } |
10520 | |
10521 | selection_count = ctk_tree_selection_count_selected_rows (tree_view->priv->selection); |
10522 | selectable = _ctk_tree_selection_row_is_selectable (tree_view->priv->selection, |
10523 | tree_view->priv->cursor_node, |
10524 | cursor_path); |
10525 | |
10526 | if (selection_count == 0 |
10527 | && ctk_tree_selection_get_mode (tree_view->priv->selection) != CTK_SELECTION_NONE |
10528 | && !tree_view->priv->modify_selection_pressed |
10529 | && selectable) |
10530 | { |
10531 | /* Don't move the cursor, but just select the current node */ |
10532 | new_cursor_tree = tree_view->priv->cursor_tree; |
10533 | new_cursor_node = tree_view->priv->cursor_node; |
10534 | } |
10535 | else |
10536 | { |
10537 | if (count == -1) |
10538 | _ctk_rbtree_prev_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node, |
10539 | &new_cursor_tree, &new_cursor_node); |
10540 | else |
10541 | _ctk_rbtree_next_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node, |
10542 | &new_cursor_tree, &new_cursor_node); |
10543 | } |
10544 | |
10545 | ctk_tree_path_free (cursor_path); |
10546 | |
10547 | if (new_cursor_node) |
10548 | { |
10549 | cursor_path = _ctk_tree_path_new_from_rbtree (new_cursor_tree, new_cursor_node); |
10550 | |
10551 | search_first_focusable_path (tree_view, &cursor_path, |
10552 | (count != -1), |
10553 | &new_cursor_tree, |
10554 | &new_cursor_node); |
10555 | |
10556 | if (cursor_path) |
10557 | ctk_tree_path_free (cursor_path); |
10558 | } |
10559 | |
10560 | /* |
10561 | * If the list has only one item and multi-selection is set then select |
10562 | * the row (if not yet selected). |
10563 | */ |
10564 | if (ctk_tree_selection_get_mode (tree_view->priv->selection) == CTK_SELECTION_MULTIPLE && |
10565 | new_cursor_node == NULL((void*)0)) |
10566 | { |
10567 | if (count == -1) |
10568 | _ctk_rbtree_next_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node, |
10569 | &new_cursor_tree, &new_cursor_node); |
10570 | else |
10571 | _ctk_rbtree_prev_full (tree_view->priv->cursor_tree, tree_view->priv->cursor_node, |
10572 | &new_cursor_tree, &new_cursor_node); |
10573 | |
10574 | if (new_cursor_node == NULL((void*)0) |
10575 | && !CTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, CTK_RBNODE_IS_SELECTED)(tree_view->priv->cursor_node?(((tree_view->priv-> cursor_node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
10576 | { |
10577 | new_cursor_node = tree_view->priv->cursor_node; |
10578 | new_cursor_tree = tree_view->priv->cursor_tree; |
10579 | } |
10580 | else |
10581 | { |
10582 | new_cursor_tree = NULL((void*)0); |
10583 | new_cursor_node = NULL((void*)0); |
10584 | } |
10585 | } |
10586 | |
10587 | if (new_cursor_node) |
10588 | { |
10589 | cursor_path = _ctk_tree_path_new_from_rbtree (new_cursor_tree, new_cursor_node); |
10590 | ctk_tree_view_real_set_cursor (tree_view, cursor_path, CLEAR_AND_SELECT | CLAMP_NODE); |
10591 | ctk_tree_path_free (cursor_path); |
10592 | |
10593 | /* Give focus to the area in the new row */ |
10594 | if (cell_area) |
10595 | ctk_cell_area_focus (cell_area, direction); |
10596 | } |
10597 | else |
10598 | { |
10599 | ctk_tree_view_clamp_node_visible (tree_view, |
10600 | tree_view->priv->cursor_tree, |
10601 | tree_view->priv->cursor_node); |
10602 | |
10603 | if (!tree_view->priv->extend_selection_pressed) |
10604 | { |
10605 | if (! ctk_widget_keynav_failed (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
10606 | count < 0 ? |
10607 | CTK_DIR_UP : CTK_DIR_DOWN)) |
10608 | { |
10609 | CtkWidget *toplevel = ctk_widget_get_toplevel (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10610 | |
10611 | if (toplevel) |
10612 | ctk_widget_child_focus (toplevel, |
10613 | count < 0 ? |
10614 | CTK_DIR_TAB_BACKWARD : |
10615 | CTK_DIR_TAB_FORWARD); |
10616 | |
10617 | grab_focus = FALSE(0); |
10618 | } |
10619 | } |
10620 | else |
10621 | { |
10622 | ctk_widget_error_bell (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10623 | } |
10624 | |
10625 | if (cell_area) |
10626 | ctk_cell_area_set_focus_cell (cell_area, last_focus_cell); |
10627 | } |
10628 | |
10629 | if (grab_focus) |
10630 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10631 | } |
10632 | |
10633 | static void |
10634 | ctk_tree_view_move_cursor_page_up_down (CtkTreeView *tree_view, |
10635 | gint count) |
10636 | { |
10637 | CtkTreePath *old_cursor_path = NULL((void*)0); |
10638 | CtkTreePath *cursor_path = NULL((void*)0); |
10639 | CtkRBTree *start_cursor_tree = NULL((void*)0); |
10640 | CtkRBNode *start_cursor_node = NULL((void*)0); |
10641 | CtkRBTree *cursor_tree; |
10642 | CtkRBNode *cursor_node; |
10643 | gint y; |
10644 | gint window_y; |
10645 | gint vertical_separator; |
10646 | |
10647 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10648 | return; |
10649 | |
10650 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
10651 | return; |
10652 | |
10653 | old_cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
10654 | tree_view->priv->cursor_node); |
10655 | |
10656 | ctk_widget_style_get (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), "vertical-separator", &vertical_separator, NULL((void*)0)); |
10657 | |
10658 | y = _ctk_rbtree_node_find_offset (tree_view->priv->cursor_tree, tree_view->priv->cursor_node); |
10659 | window_y = RBTREE_Y_TO_TREE_WINDOW_Y (tree_view, y)((y) - tree_view->priv->dy); |
10660 | y += tree_view->priv->cursor_offset; |
10661 | y += count * (int)ctk_adjustment_get_page_increment (tree_view->priv->vadjustment); |
10662 | y = CLAMP (y, (gint)ctk_adjustment_get_lower (tree_view->priv->vadjustment), (gint)ctk_adjustment_get_upper (tree_view->priv->vadjustment) - vertical_separator)(((y) > ((gint)ctk_adjustment_get_upper (tree_view->priv ->vadjustment) - vertical_separator)) ? ((gint)ctk_adjustment_get_upper (tree_view->priv->vadjustment) - vertical_separator) : (((y) < ((gint)ctk_adjustment_get_lower (tree_view->priv ->vadjustment))) ? ((gint)ctk_adjustment_get_lower (tree_view ->priv->vadjustment)) : (y))); |
10663 | |
10664 | if (y >= ctk_tree_view_get_height (tree_view)) |
10665 | y = ctk_tree_view_get_height (tree_view) - 1; |
10666 | |
10667 | tree_view->priv->cursor_offset = |
10668 | _ctk_rbtree_find_offset (tree_view->priv->tree, y, |
10669 | &cursor_tree, &cursor_node); |
10670 | |
10671 | if (cursor_tree == NULL((void*)0)) |
10672 | { |
10673 | /* FIXME: we lost the cursor. Should we try to get one? */ |
10674 | ctk_tree_path_free (old_cursor_path); |
10675 | return; |
10676 | } |
10677 | |
10678 | if (tree_view->priv->cursor_offset |
10679 | > ctk_tree_view_get_row_height (tree_view, cursor_node)) |
10680 | { |
10681 | _ctk_rbtree_next_full (cursor_tree, cursor_node, |
10682 | &cursor_tree, &cursor_node); |
10683 | tree_view->priv->cursor_offset -= ctk_tree_view_get_row_height (tree_view, cursor_node); |
10684 | } |
10685 | |
10686 | y -= tree_view->priv->cursor_offset; |
10687 | cursor_path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
10688 | |
10689 | start_cursor_tree = cursor_tree; |
10690 | start_cursor_node = cursor_node; |
10691 | |
10692 | if (! search_first_focusable_path (tree_view, &cursor_path, |
10693 | (count != -1), |
10694 | &cursor_tree, &cursor_node)) |
10695 | { |
10696 | /* It looks like we reached the end of the view without finding |
10697 | * a focusable row. We will step backwards to find the last |
10698 | * focusable row. |
10699 | */ |
10700 | cursor_tree = start_cursor_tree; |
10701 | cursor_node = start_cursor_node; |
10702 | cursor_path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
10703 | |
10704 | search_first_focusable_path (tree_view, &cursor_path, |
10705 | (count == -1), |
10706 | &cursor_tree, &cursor_node); |
10707 | } |
10708 | |
10709 | if (!cursor_path) |
10710 | goto cleanup; |
10711 | |
10712 | /* update y */ |
10713 | y = _ctk_rbtree_node_find_offset (cursor_tree, cursor_node); |
10714 | |
10715 | ctk_tree_view_real_set_cursor (tree_view, cursor_path, CLEAR_AND_SELECT); |
10716 | |
10717 | y -= window_y; |
10718 | ctk_tree_view_scroll_to_point (tree_view, -1, y); |
10719 | ctk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node); |
10720 | _ctk_tree_view_queue_draw_node (tree_view, cursor_tree, cursor_node, NULL((void*)0)); |
10721 | |
10722 | if (!ctk_tree_path_compare (old_cursor_path, cursor_path)) |
10723 | ctk_widget_error_bell (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10724 | |
10725 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10726 | |
10727 | cleanup: |
10728 | ctk_tree_path_free (old_cursor_path); |
10729 | ctk_tree_path_free (cursor_path); |
10730 | } |
10731 | |
10732 | static void |
10733 | ctk_tree_view_move_cursor_left_right (CtkTreeView *tree_view, |
10734 | gint count) |
10735 | { |
10736 | CtkTreePath *cursor_path = NULL((void*)0); |
10737 | CtkTreeViewColumn *column; |
10738 | CtkTreeIter iter; |
10739 | GList *list; |
10740 | gboolean found_column = FALSE(0); |
10741 | gboolean rtl; |
10742 | CtkDirectionType direction; |
10743 | CtkCellArea *cell_area; |
10744 | CtkCellRenderer *last_focus_cell = NULL((void*)0); |
10745 | CtkCellArea *last_focus_area = NULL((void*)0); |
10746 | |
10747 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
10748 | |
10749 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10750 | return; |
10751 | |
10752 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
10753 | return; |
10754 | |
10755 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
10756 | tree_view->priv->cursor_node); |
10757 | |
10758 | if (ctk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path) == FALSE(0)) |
10759 | { |
10760 | ctk_tree_path_free (cursor_path); |
10761 | return; |
10762 | } |
10763 | ctk_tree_path_free (cursor_path); |
10764 | |
10765 | list = rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns); |
10766 | if (tree_view->priv->focus_column) |
10767 | { |
10768 | /* Save the cell/area we are moving focus from, if moving the cursor |
10769 | * by one step hits the end we'll set focus back here */ |
10770 | last_focus_area = ctk_cell_layout_get_area (CTK_CELL_LAYOUT (tree_view->priv->focus_column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->focus_column)), ((ctk_cell_layout_get_type ()))))))); |
10771 | last_focus_cell = ctk_cell_area_get_focus_cell (last_focus_area); |
10772 | |
10773 | for (; list; list = (rtl ? list->prev : list->next)) |
10774 | { |
10775 | if (list->data == tree_view->priv->focus_column) |
10776 | break; |
10777 | } |
10778 | } |
10779 | |
10780 | direction = count > 0 ? CTK_DIR_RIGHT : CTK_DIR_LEFT; |
10781 | |
10782 | while (list) |
10783 | { |
10784 | column = list->data; |
10785 | if (ctk_tree_view_column_get_visible (column) == FALSE(0)) |
10786 | goto loop_end; |
10787 | |
10788 | ctk_tree_view_column_cell_set_cell_data (column, |
10789 | tree_view->priv->model, |
10790 | &iter, |
10791 | CTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, CTK_RBNODE_IS_PARENT)(tree_view->priv->cursor_node?(((tree_view->priv-> cursor_node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
10792 | tree_view->priv->cursor_node->children ? TRUE(!(0)) : FALSE(0)); |
10793 | |
10794 | cell_area = ctk_cell_layout_get_area (CTK_CELL_LAYOUT (column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((column)), ((ctk_cell_layout_get_type ()))))))); |
10795 | if (ctk_cell_area_focus (cell_area, direction)) |
10796 | { |
10797 | _ctk_tree_view_set_focus_column (tree_view, column); |
10798 | found_column = TRUE(!(0)); |
10799 | break; |
10800 | } |
10801 | |
10802 | loop_end: |
10803 | if (count == 1) |
10804 | list = rtl ? list->prev : list->next; |
10805 | else |
10806 | list = rtl ? list->next : list->prev; |
10807 | } |
10808 | |
10809 | if (found_column) |
10810 | { |
10811 | if (!ctk_tree_view_has_can_focus_cell (tree_view)) |
10812 | _ctk_tree_view_queue_draw_node (tree_view, |
10813 | tree_view->priv->cursor_tree, |
10814 | tree_view->priv->cursor_node, |
10815 | NULL((void*)0)); |
10816 | g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0); |
10817 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10818 | } |
10819 | else |
10820 | { |
10821 | ctk_widget_error_bell (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10822 | |
10823 | if (last_focus_area) |
10824 | ctk_cell_area_set_focus_cell (last_focus_area, last_focus_cell); |
10825 | } |
10826 | |
10827 | ctk_tree_view_clamp_column_visible (tree_view, |
10828 | tree_view->priv->focus_column, TRUE(!(0))); |
10829 | } |
10830 | |
10831 | static void |
10832 | ctk_tree_view_move_cursor_start_end (CtkTreeView *tree_view, |
10833 | gint count) |
10834 | { |
10835 | CtkRBTree *cursor_tree; |
10836 | CtkRBNode *cursor_node; |
10837 | CtkTreePath *path; |
10838 | CtkTreePath *old_path; |
10839 | |
10840 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10841 | return; |
10842 | |
10843 | g_return_if_fail (tree_view->priv->tree != NULL)do { if ((tree_view->priv->tree != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "tree_view->priv->tree != NULL"); return; } } while ( 0); |
10844 | |
10845 | ctk_tree_view_get_cursor (tree_view, &old_path, NULL((void*)0)); |
10846 | |
10847 | cursor_tree = tree_view->priv->tree; |
10848 | |
10849 | if (count == -1) |
10850 | { |
10851 | cursor_node = _ctk_rbtree_first (cursor_tree); |
10852 | |
10853 | /* Now go forward to find the first focusable row. */ |
10854 | path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
10855 | search_first_focusable_path (tree_view, &path, |
10856 | TRUE(!(0)), &cursor_tree, &cursor_node); |
10857 | } |
10858 | else |
10859 | { |
10860 | cursor_node = cursor_tree->root; |
10861 | |
10862 | do |
10863 | { |
10864 | while (cursor_node && !_ctk_rbtree_is_nil (cursor_node->right)) |
10865 | cursor_node = cursor_node->right; |
10866 | if (cursor_node->children == NULL((void*)0)) |
10867 | break; |
10868 | |
10869 | cursor_tree = cursor_node->children; |
10870 | cursor_node = cursor_tree->root; |
10871 | } |
10872 | while (1); |
10873 | |
10874 | /* Now go backwards to find last focusable row. */ |
10875 | path = _ctk_tree_path_new_from_rbtree (cursor_tree, cursor_node); |
10876 | search_first_focusable_path (tree_view, &path, |
10877 | FALSE(0), &cursor_tree, &cursor_node); |
10878 | } |
10879 | |
10880 | if (!path) |
10881 | goto cleanup; |
10882 | |
10883 | if (ctk_tree_path_compare (old_path, path)) |
10884 | { |
10885 | ctk_tree_view_real_set_cursor (tree_view, path, CLEAR_AND_SELECT | CLAMP_NODE); |
10886 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10887 | } |
10888 | else |
10889 | { |
10890 | ctk_widget_error_bell (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10891 | } |
10892 | |
10893 | cleanup: |
10894 | ctk_tree_path_free (old_path); |
10895 | ctk_tree_path_free (path); |
10896 | } |
10897 | |
10898 | static gboolean |
10899 | ctk_tree_view_real_select_all (CtkTreeView *tree_view) |
10900 | { |
10901 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10902 | return FALSE(0); |
10903 | |
10904 | if (ctk_tree_selection_get_mode (tree_view->priv->selection) != CTK_SELECTION_MULTIPLE) |
10905 | return FALSE(0); |
10906 | |
10907 | ctk_tree_selection_select_all (tree_view->priv->selection); |
10908 | |
10909 | return TRUE(!(0)); |
10910 | } |
10911 | |
10912 | static gboolean |
10913 | ctk_tree_view_real_unselect_all (CtkTreeView *tree_view) |
10914 | { |
10915 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10916 | return FALSE(0); |
10917 | |
10918 | if (ctk_tree_selection_get_mode (tree_view->priv->selection) != CTK_SELECTION_MULTIPLE) |
10919 | return FALSE(0); |
10920 | |
10921 | ctk_tree_selection_unselect_all (tree_view->priv->selection); |
10922 | |
10923 | return TRUE(!(0)); |
10924 | } |
10925 | |
10926 | static gboolean |
10927 | ctk_tree_view_real_select_cursor_row (CtkTreeView *tree_view, |
10928 | gboolean start_editing) |
10929 | { |
10930 | CtkRBTree *new_tree = NULL((void*)0); |
10931 | CtkRBNode *new_node = NULL((void*)0); |
10932 | CtkRBTree *cursor_tree = NULL((void*)0); |
10933 | CtkRBNode *cursor_node = NULL((void*)0); |
10934 | CtkTreePath *cursor_path = NULL((void*)0); |
10935 | CtkTreeSelectMode mode = 0; |
10936 | |
10937 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
10938 | return FALSE(0); |
10939 | |
10940 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
10941 | return FALSE(0); |
10942 | |
10943 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
10944 | tree_view->priv->cursor_node); |
10945 | |
10946 | _ctk_tree_view_find_node (tree_view, cursor_path, |
10947 | &cursor_tree, &cursor_node); |
10948 | |
10949 | if (cursor_tree == NULL((void*)0)) |
10950 | { |
10951 | ctk_tree_path_free (cursor_path); |
10952 | return FALSE(0); |
10953 | } |
10954 | |
10955 | if (!tree_view->priv->extend_selection_pressed && start_editing && |
10956 | tree_view->priv->focus_column) |
10957 | { |
10958 | if (ctk_tree_view_start_editing (tree_view, cursor_path, FALSE(0))) |
10959 | { |
10960 | ctk_tree_path_free (cursor_path); |
10961 | return TRUE(!(0)); |
10962 | } |
10963 | } |
10964 | |
10965 | if (tree_view->priv->modify_selection_pressed) |
10966 | mode |= CTK_TREE_SELECT_MODE_TOGGLE; |
10967 | if (tree_view->priv->extend_selection_pressed) |
10968 | mode |= CTK_TREE_SELECT_MODE_EXTEND; |
10969 | |
10970 | _ctk_tree_selection_internal_select_node (tree_view->priv->selection, |
10971 | cursor_node, |
10972 | cursor_tree, |
10973 | cursor_path, |
10974 | mode, |
10975 | FALSE(0)); |
10976 | |
10977 | /* We bail out if the original (tree, node) don't exist anymore after |
10978 | * handling the selection-changed callback. We do return TRUE because |
10979 | * the key press has been handled at this point. |
10980 | */ |
10981 | _ctk_tree_view_find_node (tree_view, cursor_path, &new_tree, &new_node); |
10982 | |
10983 | if (cursor_tree != new_tree || cursor_node != new_node) |
10984 | return FALSE(0); |
10985 | |
10986 | ctk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node); |
10987 | |
10988 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
10989 | _ctk_tree_view_queue_draw_node (tree_view, cursor_tree, cursor_node, NULL((void*)0)); |
10990 | |
10991 | if (!tree_view->priv->extend_selection_pressed) |
10992 | ctk_tree_view_row_activated (tree_view, cursor_path, |
10993 | tree_view->priv->focus_column); |
10994 | |
10995 | ctk_tree_path_free (cursor_path); |
10996 | |
10997 | return TRUE(!(0)); |
10998 | } |
10999 | |
11000 | static gboolean |
11001 | ctk_tree_view_real_toggle_cursor_row (CtkTreeView *tree_view) |
11002 | { |
11003 | CtkRBTree *new_tree = NULL((void*)0); |
11004 | CtkRBNode *new_node = NULL((void*)0); |
11005 | CtkTreePath *cursor_path = NULL((void*)0); |
11006 | |
11007 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11008 | return FALSE(0); |
11009 | |
11010 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
11011 | return FALSE(0); |
11012 | |
11013 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
11014 | tree_view->priv->cursor_node); |
11015 | |
11016 | _ctk_tree_selection_internal_select_node (tree_view->priv->selection, |
11017 | tree_view->priv->cursor_node, |
11018 | tree_view->priv->cursor_tree, |
11019 | cursor_path, |
11020 | CTK_TREE_SELECT_MODE_TOGGLE, |
11021 | FALSE(0)); |
11022 | |
11023 | /* We bail out if the original (tree, node) don't exist anymore after |
11024 | * handling the selection-changed callback. We do return TRUE because |
11025 | * the key press has been handled at this point. |
11026 | */ |
11027 | _ctk_tree_view_find_node (tree_view, cursor_path, &new_tree, &new_node); |
11028 | |
11029 | if (tree_view->priv->cursor_node != new_node) |
11030 | return FALSE(0); |
11031 | |
11032 | ctk_tree_view_clamp_node_visible (tree_view, |
11033 | tree_view->priv->cursor_tree, |
11034 | tree_view->priv->cursor_node); |
11035 | |
11036 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11037 | ctk_tree_view_queue_draw_path (tree_view, cursor_path, NULL((void*)0)); |
11038 | ctk_tree_path_free (cursor_path); |
11039 | |
11040 | return TRUE(!(0)); |
11041 | } |
11042 | |
11043 | static gboolean |
11044 | ctk_tree_view_real_expand_collapse_cursor_row (CtkTreeView *tree_view, |
11045 | gboolean logical, |
11046 | gboolean expand, |
11047 | gboolean open_all) |
11048 | { |
11049 | CtkTreePath *cursor_path = NULL((void*)0); |
11050 | |
11051 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11052 | return FALSE(0); |
11053 | |
11054 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
11055 | return FALSE(0); |
11056 | |
11057 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
11058 | tree_view->priv->cursor_node); |
11059 | |
11060 | /* Don't handle the event if we aren't an expander */ |
11061 | if (!CTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, CTK_RBNODE_IS_PARENT)(tree_view->priv->cursor_node?(((tree_view->priv-> cursor_node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0))) |
11062 | return FALSE(0); |
11063 | |
11064 | if (!logical |
11065 | && ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL) |
11066 | expand = !expand; |
11067 | |
11068 | if (expand) |
11069 | ctk_tree_view_real_expand_row (tree_view, |
11070 | cursor_path, |
11071 | tree_view->priv->cursor_tree, |
11072 | tree_view->priv->cursor_node, |
11073 | open_all, |
11074 | TRUE(!(0))); |
11075 | else |
11076 | ctk_tree_view_real_collapse_row (tree_view, |
11077 | cursor_path, |
11078 | tree_view->priv->cursor_tree, |
11079 | tree_view->priv->cursor_node, |
11080 | TRUE(!(0))); |
11081 | |
11082 | ctk_tree_path_free (cursor_path); |
11083 | |
11084 | return TRUE(!(0)); |
11085 | } |
11086 | |
11087 | static gboolean |
11088 | ctk_tree_view_real_select_cursor_parent (CtkTreeView *tree_view) |
11089 | { |
11090 | CtkTreePath *cursor_path = NULL((void*)0); |
11091 | CdkModifierType state; |
11092 | |
11093 | if (!ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11094 | goto out; |
11095 | |
11096 | if (tree_view->priv->cursor_node == NULL((void*)0)) |
11097 | goto out; |
11098 | |
11099 | cursor_path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
11100 | tree_view->priv->cursor_node); |
11101 | |
11102 | if (tree_view->priv->cursor_tree->parent_node) |
11103 | { |
11104 | ctk_tree_view_queue_draw_path (tree_view, cursor_path, NULL((void*)0)); |
11105 | |
11106 | ctk_tree_path_up (cursor_path); |
11107 | |
11108 | if (ctk_get_current_event_state (&state)) |
11109 | { |
11110 | CdkModifierType modify_mod_mask; |
11111 | |
11112 | modify_mod_mask = |
11113 | ctk_widget_get_modifier_mask (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
11114 | CDK_MODIFIER_INTENT_MODIFY_SELECTION); |
11115 | |
11116 | if ((state & modify_mod_mask) == modify_mod_mask) |
11117 | tree_view->priv->modify_selection_pressed = TRUE(!(0)); |
11118 | } |
11119 | |
11120 | ctk_tree_view_real_set_cursor (tree_view, cursor_path, CLEAR_AND_SELECT | CLAMP_NODE); |
11121 | ctk_tree_path_free (cursor_path); |
11122 | |
11123 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11124 | |
11125 | tree_view->priv->modify_selection_pressed = FALSE(0); |
11126 | |
11127 | return TRUE(!(0)); |
11128 | } |
11129 | |
11130 | out: |
11131 | |
11132 | tree_view->priv->search_entry_avoid_unhandled_binding = TRUE(!(0)); |
11133 | return FALSE(0); |
11134 | } |
11135 | |
11136 | static gboolean |
11137 | ctk_tree_view_search_entry_flush_timeout (CtkTreeView *tree_view) |
11138 | { |
11139 | ctk_tree_view_search_window_hide (tree_view->priv->search_window, tree_view, NULL((void*)0)); |
11140 | tree_view->priv->typeselect_flush_timeout = 0; |
11141 | |
11142 | return FALSE(0); |
11143 | } |
11144 | |
11145 | /* Cut and paste from ctkwindow.c */ |
11146 | static void |
11147 | send_focus_change (CtkWidget *widget, |
11148 | CdkDevice *device, |
11149 | gboolean in) |
11150 | { |
11151 | CdkDeviceManager *device_manager; |
11152 | GList *devices, *d; |
11153 | |
11154 | G_GNUC_BEGIN_IGNORE_DEPRECATIONSclang diagnostic push
clang diagnostic ignored "-Wdeprecated-declarations" ; |
11155 | device_manager = cdk_display_get_device_manager (ctk_widget_get_display (widget)); |
11156 | devices = cdk_device_manager_list_devices (device_manager, CDK_DEVICE_TYPE_MASTER); |
11157 | devices = g_list_concat (devices, cdk_device_manager_list_devices (device_manager, CDK_DEVICE_TYPE_SLAVE)); |
11158 | devices = g_list_concat (devices, cdk_device_manager_list_devices (device_manager, CDK_DEVICE_TYPE_FLOATING)); |
11159 | G_GNUC_END_IGNORE_DEPRECATIONSclang diagnostic pop ; |
11160 | |
11161 | for (d = devices; d; d = d->next) |
11162 | { |
11163 | CdkDevice *dev = d->data; |
11164 | CdkEvent *fevent; |
11165 | CdkWindow *window; |
11166 | |
11167 | if (cdk_device_get_source (dev) != CDK_SOURCE_KEYBOARD) |
11168 | continue; |
11169 | |
11170 | window = ctk_widget_get_window (widget); |
11171 | |
11172 | /* Skip non-master keyboards that haven't |
11173 | * selected for events from this window |
11174 | */ |
11175 | if (cdk_device_get_device_type (dev) != CDK_DEVICE_TYPE_MASTER && |
11176 | !cdk_window_get_device_events (window, dev)) |
11177 | continue; |
11178 | |
11179 | fevent = cdk_event_new (CDK_FOCUS_CHANGE); |
11180 | |
11181 | fevent->focus_change.type = CDK_FOCUS_CHANGE; |
11182 | fevent->focus_change.window = g_object_ref (window)((__typeof__ (window)) (g_object_ref) (window)); |
11183 | fevent->focus_change.in = in; |
11184 | cdk_event_set_device (fevent, device); |
11185 | |
11186 | ctk_widget_send_focus_change (widget, fevent); |
11187 | |
11188 | cdk_event_free (fevent); |
11189 | } |
11190 | |
11191 | g_list_free (devices); |
11192 | } |
11193 | |
11194 | static void |
11195 | ctk_tree_view_ensure_interactive_directory (CtkTreeView *tree_view) |
11196 | { |
11197 | CtkWidget *frame, *vbox, *toplevel; |
11198 | CdkScreen *screen; |
11199 | |
11200 | if (tree_view->priv->search_custom_entry_set) |
11201 | return; |
11202 | |
11203 | toplevel = ctk_widget_get_toplevel (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11204 | screen = ctk_widget_get_screen (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11205 | |
11206 | if (tree_view->priv->search_window != NULL((void*)0)) |
11207 | { |
11208 | if (ctk_window_has_group (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ())))))))) |
11209 | ctk_window_group_add_window (ctk_window_get_group (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ()))))))), |
11210 | CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ()))))))); |
11211 | else if (ctk_window_has_group (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ())))))))) |
11212 | ctk_window_group_remove_window (ctk_window_get_group (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ()))))))), |
11213 | CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ()))))))); |
11214 | |
11215 | ctk_window_set_screen (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ())))))), screen); |
11216 | |
11217 | return; |
11218 | } |
11219 | |
11220 | tree_view->priv->search_window = ctk_window_new (CTK_WINDOW_POPUP); |
11221 | ctk_window_set_screen (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ())))))), screen); |
11222 | |
11223 | if (ctk_window_has_group (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ())))))))) |
11224 | ctk_window_group_add_window (ctk_window_get_group (CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ()))))))), |
11225 | CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ()))))))); |
11226 | |
11227 | ctk_window_set_type_hint (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ())))))), |
11228 | CDK_WINDOW_TYPE_HINT_UTILITY); |
11229 | ctk_window_set_modal (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ())))))), TRUE(!(0))); |
11230 | ctk_window_set_transient_for (CTK_WINDOW (tree_view->priv->search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_window_get_type ())))))), |
11231 | CTK_WINDOW (toplevel)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((toplevel)), ((ctk_window_get_type ()))))))); |
11232 | |
11233 | g_signal_connect (tree_view->priv->search_window, "delete-event",g_signal_connect_data ((tree_view->priv->search_window) , ("delete-event"), (((GCallback) (ctk_tree_view_search_delete_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11234 | G_CALLBACK (ctk_tree_view_search_delete_event),g_signal_connect_data ((tree_view->priv->search_window) , ("delete-event"), (((GCallback) (ctk_tree_view_search_delete_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11235 | tree_view)g_signal_connect_data ((tree_view->priv->search_window) , ("delete-event"), (((GCallback) (ctk_tree_view_search_delete_event ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11236 | g_signal_connect (tree_view->priv->search_window, "key-press-event",g_signal_connect_data ((tree_view->priv->search_window) , ("key-press-event"), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11237 | G_CALLBACK (ctk_tree_view_search_key_press_event),g_signal_connect_data ((tree_view->priv->search_window) , ("key-press-event"), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11238 | tree_view)g_signal_connect_data ((tree_view->priv->search_window) , ("key-press-event"), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11239 | g_signal_connect (tree_view->priv->search_window, "button-press-event",g_signal_connect_data ((tree_view->priv->search_window) , ("button-press-event"), (((GCallback) (ctk_tree_view_search_button_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11240 | G_CALLBACK (ctk_tree_view_search_button_press_event),g_signal_connect_data ((tree_view->priv->search_window) , ("button-press-event"), (((GCallback) (ctk_tree_view_search_button_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11241 | tree_view)g_signal_connect_data ((tree_view->priv->search_window) , ("button-press-event"), (((GCallback) (ctk_tree_view_search_button_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11242 | g_signal_connect (tree_view->priv->search_window, "scroll-event",g_signal_connect_data ((tree_view->priv->search_window) , ("scroll-event"), (((GCallback) (ctk_tree_view_search_scroll_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11243 | G_CALLBACK (ctk_tree_view_search_scroll_event),g_signal_connect_data ((tree_view->priv->search_window) , ("scroll-event"), (((GCallback) (ctk_tree_view_search_scroll_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11244 | tree_view)g_signal_connect_data ((tree_view->priv->search_window) , ("scroll-event"), (((GCallback) (ctk_tree_view_search_scroll_event ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11245 | |
11246 | frame = ctk_frame_new (NULL((void*)0)); |
11247 | ctk_frame_set_shadow_type (CTK_FRAME (frame)((((CtkFrame*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((frame)), ((ctk_frame_get_type ())))))), CTK_SHADOW_ETCHED_IN); |
11248 | ctk_widget_show (frame); |
11249 | ctk_container_add (CTK_CONTAINER (tree_view->priv->search_window)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_window)), ((ctk_container_get_type ())))))), frame); |
11250 | |
11251 | vbox = ctk_box_new (CTK_ORIENTATION_VERTICAL, 0); |
11252 | ctk_widget_show (vbox); |
11253 | ctk_container_add (CTK_CONTAINER (frame)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((frame)), ((ctk_container_get_type ())))))), vbox); |
11254 | ctk_container_set_border_width (CTK_CONTAINER (vbox)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((vbox)), ((ctk_container_get_type ())))))), 3); |
11255 | |
11256 | /* add entry */ |
11257 | tree_view->priv->search_entry = ctk_entry_new (); |
11258 | ctk_widget_show (tree_view->priv->search_entry); |
11259 | g_signal_connect (tree_view->priv->search_entry, "populate-popup",g_signal_connect_data ((tree_view->priv->search_entry), ("populate-popup"), (((GCallback) (ctk_tree_view_search_disable_popdown ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11260 | G_CALLBACK (ctk_tree_view_search_disable_popdown),g_signal_connect_data ((tree_view->priv->search_entry), ("populate-popup"), (((GCallback) (ctk_tree_view_search_disable_popdown ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11261 | tree_view)g_signal_connect_data ((tree_view->priv->search_entry), ("populate-popup"), (((GCallback) (ctk_tree_view_search_disable_popdown ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11262 | g_signal_connect (tree_view->priv->search_entry,g_signal_connect_data ((tree_view->priv->search_entry), ("activate"), (((GCallback) (ctk_tree_view_search_activate)) ), (tree_view), ((void*)0), (GConnectFlags) 0) |
11263 | "activate", G_CALLBACK (ctk_tree_view_search_activate),g_signal_connect_data ((tree_view->priv->search_entry), ("activate"), (((GCallback) (ctk_tree_view_search_activate)) ), (tree_view), ((void*)0), (GConnectFlags) 0) |
11264 | tree_view)g_signal_connect_data ((tree_view->priv->search_entry), ("activate"), (((GCallback) (ctk_tree_view_search_activate)) ), (tree_view), ((void*)0), (GConnectFlags) 0); |
11265 | |
11266 | g_signal_connect (_ctk_entry_get_im_context (CTK_ENTRY (tree_view->priv->search_entry)),g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("preedit-changed"), (((GCallback) (ctk_tree_view_search_preedit_changed ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11267 | "preedit-changed",g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("preedit-changed"), (((GCallback) (ctk_tree_view_search_preedit_changed ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11268 | G_CALLBACK (ctk_tree_view_search_preedit_changed),g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("preedit-changed"), (((GCallback) (ctk_tree_view_search_preedit_changed ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11269 | tree_view)g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("preedit-changed"), (((GCallback) (ctk_tree_view_search_preedit_changed ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11270 | g_signal_connect (_ctk_entry_get_im_context (CTK_ENTRY (tree_view->priv->search_entry)),g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("commit"), (((GCallback) (ctk_tree_view_search_commit))), ( tree_view), ((void*)0), (GConnectFlags) 0) |
11271 | "commit",g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("commit"), (((GCallback) (ctk_tree_view_search_commit))), ( tree_view), ((void*)0), (GConnectFlags) 0) |
11272 | G_CALLBACK (ctk_tree_view_search_commit),g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("commit"), (((GCallback) (ctk_tree_view_search_commit))), ( tree_view), ((void*)0), (GConnectFlags) 0) |
11273 | tree_view)g_signal_connect_data ((_ctk_entry_get_im_context (((((CtkEntry *) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view ->priv->search_entry)), ((ctk_entry_get_type ())))))))) , ("commit"), (((GCallback) (ctk_tree_view_search_commit))), ( tree_view), ((void*)0), (GConnectFlags) 0); |
11274 | |
11275 | ctk_container_add (CTK_CONTAINER (vbox)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((vbox)), ((ctk_container_get_type ())))))), |
11276 | tree_view->priv->search_entry); |
11277 | |
11278 | ctk_widget_realize (tree_view->priv->search_entry); |
11279 | } |
11280 | |
11281 | /* Pops up the interactive search entry. If keybinding is TRUE then the user |
11282 | * started this by typing the start_interactive_search keybinding. Otherwise, it came from |
11283 | */ |
11284 | static gboolean |
11285 | ctk_tree_view_real_start_interactive_search (CtkTreeView *tree_view, |
11286 | CdkDevice *device, |
11287 | gboolean keybinding) |
11288 | { |
11289 | /* We only start interactive search if we have focus or the columns |
11290 | * have focus. If one of our children have focus, we don't want to |
11291 | * start the search. |
11292 | */ |
11293 | GList *list; |
11294 | gboolean found_focus = FALSE(0); |
11295 | |
11296 | if (!tree_view->priv->enable_search && !keybinding) |
11297 | return FALSE(0); |
11298 | |
11299 | if (tree_view->priv->search_custom_entry_set) |
11300 | return FALSE(0); |
11301 | |
11302 | if (tree_view->priv->search_window != NULL((void*)0) && |
11303 | ctk_widget_get_visible (tree_view->priv->search_window)) |
11304 | return TRUE(!(0)); |
11305 | |
11306 | for (list = tree_view->priv->columns; list; list = list->next) |
11307 | { |
11308 | CtkTreeViewColumn *column; |
11309 | CtkWidget *button; |
11310 | |
11311 | column = list->data; |
11312 | if (!ctk_tree_view_column_get_visible (column)) |
11313 | continue; |
11314 | |
11315 | button = ctk_tree_view_column_get_button (column); |
11316 | if (ctk_widget_has_focus (button)) |
11317 | { |
11318 | found_focus = TRUE(!(0)); |
11319 | break; |
11320 | } |
11321 | } |
11322 | |
11323 | if (ctk_widget_has_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11324 | found_focus = TRUE(!(0)); |
11325 | |
11326 | if (!found_focus) |
11327 | return FALSE(0); |
11328 | |
11329 | if (tree_view->priv->search_column < 0) |
11330 | return FALSE(0); |
11331 | |
11332 | ctk_tree_view_ensure_interactive_directory (tree_view); |
11333 | |
11334 | if (keybinding) |
11335 | ctk_entry_set_text (CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ())))))), ""); |
11336 | |
11337 | /* done, show it */ |
11338 | tree_view->priv->search_position_func (tree_view, tree_view->priv->search_window, tree_view->priv->search_position_user_data); |
11339 | |
11340 | /* Grab focus without selecting all the text. */ |
11341 | ctk_entry_grab_focus_without_selecting (CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ()))))))); |
11342 | |
11343 | ctk_widget_show (tree_view->priv->search_window); |
11344 | if (tree_view->priv->search_entry_changed_id == 0) |
11345 | { |
11346 | tree_view->priv->search_entry_changed_id = |
11347 | g_signal_connect (tree_view->priv->search_entry, "changed",g_signal_connect_data ((tree_view->priv->search_entry), ("changed"), (((GCallback) (ctk_tree_view_search_init))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11348 | G_CALLBACK (ctk_tree_view_search_init),g_signal_connect_data ((tree_view->priv->search_entry), ("changed"), (((GCallback) (ctk_tree_view_search_init))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11349 | tree_view)g_signal_connect_data ((tree_view->priv->search_entry), ("changed"), (((GCallback) (ctk_tree_view_search_init))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
11350 | } |
11351 | |
11352 | tree_view->priv->typeselect_flush_timeout = |
11353 | cdk_threads_add_timeout (CTK_TREE_VIEW_SEARCH_DIALOG_TIMEOUT5000, |
11354 | (GSourceFunc) ctk_tree_view_search_entry_flush_timeout, |
11355 | tree_view); |
11356 | g_source_set_name_by_id (tree_view->priv->typeselect_flush_timeout, "[ctk+] ctk_tree_view_search_entry_flush_timeout"); |
11357 | |
11358 | /* send focus-in event */ |
11359 | send_focus_change (tree_view->priv->search_entry, device, TRUE(!(0))); |
11360 | |
11361 | /* search first matching iter */ |
11362 | ctk_tree_view_search_init (tree_view->priv->search_entry, tree_view); |
11363 | |
11364 | return TRUE(!(0)); |
11365 | } |
11366 | |
11367 | static gboolean |
11368 | ctk_tree_view_start_interactive_search (CtkTreeView *tree_view) |
11369 | { |
11370 | return ctk_tree_view_real_start_interactive_search (tree_view, |
11371 | ctk_get_current_event_device (), |
11372 | TRUE(!(0))); |
11373 | } |
11374 | |
11375 | /* Callbacks */ |
11376 | static void |
11377 | ctk_tree_view_adjustment_changed (CtkAdjustment *adjustment G_GNUC_UNUSED__attribute__ ((__unused__)), |
11378 | CtkTreeView *tree_view) |
11379 | { |
11380 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11381 | { |
11382 | gint dy; |
11383 | |
11384 | cdk_window_move (tree_view->priv->bin_window, |
11385 | - ctk_adjustment_get_value (tree_view->priv->hadjustment), |
11386 | ctk_tree_view_get_effective_header_height (tree_view)); |
11387 | cdk_window_move (tree_view->priv->header_window, |
11388 | - ctk_adjustment_get_value (tree_view->priv->hadjustment), |
11389 | 0); |
11390 | dy = tree_view->priv->dy - (int) ctk_adjustment_get_value (tree_view->priv->vadjustment); |
11391 | cdk_window_scroll (tree_view->priv->bin_window, 0, dy); |
11392 | |
11393 | if (dy != 0) |
11394 | { |
11395 | /* update our dy and top_row */ |
11396 | tree_view->priv->dy = (int) ctk_adjustment_get_value (tree_view->priv->vadjustment); |
11397 | |
11398 | update_prelight (tree_view, |
11399 | tree_view->priv->event_last_x, |
11400 | tree_view->priv->event_last_y); |
11401 | |
11402 | if (!tree_view->priv->in_top_row_to_dy) |
11403 | ctk_tree_view_dy_to_top_row (tree_view); |
11404 | |
11405 | } |
11406 | } |
11407 | } |
11408 | |
11409 | |
11410 | |
11411 | /* Public methods |
11412 | */ |
11413 | |
11414 | /** |
11415 | * ctk_tree_view_new: |
11416 | * |
11417 | * Creates a new #CtkTreeView widget. |
11418 | * |
11419 | * Returns: A newly created #CtkTreeView widget. |
11420 | **/ |
11421 | CtkWidget * |
11422 | ctk_tree_view_new (void) |
11423 | { |
11424 | return g_object_new (CTK_TYPE_TREE_VIEW(ctk_tree_view_get_type ()), NULL((void*)0)); |
11425 | } |
11426 | |
11427 | /** |
11428 | * ctk_tree_view_new_with_model: |
11429 | * @model: the model. |
11430 | * |
11431 | * Creates a new #CtkTreeView widget with the model initialized to @model. |
11432 | * |
11433 | * Returns: A newly created #CtkTreeView widget. |
11434 | **/ |
11435 | CtkWidget * |
11436 | ctk_tree_view_new_with_model (CtkTreeModel *model) |
11437 | { |
11438 | return g_object_new (CTK_TYPE_TREE_VIEW(ctk_tree_view_get_type ()), "model", model, NULL((void*)0)); |
11439 | } |
11440 | |
11441 | /* Public Accessors |
11442 | */ |
11443 | |
11444 | /** |
11445 | * ctk_tree_view_get_model: |
11446 | * @tree_view: a #CtkTreeView |
11447 | * |
11448 | * Returns the model the #CtkTreeView is based on. Returns %NULL if the |
11449 | * model is unset. |
11450 | * |
11451 | * Returns: (transfer none) (nullable): A #CtkTreeModel, or %NULL if |
11452 | * none is currently being used. |
11453 | **/ |
11454 | CtkTreeModel * |
11455 | ctk_tree_view_get_model (CtkTreeView *tree_view) |
11456 | { |
11457 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
11458 | |
11459 | return tree_view->priv->model; |
11460 | } |
11461 | |
11462 | /** |
11463 | * ctk_tree_view_set_model: |
11464 | * @tree_view: A #CtkTreeView. |
11465 | * @model: (allow-none): The model. |
11466 | * |
11467 | * Sets the model for a #CtkTreeView. If the @tree_view already has a model |
11468 | * set, it will remove it before setting the new model. If @model is %NULL, |
11469 | * then it will unset the old model. |
11470 | **/ |
11471 | void |
11472 | ctk_tree_view_set_model (CtkTreeView *tree_view, |
11473 | CtkTreeModel *model) |
11474 | { |
11475 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11476 | g_return_if_fail (model == NULL || CTK_IS_TREE_MODEL (model))do { if ((model == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((model)); GType __t = ((ctk_tree_model_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "model == NULL || CTK_IS_TREE_MODEL (model)" ); return; } } while (0); |
11477 | |
11478 | if (model == tree_view->priv->model) |
11479 | return; |
11480 | |
11481 | if (tree_view->priv->scroll_to_path) |
11482 | { |
11483 | ctk_tree_row_reference_free (tree_view->priv->scroll_to_path); |
11484 | tree_view->priv->scroll_to_path = NULL((void*)0); |
11485 | } |
11486 | |
11487 | if (tree_view->priv->rubber_band_status) |
11488 | ctk_tree_view_stop_rubber_band (tree_view); |
11489 | |
11490 | if (tree_view->priv->model) |
11491 | { |
11492 | GList *tmplist = tree_view->priv->columns; |
11493 | |
11494 | ctk_tree_view_unref_and_check_selection_tree (tree_view, tree_view->priv->tree); |
11495 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
11496 | |
11497 | g_signal_handlers_disconnect_by_func (tree_view->priv->model,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_changed), (tree_view) ) |
11498 | ctk_tree_view_row_changed,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_changed), (tree_view) ) |
11499 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_changed), (tree_view) ); |
11500 | g_signal_handlers_disconnect_by_func (tree_view->priv->model,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_inserted), (tree_view )) |
11501 | ctk_tree_view_row_inserted,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_inserted), (tree_view )) |
11502 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_inserted), (tree_view )); |
11503 | g_signal_handlers_disconnect_by_func (tree_view->priv->model,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_has_child_toggled), ( tree_view)) |
11504 | ctk_tree_view_row_has_child_toggled,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_has_child_toggled), ( tree_view)) |
11505 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_has_child_toggled), ( tree_view)); |
11506 | g_signal_handlers_disconnect_by_func (tree_view->priv->model,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_deleted), (tree_view) ) |
11507 | ctk_tree_view_row_deleted,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_deleted), (tree_view) ) |
11508 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_row_deleted), (tree_view) ); |
11509 | g_signal_handlers_disconnect_by_func (tree_view->priv->model,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_rows_reordered), (tree_view )) |
11510 | ctk_tree_view_rows_reordered,g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_rows_reordered), (tree_view )) |
11511 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> model), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_rows_reordered), (tree_view )); |
11512 | |
11513 | for (; tmplist; tmplist = tmplist->next) |
11514 | _ctk_tree_view_column_unset_model (tmplist->data, |
11515 | tree_view->priv->model); |
11516 | |
11517 | if (tree_view->priv->tree) |
11518 | ctk_tree_view_free_rbtree (tree_view); |
11519 | |
11520 | ctk_tree_row_reference_free (tree_view->priv->drag_dest_row); |
11521 | tree_view->priv->drag_dest_row = NULL((void*)0); |
11522 | ctk_tree_row_reference_free (tree_view->priv->anchor); |
11523 | tree_view->priv->anchor = NULL((void*)0); |
11524 | ctk_tree_row_reference_free (tree_view->priv->top_row); |
11525 | tree_view->priv->top_row = NULL((void*)0); |
11526 | ctk_tree_row_reference_free (tree_view->priv->scroll_to_path); |
11527 | tree_view->priv->scroll_to_path = NULL((void*)0); |
11528 | |
11529 | tree_view->priv->scroll_to_column = NULL((void*)0); |
11530 | |
11531 | g_object_unref (tree_view->priv->model); |
11532 | |
11533 | tree_view->priv->search_column = -1; |
11534 | tree_view->priv->fixed_height_check = 0; |
11535 | tree_view->priv->fixed_height = -1; |
11536 | tree_view->priv->dy = tree_view->priv->top_row_dy = 0; |
11537 | } |
11538 | |
11539 | tree_view->priv->model = model; |
11540 | |
11541 | if (tree_view->priv->model) |
11542 | { |
11543 | gint i; |
11544 | CtkTreePath *path; |
11545 | CtkTreeIter iter; |
11546 | CtkTreeModelFlags flags; |
11547 | |
11548 | if (tree_view->priv->search_column == -1) |
11549 | { |
11550 | for (i = 0; i < ctk_tree_model_get_n_columns (model); i++) |
11551 | { |
11552 | GType type = ctk_tree_model_get_column_type (model, i); |
11553 | |
11554 | if (g_value_type_transformable (type, G_TYPE_STRING((GType) ((16) << (2))))) |
11555 | { |
11556 | tree_view->priv->search_column = i; |
11557 | break; |
11558 | } |
11559 | } |
11560 | } |
11561 | |
11562 | g_object_ref (tree_view->priv->model)((__typeof__ (tree_view->priv->model)) (g_object_ref) ( tree_view->priv->model)); |
11563 | g_signal_connect (tree_view->priv->model,g_signal_connect_data ((tree_view->priv->model), ("row-changed" ), (((GCallback) (ctk_tree_view_row_changed))), (tree_view), ( (void*)0), (GConnectFlags) 0) |
11564 | "row-changed",g_signal_connect_data ((tree_view->priv->model), ("row-changed" ), (((GCallback) (ctk_tree_view_row_changed))), (tree_view), ( (void*)0), (GConnectFlags) 0) |
11565 | G_CALLBACK (ctk_tree_view_row_changed),g_signal_connect_data ((tree_view->priv->model), ("row-changed" ), (((GCallback) (ctk_tree_view_row_changed))), (tree_view), ( (void*)0), (GConnectFlags) 0) |
11566 | tree_view)g_signal_connect_data ((tree_view->priv->model), ("row-changed" ), (((GCallback) (ctk_tree_view_row_changed))), (tree_view), ( (void*)0), (GConnectFlags) 0); |
11567 | g_signal_connect (tree_view->priv->model,g_signal_connect_data ((tree_view->priv->model), ("row-inserted" ), (((GCallback) (ctk_tree_view_row_inserted))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11568 | "row-inserted",g_signal_connect_data ((tree_view->priv->model), ("row-inserted" ), (((GCallback) (ctk_tree_view_row_inserted))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11569 | G_CALLBACK (ctk_tree_view_row_inserted),g_signal_connect_data ((tree_view->priv->model), ("row-inserted" ), (((GCallback) (ctk_tree_view_row_inserted))), (tree_view), ((void*)0), (GConnectFlags) 0) |
11570 | tree_view)g_signal_connect_data ((tree_view->priv->model), ("row-inserted" ), (((GCallback) (ctk_tree_view_row_inserted))), (tree_view), ((void*)0), (GConnectFlags) 0); |
11571 | g_signal_connect (tree_view->priv->model,g_signal_connect_data ((tree_view->priv->model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_view_row_has_child_toggled))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11572 | "row-has-child-toggled",g_signal_connect_data ((tree_view->priv->model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_view_row_has_child_toggled))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11573 | G_CALLBACK (ctk_tree_view_row_has_child_toggled),g_signal_connect_data ((tree_view->priv->model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_view_row_has_child_toggled))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11574 | tree_view)g_signal_connect_data ((tree_view->priv->model), ("row-has-child-toggled" ), (((GCallback) (ctk_tree_view_row_has_child_toggled))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
11575 | g_signal_connect (tree_view->priv->model,g_signal_connect_data ((tree_view->priv->model), ("row-deleted" ), (((GCallback) (ctk_tree_view_row_deleted))), (tree_view), ( (void*)0), (GConnectFlags) 0) |
11576 | "row-deleted",g_signal_connect_data ((tree_view->priv->model), ("row-deleted" ), (((GCallback) (ctk_tree_view_row_deleted))), (tree_view), ( (void*)0), (GConnectFlags) 0) |
11577 | G_CALLBACK (ctk_tree_view_row_deleted),g_signal_connect_data ((tree_view->priv->model), ("row-deleted" ), (((GCallback) (ctk_tree_view_row_deleted))), (tree_view), ( (void*)0), (GConnectFlags) 0) |
11578 | tree_view)g_signal_connect_data ((tree_view->priv->model), ("row-deleted" ), (((GCallback) (ctk_tree_view_row_deleted))), (tree_view), ( (void*)0), (GConnectFlags) 0); |
11579 | g_signal_connect (tree_view->priv->model,g_signal_connect_data ((tree_view->priv->model), ("rows-reordered" ), (((GCallback) (ctk_tree_view_rows_reordered))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11580 | "rows-reordered",g_signal_connect_data ((tree_view->priv->model), ("rows-reordered" ), (((GCallback) (ctk_tree_view_rows_reordered))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11581 | G_CALLBACK (ctk_tree_view_rows_reordered),g_signal_connect_data ((tree_view->priv->model), ("rows-reordered" ), (((GCallback) (ctk_tree_view_rows_reordered))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
11582 | tree_view)g_signal_connect_data ((tree_view->priv->model), ("rows-reordered" ), (((GCallback) (ctk_tree_view_rows_reordered))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
11583 | |
11584 | flags = ctk_tree_model_get_flags (tree_view->priv->model); |
11585 | if ((flags & CTK_TREE_MODEL_LIST_ONLY) == CTK_TREE_MODEL_LIST_ONLY) |
11586 | tree_view->priv->is_list = TRUE(!(0)); |
11587 | else |
11588 | tree_view->priv->is_list = FALSE(0); |
11589 | |
11590 | path = ctk_tree_path_new_first (); |
11591 | if (ctk_tree_model_get_iter (tree_view->priv->model, &iter, path)) |
11592 | { |
11593 | tree_view->priv->tree = _ctk_rbtree_new (); |
11594 | ctk_tree_view_build_tree (tree_view, tree_view->priv->tree, &iter, 1, FALSE(0)); |
11595 | _ctk_tree_view_accessible_add (tree_view, tree_view->priv->tree, NULL((void*)0)); |
11596 | } |
11597 | ctk_tree_path_free (path); |
11598 | |
11599 | /* FIXME: do I need to do this? ctk_tree_view_create_buttons (tree_view); */ |
11600 | install_presize_handler (tree_view); |
11601 | } |
11602 | |
11603 | ctk_tree_view_real_set_cursor (tree_view, NULL((void*)0), CURSOR_INVALID); |
11604 | |
11605 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_MODEL]); |
11606 | |
11607 | if (tree_view->priv->selection) |
11608 | _ctk_tree_selection_emit_changed (tree_view->priv->selection); |
11609 | |
11610 | if (tree_view->priv->pixel_cache != NULL((void*)0)) |
11611 | _ctk_pixel_cache_set_always_cache (tree_view->priv->pixel_cache, (model != NULL((void*)0))); |
11612 | |
11613 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11614 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11615 | } |
11616 | |
11617 | /** |
11618 | * ctk_tree_view_get_selection: |
11619 | * @tree_view: A #CtkTreeView. |
11620 | * |
11621 | * Gets the #CtkTreeSelection associated with @tree_view. |
11622 | * |
11623 | * Returns: (transfer none): A #CtkTreeSelection object. |
11624 | **/ |
11625 | CtkTreeSelection * |
11626 | ctk_tree_view_get_selection (CtkTreeView *tree_view) |
11627 | { |
11628 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
11629 | |
11630 | return tree_view->priv->selection; |
11631 | } |
11632 | |
11633 | /** |
11634 | * ctk_tree_view_get_hadjustment: |
11635 | * @tree_view: A #CtkTreeView |
11636 | * |
11637 | * Gets the #CtkAdjustment currently being used for the horizontal aspect. |
11638 | * |
11639 | * Returns: (transfer none): A #CtkAdjustment object, or %NULL |
11640 | * if none is currently being used. |
11641 | * |
11642 | * Deprecated: 3.0: Use ctk_scrollable_get_hadjustment() |
11643 | **/ |
11644 | CtkAdjustment * |
11645 | ctk_tree_view_get_hadjustment (CtkTreeView *tree_view) |
11646 | { |
11647 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
11648 | |
11649 | return ctk_tree_view_do_get_hadjustment (tree_view); |
11650 | } |
11651 | |
11652 | static CtkAdjustment * |
11653 | ctk_tree_view_do_get_hadjustment (CtkTreeView *tree_view) |
11654 | { |
11655 | return tree_view->priv->hadjustment; |
11656 | } |
11657 | |
11658 | /** |
11659 | * ctk_tree_view_set_hadjustment: |
11660 | * @tree_view: A #CtkTreeView |
11661 | * @adjustment: (allow-none): The #CtkAdjustment to set, or %NULL |
11662 | * |
11663 | * Sets the #CtkAdjustment for the current horizontal aspect. |
11664 | * |
11665 | * Deprecated: 3.0: Use ctk_scrollable_set_hadjustment() |
11666 | **/ |
11667 | void |
11668 | ctk_tree_view_set_hadjustment (CtkTreeView *tree_view, |
11669 | CtkAdjustment *adjustment) |
11670 | { |
11671 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11672 | g_return_if_fail (adjustment == NULL || CTK_IS_ADJUSTMENT (adjustment))do { if ((adjustment == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((adjustment)); GType __t = ((ctk_adjustment_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "adjustment == NULL || CTK_IS_ADJUSTMENT (adjustment)" ); return; } } while (0); |
11673 | |
11674 | ctk_tree_view_do_set_hadjustment (tree_view, adjustment); |
11675 | } |
11676 | |
11677 | static void |
11678 | ctk_tree_view_do_set_hadjustment (CtkTreeView *tree_view, |
11679 | CtkAdjustment *adjustment) |
11680 | { |
11681 | CtkTreeViewPrivate *priv = tree_view->priv; |
11682 | |
11683 | if (adjustment && priv->hadjustment == adjustment) |
11684 | return; |
11685 | |
11686 | if (priv->hadjustment != NULL((void*)0)) |
11687 | { |
11688 | g_signal_handlers_disconnect_by_func (priv->hadjustment,g_signal_handlers_disconnect_matched ((priv->hadjustment), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_adjustment_changed), (tree_view )) |
11689 | ctk_tree_view_adjustment_changed,g_signal_handlers_disconnect_matched ((priv->hadjustment), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_adjustment_changed), (tree_view )) |
11690 | tree_view)g_signal_handlers_disconnect_matched ((priv->hadjustment), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_adjustment_changed), (tree_view )); |
11691 | g_object_unref (priv->hadjustment); |
11692 | } |
11693 | |
11694 | if (adjustment == NULL((void*)0)) |
11695 | adjustment = ctk_adjustment_new (0.0, 0.0, 0.0, |
11696 | 0.0, 0.0, 0.0); |
11697 | |
11698 | g_signal_connect (adjustment, "value-changed",g_signal_connect_data ((adjustment), ("value-changed"), (((GCallback ) (ctk_tree_view_adjustment_changed))), (tree_view), ((void*) 0), (GConnectFlags) 0) |
11699 | G_CALLBACK (ctk_tree_view_adjustment_changed), tree_view)g_signal_connect_data ((adjustment), ("value-changed"), (((GCallback ) (ctk_tree_view_adjustment_changed))), (tree_view), ((void*) 0), (GConnectFlags) 0); |
11700 | priv->hadjustment = g_object_ref_sink (adjustment)((__typeof__ (adjustment)) (g_object_ref_sink) (adjustment)); |
11701 | /* FIXME: Adjustment should probably be populated here with fresh values, but |
11702 | * internal details are too complicated for me to decipher right now. |
11703 | */ |
11704 | ctk_tree_view_adjustment_changed (NULL((void*)0), tree_view); |
11705 | |
11706 | g_object_notify (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), "hadjustment"); |
11707 | } |
11708 | |
11709 | /** |
11710 | * ctk_tree_view_get_vadjustment: |
11711 | * @tree_view: A #CtkTreeView |
11712 | * |
11713 | * Gets the #CtkAdjustment currently being used for the vertical aspect. |
11714 | * |
11715 | * Returns: (transfer none): A #CtkAdjustment object, or %NULL |
11716 | * if none is currently being used. |
11717 | * |
11718 | * Deprecated: 3.0: Use ctk_scrollable_get_vadjustment() |
11719 | **/ |
11720 | CtkAdjustment * |
11721 | ctk_tree_view_get_vadjustment (CtkTreeView *tree_view) |
11722 | { |
11723 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
11724 | |
11725 | return ctk_tree_view_do_get_vadjustment (tree_view); |
11726 | } |
11727 | |
11728 | static CtkAdjustment * |
11729 | ctk_tree_view_do_get_vadjustment (CtkTreeView *tree_view) |
11730 | { |
11731 | return tree_view->priv->vadjustment; |
11732 | } |
11733 | |
11734 | /** |
11735 | * ctk_tree_view_set_vadjustment: |
11736 | * @tree_view: A #CtkTreeView |
11737 | * @adjustment: (allow-none): The #CtkAdjustment to set, or %NULL |
11738 | * |
11739 | * Sets the #CtkAdjustment for the current vertical aspect. |
11740 | * |
11741 | * Deprecated: 3.0: Use ctk_scrollable_set_vadjustment() |
11742 | **/ |
11743 | void |
11744 | ctk_tree_view_set_vadjustment (CtkTreeView *tree_view, |
11745 | CtkAdjustment *adjustment) |
11746 | { |
11747 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11748 | g_return_if_fail (adjustment == NULL || CTK_IS_ADJUSTMENT (adjustment))do { if ((adjustment == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((adjustment)); GType __t = ((ctk_adjustment_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "adjustment == NULL || CTK_IS_ADJUSTMENT (adjustment)" ); return; } } while (0); |
11749 | |
11750 | ctk_tree_view_do_set_vadjustment (tree_view, adjustment); |
11751 | } |
11752 | |
11753 | static void |
11754 | ctk_tree_view_do_set_vadjustment (CtkTreeView *tree_view, |
11755 | CtkAdjustment *adjustment) |
11756 | { |
11757 | CtkTreeViewPrivate *priv = tree_view->priv; |
11758 | |
11759 | if (adjustment && priv->vadjustment == adjustment) |
11760 | return; |
11761 | |
11762 | if (priv->vadjustment != NULL((void*)0)) |
11763 | { |
11764 | g_signal_handlers_disconnect_by_func (priv->vadjustment,g_signal_handlers_disconnect_matched ((priv->vadjustment), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_adjustment_changed), (tree_view )) |
11765 | ctk_tree_view_adjustment_changed,g_signal_handlers_disconnect_matched ((priv->vadjustment), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_adjustment_changed), (tree_view )) |
11766 | tree_view)g_signal_handlers_disconnect_matched ((priv->vadjustment), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (ctk_tree_view_adjustment_changed), (tree_view )); |
11767 | g_object_unref (priv->vadjustment); |
11768 | } |
11769 | |
11770 | if (adjustment == NULL((void*)0)) |
11771 | adjustment = ctk_adjustment_new (0.0, 0.0, 0.0, |
11772 | 0.0, 0.0, 0.0); |
11773 | |
11774 | g_signal_connect (adjustment, "value-changed",g_signal_connect_data ((adjustment), ("value-changed"), (((GCallback ) (ctk_tree_view_adjustment_changed))), (tree_view), ((void*) 0), (GConnectFlags) 0) |
11775 | G_CALLBACK (ctk_tree_view_adjustment_changed), tree_view)g_signal_connect_data ((adjustment), ("value-changed"), (((GCallback ) (ctk_tree_view_adjustment_changed))), (tree_view), ((void*) 0), (GConnectFlags) 0); |
11776 | priv->vadjustment = g_object_ref_sink (adjustment)((__typeof__ (adjustment)) (g_object_ref_sink) (adjustment)); |
11777 | /* FIXME: Adjustment should probably be populated here with fresh values, but |
11778 | * internal details are too complicated for me to decipher right now. |
11779 | */ |
11780 | ctk_tree_view_adjustment_changed (NULL((void*)0), tree_view); |
11781 | g_object_notify (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), "vadjustment"); |
11782 | } |
11783 | |
11784 | /* Column and header operations */ |
11785 | |
11786 | /** |
11787 | * ctk_tree_view_get_headers_visible: |
11788 | * @tree_view: A #CtkTreeView. |
11789 | * |
11790 | * Returns %TRUE if the headers on the @tree_view are visible. |
11791 | * |
11792 | * Returns: Whether the headers are visible or not. |
11793 | **/ |
11794 | gboolean |
11795 | ctk_tree_view_get_headers_visible (CtkTreeView *tree_view) |
11796 | { |
11797 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
11798 | |
11799 | return tree_view->priv->headers_visible; |
11800 | } |
11801 | |
11802 | /** |
11803 | * ctk_tree_view_set_headers_visible: |
11804 | * @tree_view: A #CtkTreeView. |
11805 | * @headers_visible: %TRUE if the headers are visible |
11806 | * |
11807 | * Sets the visibility state of the headers. |
11808 | **/ |
11809 | void |
11810 | ctk_tree_view_set_headers_visible (CtkTreeView *tree_view, |
11811 | gboolean headers_visible) |
11812 | { |
11813 | gint x, y; |
11814 | GList *list; |
11815 | CtkTreeViewColumn *column; |
11816 | CtkAllocation allocation; |
11817 | CtkWidget *button; |
11818 | |
11819 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11820 | |
11821 | headers_visible = !! headers_visible; |
11822 | |
11823 | if (tree_view->priv->headers_visible == headers_visible) |
11824 | return; |
11825 | |
11826 | tree_view->priv->headers_visible = headers_visible == TRUE(!(0)); |
11827 | |
11828 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11829 | { |
11830 | cdk_window_get_position (tree_view->priv->bin_window, &x, &y); |
11831 | if (headers_visible) |
11832 | { |
11833 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
11834 | cdk_window_move_resize (tree_view->priv->bin_window, |
11835 | x, y + ctk_tree_view_get_effective_header_height (tree_view), |
11836 | tree_view->priv->width, allocation.height - + ctk_tree_view_get_effective_header_height (tree_view)); |
11837 | |
11838 | if (ctk_widget_get_mapped (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
11839 | ctk_tree_view_map_buttons (tree_view); |
11840 | } |
11841 | else |
11842 | { |
11843 | cdk_window_move_resize (tree_view->priv->bin_window, x, y, tree_view->priv->width, ctk_tree_view_get_height (tree_view)); |
11844 | |
11845 | for (list = tree_view->priv->columns; list; list = list->next) |
11846 | { |
11847 | column = list->data; |
11848 | button = ctk_tree_view_column_get_button (column); |
11849 | |
11850 | ctk_widget_hide (button); |
11851 | ctk_widget_unmap (button); |
11852 | } |
11853 | cdk_window_hide (tree_view->priv->header_window); |
11854 | } |
11855 | } |
11856 | |
11857 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
11858 | ctk_adjustment_configure (tree_view->priv->vadjustment, |
11859 | ctk_adjustment_get_value (tree_view->priv->vadjustment), |
11860 | 0, |
11861 | ctk_tree_view_get_height (tree_view), |
11862 | ctk_adjustment_get_step_increment (tree_view->priv->vadjustment), |
11863 | (allocation.height - ctk_tree_view_get_effective_header_height (tree_view)) / 2, |
11864 | allocation.height - ctk_tree_view_get_effective_header_height (tree_view)); |
11865 | |
11866 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11867 | |
11868 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_HEADERS_VISIBLE]); |
11869 | } |
11870 | |
11871 | /** |
11872 | * ctk_tree_view_columns_autosize: |
11873 | * @tree_view: A #CtkTreeView. |
11874 | * |
11875 | * Resizes all columns to their optimal width. Only works after the |
11876 | * treeview has been realized. |
11877 | **/ |
11878 | void |
11879 | ctk_tree_view_columns_autosize (CtkTreeView *tree_view) |
11880 | { |
11881 | gboolean dirty = FALSE(0); |
11882 | GList *list; |
11883 | CtkTreeViewColumn *column; |
11884 | |
11885 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11886 | |
11887 | for (list = tree_view->priv->columns; list; list = list->next) |
11888 | { |
11889 | column = list->data; |
11890 | if (ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_AUTOSIZE) |
11891 | continue; |
11892 | _ctk_tree_view_column_cell_set_dirty (column, TRUE(!(0))); |
11893 | dirty = TRUE(!(0)); |
11894 | } |
11895 | |
11896 | if (dirty) |
11897 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11898 | } |
11899 | |
11900 | /** |
11901 | * ctk_tree_view_set_headers_clickable: |
11902 | * @tree_view: A #CtkTreeView. |
11903 | * @setting: %TRUE if the columns are clickable. |
11904 | * |
11905 | * Allow the column title buttons to be clicked. |
11906 | **/ |
11907 | void |
11908 | ctk_tree_view_set_headers_clickable (CtkTreeView *tree_view, |
11909 | gboolean setting) |
11910 | { |
11911 | GList *list; |
11912 | gboolean changed = FALSE(0); |
11913 | |
11914 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11915 | |
11916 | for (list = tree_view->priv->columns; list; list = list->next) |
11917 | { |
11918 | if (ctk_tree_view_column_get_clickable (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ()))))))) != setting) |
11919 | { |
11920 | ctk_tree_view_column_set_clickable (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))), setting); |
11921 | changed = TRUE(!(0)); |
11922 | } |
11923 | } |
11924 | |
11925 | if (changed) |
11926 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_HEADERS_CLICKABLE]); |
11927 | } |
11928 | |
11929 | |
11930 | /** |
11931 | * ctk_tree_view_get_headers_clickable: |
11932 | * @tree_view: A #CtkTreeView. |
11933 | * |
11934 | * Returns whether all header columns are clickable. |
11935 | * |
11936 | * Returns: %TRUE if all header columns are clickable, otherwise %FALSE |
11937 | * |
11938 | * Since: 2.10 |
11939 | **/ |
11940 | gboolean |
11941 | ctk_tree_view_get_headers_clickable (CtkTreeView *tree_view) |
11942 | { |
11943 | GList *list; |
11944 | |
11945 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
11946 | |
11947 | for (list = tree_view->priv->columns; list; list = list->next) |
11948 | if (!ctk_tree_view_column_get_clickable (CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))))) |
11949 | return FALSE(0); |
11950 | |
11951 | return TRUE(!(0)); |
11952 | } |
11953 | |
11954 | /** |
11955 | * ctk_tree_view_set_rules_hint: |
11956 | * @tree_view: a #CtkTreeView |
11957 | * @setting: %TRUE if the tree requires reading across rows |
11958 | * |
11959 | * Sets a hint for the theme to draw even/odd rows in the @tree_view |
11960 | * with different colors, also known as "zebra striping". |
11961 | * |
11962 | * This function tells the CTK+ theme that the user interface for your |
11963 | * application requires users to read across tree rows and associate |
11964 | * cells with one another. |
11965 | * |
11966 | * Do not use it just because you prefer the appearance of the ruled |
11967 | * tree; that’s a question for the theme. Some themes will draw tree |
11968 | * rows in alternating colors even when rules are turned off, and |
11969 | * users who prefer that appearance all the time can choose those |
11970 | * themes. You should call this function only as a semantic hint to |
11971 | * the theme engine that your tree makes alternating colors useful |
11972 | * from a functional standpoint (since it has lots of columns, |
11973 | * generally). |
11974 | * |
11975 | * Deprecated: 3.14 |
11976 | */ |
11977 | void |
11978 | ctk_tree_view_set_rules_hint (CtkTreeView *tree_view, |
11979 | gboolean setting) |
11980 | { |
11981 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
11982 | |
11983 | setting = setting != FALSE(0); |
11984 | |
11985 | if (tree_view->priv->has_rules != setting) |
11986 | { |
11987 | tree_view->priv->has_rules = setting; |
11988 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
11989 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_RULES_HINT]); |
11990 | } |
11991 | } |
11992 | |
11993 | /** |
11994 | * ctk_tree_view_get_rules_hint: |
11995 | * @tree_view: a #CtkTreeView |
11996 | * |
11997 | * Gets the setting set by ctk_tree_view_set_rules_hint(). |
11998 | * |
11999 | * Returns: %TRUE if the hint is set |
12000 | * |
12001 | * Deprecated: 3.14 |
12002 | */ |
12003 | gboolean |
12004 | ctk_tree_view_get_rules_hint (CtkTreeView *tree_view) |
12005 | { |
12006 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
12007 | |
12008 | return tree_view->priv->has_rules; |
12009 | } |
12010 | |
12011 | |
12012 | /** |
12013 | * ctk_tree_view_set_activate_on_single_click: |
12014 | * @tree_view: a #CtkTreeView |
12015 | * @single: %TRUE to emit row-activated on a single click |
12016 | * |
12017 | * Cause the #CtkTreeView::row-activated signal to be emitted |
12018 | * on a single click instead of a double click. |
12019 | * |
12020 | * Since: 3.8 |
12021 | **/ |
12022 | void |
12023 | ctk_tree_view_set_activate_on_single_click (CtkTreeView *tree_view, |
12024 | gboolean single) |
12025 | { |
12026 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12027 | |
12028 | single = single != FALSE(0); |
12029 | |
12030 | if (tree_view->priv->activate_on_single_click == single) |
12031 | return; |
12032 | |
12033 | tree_view->priv->activate_on_single_click = single; |
12034 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_ACTIVATE_ON_SINGLE_CLICK]); |
12035 | } |
12036 | |
12037 | /** |
12038 | * ctk_tree_view_get_activate_on_single_click: |
12039 | * @tree_view: a #CtkTreeView |
12040 | * |
12041 | * Gets the setting set by ctk_tree_view_set_activate_on_single_click(). |
12042 | * |
12043 | * Returns: %TRUE if row-activated will be emitted on a single click |
12044 | * |
12045 | * Since: 3.8 |
12046 | **/ |
12047 | gboolean |
12048 | ctk_tree_view_get_activate_on_single_click (CtkTreeView *tree_view) |
12049 | { |
12050 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
12051 | |
12052 | return tree_view->priv->activate_on_single_click; |
12053 | } |
12054 | |
12055 | /* Public Column functions |
12056 | */ |
12057 | |
12058 | /** |
12059 | * ctk_tree_view_append_column: |
12060 | * @tree_view: A #CtkTreeView. |
12061 | * @column: The #CtkTreeViewColumn to add. |
12062 | * |
12063 | * Appends @column to the list of columns. If @tree_view has “fixed_height” |
12064 | * mode enabled, then @column must have its “sizing” property set to be |
12065 | * CTK_TREE_VIEW_COLUMN_FIXED. |
12066 | * |
12067 | * Returns: The number of columns in @tree_view after appending. |
12068 | **/ |
12069 | gint |
12070 | ctk_tree_view_append_column (CtkTreeView *tree_view, |
12071 | CtkTreeViewColumn *column) |
12072 | { |
12073 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (-1); } } while ( 0); |
12074 | g_return_val_if_fail (CTK_IS_TREE_VIEW_COLUMN (column), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((column)); GType __t = ((ctk_tree_view_column_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_TREE_VIEW_COLUMN (column)"); return (-1); } } while (0); |
12075 | g_return_val_if_fail (ctk_tree_view_column_get_tree_view (column) == NULL, -1)do { if ((ctk_tree_view_column_get_tree_view (column) == ((void *)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "ctk_tree_view_column_get_tree_view (column) == NULL" ); return (-1); } } while (0); |
12076 | |
12077 | return ctk_tree_view_insert_column (tree_view, column, -1); |
12078 | } |
12079 | |
12080 | /** |
12081 | * ctk_tree_view_remove_column: |
12082 | * @tree_view: A #CtkTreeView. |
12083 | * @column: The #CtkTreeViewColumn to remove. |
12084 | * |
12085 | * Removes @column from @tree_view. |
12086 | * |
12087 | * Returns: The number of columns in @tree_view after removing. |
12088 | **/ |
12089 | gint |
12090 | ctk_tree_view_remove_column (CtkTreeView *tree_view, |
12091 | CtkTreeViewColumn *column) |
12092 | { |
12093 | guint position; |
12094 | |
12095 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (-1); } } while ( 0); |
12096 | g_return_val_if_fail (CTK_IS_TREE_VIEW_COLUMN (column), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((column)); GType __t = ((ctk_tree_view_column_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_TREE_VIEW_COLUMN (column)"); return (-1); } } while (0); |
12097 | g_return_val_if_fail (ctk_tree_view_column_get_tree_view (column) == CTK_WIDGET (tree_view), -1)do { if ((ctk_tree_view_column_get_tree_view (column) == (((( CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "ctk_tree_view_column_get_tree_view (column) == CTK_WIDGET (tree_view)" ); return (-1); } } while (0); |
12098 | |
12099 | if (tree_view->priv->focus_column == column) |
12100 | _ctk_tree_view_set_focus_column (tree_view, NULL((void*)0)); |
12101 | |
12102 | if (tree_view->priv->edited_column == column) |
12103 | { |
12104 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
12105 | |
12106 | /* no need to, but just to be sure ... */ |
12107 | tree_view->priv->edited_column = NULL((void*)0); |
12108 | } |
12109 | |
12110 | if (tree_view->priv->expander_column == column) |
12111 | tree_view->priv->expander_column = NULL((void*)0); |
12112 | |
12113 | g_signal_handlers_disconnect_by_func (column,g_signal_handlers_disconnect_matched ((column), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (((GCallback) (column_sizing_notify))), (tree_view)) |
12114 | G_CALLBACK (column_sizing_notify),g_signal_handlers_disconnect_matched ((column), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (((GCallback) (column_sizing_notify))), (tree_view)) |
12115 | tree_view)g_signal_handlers_disconnect_matched ((column), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (((GCallback) (column_sizing_notify))), (tree_view)); |
12116 | |
12117 | position = g_list_index (tree_view->priv->columns, column); |
12118 | |
12119 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
12120 | _ctk_tree_view_column_unrealize_button (column); |
12121 | |
12122 | _ctk_tree_view_column_unset_tree_view (column); |
12123 | |
12124 | tree_view->priv->columns = g_list_remove (tree_view->priv->columns, column); |
12125 | tree_view->priv->n_columns--; |
12126 | |
12127 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
12128 | { |
12129 | GList *list; |
12130 | |
12131 | for (list = tree_view->priv->columns; list; list = list->next) |
12132 | { |
12133 | CtkTreeViewColumn *tmp_column; |
12134 | |
12135 | tmp_column = CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))); |
12136 | if (ctk_tree_view_column_get_visible (tmp_column)) |
12137 | _ctk_tree_view_column_cell_set_dirty (tmp_column, TRUE(!(0))); |
12138 | } |
12139 | |
12140 | if (tree_view->priv->n_columns == 0 && |
12141 | ctk_tree_view_get_headers_visible (tree_view)) |
12142 | cdk_window_hide (tree_view->priv->header_window); |
12143 | |
12144 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
12145 | } |
12146 | |
12147 | _ctk_tree_view_accessible_remove_column (tree_view, column, position); |
12148 | |
12149 | g_object_unref (column); |
12150 | g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0); |
12151 | |
12152 | return tree_view->priv->n_columns; |
12153 | } |
12154 | |
12155 | /** |
12156 | * ctk_tree_view_insert_column: |
12157 | * @tree_view: A #CtkTreeView. |
12158 | * @column: The #CtkTreeViewColumn to be inserted. |
12159 | * @position: The position to insert @column in. |
12160 | * |
12161 | * This inserts the @column into the @tree_view at @position. If @position is |
12162 | * -1, then the column is inserted at the end. If @tree_view has |
12163 | * “fixed_height” mode enabled, then @column must have its “sizing” property |
12164 | * set to be CTK_TREE_VIEW_COLUMN_FIXED. |
12165 | * |
12166 | * Returns: The number of columns in @tree_view after insertion. |
12167 | **/ |
12168 | gint |
12169 | ctk_tree_view_insert_column (CtkTreeView *tree_view, |
12170 | CtkTreeViewColumn *column, |
12171 | gint position) |
12172 | { |
12173 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (-1); } } while ( 0); |
12174 | g_return_val_if_fail (CTK_IS_TREE_VIEW_COLUMN (column), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((column)); GType __t = ((ctk_tree_view_column_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_TREE_VIEW_COLUMN (column)"); return (-1); } } while (0); |
12175 | g_return_val_if_fail (ctk_tree_view_column_get_tree_view (column) == NULL, -1)do { if ((ctk_tree_view_column_get_tree_view (column) == ((void *)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "ctk_tree_view_column_get_tree_view (column) == NULL" ); return (-1); } } while (0); |
12176 | |
12177 | if (tree_view->priv->fixed_height_mode) |
12178 | g_return_val_if_fail (ctk_tree_view_column_get_sizing (column)do { if ((ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_FIXED )) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_FIXED" ); return (-1); } } while (0) |
12179 | == CTK_TREE_VIEW_COLUMN_FIXED, -1)do { if ((ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_FIXED )) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_FIXED" ); return (-1); } } while (0); |
12180 | |
12181 | if (position < 0 || position > tree_view->priv->n_columns) |
12182 | position = tree_view->priv->n_columns; |
12183 | |
12184 | g_object_ref_sink (column)((__typeof__ (column)) (g_object_ref_sink) (column)); |
12185 | |
12186 | if (tree_view->priv->n_columns == 0 && |
12187 | ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) && |
12188 | ctk_tree_view_get_headers_visible (tree_view)) |
12189 | { |
12190 | cdk_window_show (tree_view->priv->header_window); |
12191 | } |
12192 | |
12193 | g_signal_connect (column, "notify::sizing",g_signal_connect_data ((column), ("notify::sizing"), (((GCallback ) (column_sizing_notify))), (tree_view), ((void*)0), (GConnectFlags ) 0) |
12194 | G_CALLBACK (column_sizing_notify), tree_view)g_signal_connect_data ((column), ("notify::sizing"), (((GCallback ) (column_sizing_notify))), (tree_view), ((void*)0), (GConnectFlags ) 0); |
12195 | |
12196 | tree_view->priv->columns = g_list_insert (tree_view->priv->columns, |
12197 | column, position); |
12198 | tree_view->priv->n_columns++; |
12199 | |
12200 | _ctk_tree_view_column_set_tree_view (column, tree_view); |
12201 | |
12202 | ctk_tree_view_update_button_position (tree_view, column); |
12203 | |
12204 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
12205 | { |
12206 | GList *list; |
12207 | |
12208 | _ctk_tree_view_column_realize_button (column); |
12209 | |
12210 | for (list = tree_view->priv->columns; list; list = list->next) |
12211 | { |
12212 | column = CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))); |
12213 | if (ctk_tree_view_column_get_visible (column)) |
12214 | _ctk_tree_view_column_cell_set_dirty (column, TRUE(!(0))); |
12215 | } |
12216 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
12217 | } |
12218 | |
12219 | _ctk_tree_view_accessible_add_column (tree_view, column, position); |
12220 | |
12221 | g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0); |
12222 | |
12223 | return tree_view->priv->n_columns; |
12224 | } |
12225 | |
12226 | /** |
12227 | * ctk_tree_view_insert_column_with_attributes: |
12228 | * @tree_view: A #CtkTreeView |
12229 | * @position: The position to insert the new column in |
12230 | * @title: The title to set the header to |
12231 | * @cell: The #CtkCellRenderer |
12232 | * @...: A %NULL-terminated list of attributes |
12233 | * |
12234 | * Creates a new #CtkTreeViewColumn and inserts it into the @tree_view at |
12235 | * @position. If @position is -1, then the newly created column is inserted at |
12236 | * the end. The column is initialized with the attributes given. If @tree_view |
12237 | * has “fixed_height” mode enabled, then the new column will have its sizing |
12238 | * property set to be CTK_TREE_VIEW_COLUMN_FIXED. |
12239 | * |
12240 | * Returns: The number of columns in @tree_view after insertion. |
12241 | **/ |
12242 | gint |
12243 | ctk_tree_view_insert_column_with_attributes (CtkTreeView *tree_view, |
12244 | gint position, |
12245 | const gchar *title, |
12246 | CtkCellRenderer *cell, |
12247 | ...) |
12248 | { |
12249 | CtkTreeViewColumn *column; |
12250 | gchar *attribute; |
12251 | va_list args; |
12252 | gint column_id; |
12253 | |
12254 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (-1); } } while ( 0); |
12255 | |
12256 | column = ctk_tree_view_column_new (); |
12257 | if (tree_view->priv->fixed_height_mode) |
12258 | ctk_tree_view_column_set_sizing (column, CTK_TREE_VIEW_COLUMN_FIXED); |
12259 | |
12260 | ctk_tree_view_column_set_title (column, title); |
12261 | ctk_tree_view_column_pack_start (column, cell, TRUE(!(0))); |
12262 | |
12263 | va_start (args, cell)__builtin_va_start(args, cell); |
12264 | |
12265 | attribute = va_arg (args, gchar *)__builtin_va_arg(args, gchar *); |
12266 | |
12267 | while (attribute != NULL((void*)0)) |
12268 | { |
12269 | column_id = va_arg (args, gint)__builtin_va_arg(args, gint); |
12270 | ctk_tree_view_column_add_attribute (column, cell, attribute, column_id); |
12271 | attribute = va_arg (args, gchar *)__builtin_va_arg(args, gchar *); |
12272 | } |
12273 | |
12274 | va_end (args)__builtin_va_end(args); |
12275 | |
12276 | return ctk_tree_view_insert_column (tree_view, column, position); |
12277 | } |
12278 | |
12279 | /** |
12280 | * ctk_tree_view_insert_column_with_data_func: |
12281 | * @tree_view: a #CtkTreeView |
12282 | * @position: Position to insert, -1 for append |
12283 | * @title: column title |
12284 | * @cell: cell renderer for column |
12285 | * @func: function to set attributes of cell renderer |
12286 | * @data: data for @func |
12287 | * @dnotify: destroy notifier for @data |
12288 | * |
12289 | * Convenience function that inserts a new column into the #CtkTreeView |
12290 | * with the given cell renderer and a #CtkTreeCellDataFunc to set cell renderer |
12291 | * attributes (normally using data from the model). See also |
12292 | * ctk_tree_view_column_set_cell_data_func(), ctk_tree_view_column_pack_start(). |
12293 | * If @tree_view has “fixed_height” mode enabled, then the new column will have its |
12294 | * “sizing” property set to be CTK_TREE_VIEW_COLUMN_FIXED. |
12295 | * |
12296 | * Returns: number of columns in the tree view post-insert |
12297 | **/ |
12298 | gint |
12299 | ctk_tree_view_insert_column_with_data_func (CtkTreeView *tree_view, |
12300 | gint position, |
12301 | const gchar *title, |
12302 | CtkCellRenderer *cell, |
12303 | CtkTreeCellDataFunc func, |
12304 | gpointer data, |
12305 | GDestroyNotify dnotify) |
12306 | { |
12307 | CtkTreeViewColumn *column; |
12308 | |
12309 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (-1); } } while ( 0); |
12310 | |
12311 | column = ctk_tree_view_column_new (); |
12312 | if (tree_view->priv->fixed_height_mode) |
12313 | ctk_tree_view_column_set_sizing (column, CTK_TREE_VIEW_COLUMN_FIXED); |
12314 | |
12315 | ctk_tree_view_column_set_title (column, title); |
12316 | ctk_tree_view_column_pack_start (column, cell, TRUE(!(0))); |
12317 | ctk_tree_view_column_set_cell_data_func (column, cell, func, data, dnotify); |
12318 | |
12319 | return ctk_tree_view_insert_column (tree_view, column, position); |
12320 | } |
12321 | |
12322 | /** |
12323 | * ctk_tree_view_get_n_columns: |
12324 | * @tree_view: a #CtkTreeView |
12325 | * |
12326 | * Queries the number of columns in the given @tree_view. |
12327 | * |
12328 | * Returns: The number of columns in the @tree_view |
12329 | * |
12330 | * Since: 3.4 |
12331 | **/ |
12332 | guint |
12333 | ctk_tree_view_get_n_columns (CtkTreeView *tree_view) |
12334 | { |
12335 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (0); } } while (0 ); |
12336 | |
12337 | return tree_view->priv->n_columns; |
12338 | } |
12339 | |
12340 | /** |
12341 | * ctk_tree_view_get_column: |
12342 | * @tree_view: A #CtkTreeView. |
12343 | * @n: The position of the column, counting from 0. |
12344 | * |
12345 | * Gets the #CtkTreeViewColumn at the given position in the #tree_view. |
12346 | * |
12347 | * Returns: (nullable) (transfer none): The #CtkTreeViewColumn, or %NULL if the |
12348 | * position is outside the range of columns. |
12349 | **/ |
12350 | CtkTreeViewColumn * |
12351 | ctk_tree_view_get_column (CtkTreeView *tree_view, |
12352 | gint n) |
12353 | { |
12354 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
12355 | |
12356 | if (n < 0 || n >= tree_view->priv->n_columns) |
12357 | return NULL((void*)0); |
12358 | |
12359 | if (tree_view->priv->columns == NULL((void*)0)) |
12360 | return NULL((void*)0); |
12361 | |
12362 | return CTK_TREE_VIEW_COLUMN (g_list_nth (tree_view->priv->columns, n)->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((g_list_nth (tree_view->priv->columns , n)->data)), ((ctk_tree_view_column_get_type ())))))); |
12363 | } |
12364 | |
12365 | /** |
12366 | * ctk_tree_view_get_columns: |
12367 | * @tree_view: A #CtkTreeView |
12368 | * |
12369 | * Returns a #GList of all the #CtkTreeViewColumn s currently in @tree_view. |
12370 | * The returned list must be freed with g_list_free (). |
12371 | * |
12372 | * Returns: (element-type CtkTreeViewColumn) (transfer container): A list of #CtkTreeViewColumn s |
12373 | **/ |
12374 | GList * |
12375 | ctk_tree_view_get_columns (CtkTreeView *tree_view) |
12376 | { |
12377 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
12378 | |
12379 | return g_list_copy (tree_view->priv->columns); |
12380 | } |
12381 | |
12382 | /** |
12383 | * ctk_tree_view_move_column_after: |
12384 | * @tree_view: A #CtkTreeView |
12385 | * @column: The #CtkTreeViewColumn to be moved. |
12386 | * @base_column: (allow-none): The #CtkTreeViewColumn to be moved relative to, or %NULL. |
12387 | * |
12388 | * Moves @column to be after to @base_column. If @base_column is %NULL, then |
12389 | * @column is placed in the first position. |
12390 | **/ |
12391 | void |
12392 | ctk_tree_view_move_column_after (CtkTreeView *tree_view, |
12393 | CtkTreeViewColumn *column, |
12394 | CtkTreeViewColumn *base_column) |
12395 | { |
12396 | GList *column_list_el, *base_el = NULL((void*)0); |
12397 | |
12398 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12399 | |
12400 | column_list_el = g_list_find (tree_view->priv->columns, column); |
12401 | g_return_if_fail (column_list_el != NULL)do { if ((column_list_el != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column_list_el != NULL" ); return; } } while (0); |
12402 | |
12403 | if (base_column) |
12404 | { |
12405 | base_el = g_list_find (tree_view->priv->columns, base_column); |
12406 | g_return_if_fail (base_el != NULL)do { if ((base_el != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "base_el != NULL"); return ; } } while (0); |
12407 | } |
12408 | |
12409 | if (column_list_el->prev == base_el) |
12410 | return; |
12411 | |
12412 | tree_view->priv->columns = g_list_remove_link (tree_view->priv->columns, column_list_el); |
12413 | if (base_el == NULL((void*)0)) |
12414 | { |
12415 | column_list_el->prev = NULL((void*)0); |
12416 | column_list_el->next = tree_view->priv->columns; |
12417 | if (column_list_el->next) |
12418 | column_list_el->next->prev = column_list_el; |
12419 | tree_view->priv->columns = column_list_el; |
12420 | } |
12421 | else |
12422 | { |
12423 | column_list_el->prev = base_el; |
12424 | column_list_el->next = base_el->next; |
12425 | if (column_list_el->next) |
12426 | column_list_el->next->prev = column_list_el; |
12427 | base_el->next = column_list_el; |
12428 | } |
12429 | |
12430 | ctk_tree_view_update_button_position (tree_view, column); |
12431 | |
12432 | if (ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
12433 | { |
12434 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
12435 | ctk_tree_view_size_allocate_columns (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), NULL((void*)0)); |
12436 | } |
12437 | |
12438 | _ctk_tree_view_accessible_reorder_column (tree_view, column); |
12439 | |
12440 | g_signal_emit (tree_view, tree_view_signals[COLUMNS_CHANGED], 0); |
12441 | } |
12442 | |
12443 | /** |
12444 | * ctk_tree_view_set_expander_column: |
12445 | * @tree_view: A #CtkTreeView |
12446 | * @column: (nullable): %NULL, or the column to draw the expander arrow at. |
12447 | * |
12448 | * Sets the column to draw the expander arrow at. It must be in @tree_view. |
12449 | * If @column is %NULL, then the expander arrow is always at the first |
12450 | * visible column. |
12451 | * |
12452 | * If you do not want expander arrow to appear in your tree, set the |
12453 | * expander column to a hidden column. |
12454 | **/ |
12455 | void |
12456 | ctk_tree_view_set_expander_column (CtkTreeView *tree_view, |
12457 | CtkTreeViewColumn *column) |
12458 | { |
12459 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12460 | g_return_if_fail (column == NULL || CTK_IS_TREE_VIEW_COLUMN (column))do { if ((column == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((column)); GType __t = ((ctk_tree_view_column_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column == NULL || CTK_IS_TREE_VIEW_COLUMN (column)" ); return; } } while (0); |
12461 | g_return_if_fail (column == NULL || ctk_tree_view_column_get_tree_view (column) == CTK_WIDGET (tree_view))do { if ((column == ((void*)0) || ctk_tree_view_column_get_tree_view (column) == ((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view)), ((ctk_widget_get_type ()))) ))))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "column == NULL || ctk_tree_view_column_get_tree_view (column) == CTK_WIDGET (tree_view)" ); return; } } while (0); |
12462 | |
12463 | if (tree_view->priv->expander_column != column) |
12464 | { |
12465 | tree_view->priv->expander_column = column; |
12466 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_EXPANDER_COLUMN]); |
12467 | } |
12468 | } |
12469 | |
12470 | /** |
12471 | * ctk_tree_view_get_expander_column: |
12472 | * @tree_view: A #CtkTreeView |
12473 | * |
12474 | * Returns the column that is the current expander column. |
12475 | * This column has the expander arrow drawn next to it. |
12476 | * |
12477 | * Returns: (transfer none): The expander column. |
12478 | **/ |
12479 | CtkTreeViewColumn * |
12480 | ctk_tree_view_get_expander_column (CtkTreeView *tree_view) |
12481 | { |
12482 | GList *list; |
12483 | |
12484 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
12485 | |
12486 | for (list = tree_view->priv->columns; list; list = list->next) |
12487 | if (ctk_tree_view_is_expander_column (tree_view, CTK_TREE_VIEW_COLUMN (list->data)((((CtkTreeViewColumn*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((list->data)), ((ctk_tree_view_column_get_type ())))))))) |
12488 | return (CtkTreeViewColumn *) list->data; |
12489 | return NULL((void*)0); |
12490 | } |
12491 | |
12492 | |
12493 | /** |
12494 | * ctk_tree_view_set_column_drag_function: |
12495 | * @tree_view: A #CtkTreeView. |
12496 | * @func: (allow-none): A function to determine which columns are reorderable, or %NULL. |
12497 | * @user_data: (allow-none): User data to be passed to @func, or %NULL |
12498 | * @destroy: (allow-none): Destroy notifier for @user_data, or %NULL |
12499 | * |
12500 | * Sets a user function for determining where a column may be dropped when |
12501 | * dragged. This function is called on every column pair in turn at the |
12502 | * beginning of a column drag to determine where a drop can take place. The |
12503 | * arguments passed to @func are: the @tree_view, the #CtkTreeViewColumn being |
12504 | * dragged, the two #CtkTreeViewColumn s determining the drop spot, and |
12505 | * @user_data. If either of the #CtkTreeViewColumn arguments for the drop spot |
12506 | * are %NULL, then they indicate an edge. If @func is set to be %NULL, then |
12507 | * @tree_view reverts to the default behavior of allowing all columns to be |
12508 | * dropped everywhere. |
12509 | **/ |
12510 | void |
12511 | ctk_tree_view_set_column_drag_function (CtkTreeView *tree_view, |
12512 | CtkTreeViewColumnDropFunc func, |
12513 | gpointer user_data, |
12514 | GDestroyNotify destroy) |
12515 | { |
12516 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12517 | |
12518 | if (tree_view->priv->column_drop_func_data_destroy) |
12519 | tree_view->priv->column_drop_func_data_destroy (tree_view->priv->column_drop_func_data); |
12520 | |
12521 | tree_view->priv->column_drop_func = func; |
12522 | tree_view->priv->column_drop_func_data = user_data; |
12523 | tree_view->priv->column_drop_func_data_destroy = destroy; |
12524 | } |
12525 | |
12526 | /** |
12527 | * ctk_tree_view_scroll_to_point: |
12528 | * @tree_view: a #CtkTreeView |
12529 | * @tree_x: X coordinate of new top-left pixel of visible area, or -1 |
12530 | * @tree_y: Y coordinate of new top-left pixel of visible area, or -1 |
12531 | * |
12532 | * Scrolls the tree view such that the top-left corner of the visible |
12533 | * area is @tree_x, @tree_y, where @tree_x and @tree_y are specified |
12534 | * in tree coordinates. The @tree_view must be realized before |
12535 | * this function is called. If it isn't, you probably want to be |
12536 | * using ctk_tree_view_scroll_to_cell(). |
12537 | * |
12538 | * If either @tree_x or @tree_y are -1, then that direction isn’t scrolled. |
12539 | **/ |
12540 | void |
12541 | ctk_tree_view_scroll_to_point (CtkTreeView *tree_view, |
12542 | gint tree_x, |
12543 | gint tree_y) |
12544 | { |
12545 | CtkAdjustment *hadj; |
12546 | CtkAdjustment *vadj; |
12547 | |
12548 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12549 | g_return_if_fail (ctk_widget_get_realized (CTK_WIDGET (tree_view)))do { if ((ctk_widget_get_realized (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view)), ((ctk_widget_get_type ()))) )))))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "ctk_widget_get_realized (CTK_WIDGET (tree_view))" ); return; } } while (0); |
12550 | |
12551 | hadj = tree_view->priv->hadjustment; |
12552 | vadj = tree_view->priv->vadjustment; |
12553 | |
12554 | if (tree_x != -1) |
12555 | ctk_adjustment_animate_to_value (hadj, tree_x); |
12556 | if (tree_y != -1) |
12557 | ctk_adjustment_animate_to_value (vadj, tree_y); |
12558 | } |
12559 | |
12560 | /** |
12561 | * ctk_tree_view_scroll_to_cell: |
12562 | * @tree_view: A #CtkTreeView. |
12563 | * @path: (allow-none): The path of the row to move to, or %NULL. |
12564 | * @column: (allow-none): The #CtkTreeViewColumn to move horizontally to, or %NULL. |
12565 | * @use_align: whether to use alignment arguments, or %FALSE. |
12566 | * @row_align: The vertical alignment of the row specified by @path. |
12567 | * @col_align: The horizontal alignment of the column specified by @column. |
12568 | * |
12569 | * Moves the alignments of @tree_view to the position specified by @column and |
12570 | * @path. If @column is %NULL, then no horizontal scrolling occurs. Likewise, |
12571 | * if @path is %NULL no vertical scrolling occurs. At a minimum, one of @column |
12572 | * or @path need to be non-%NULL. @row_align determines where the row is |
12573 | * placed, and @col_align determines where @column is placed. Both are expected |
12574 | * to be between 0.0 and 1.0. 0.0 means left/top alignment, 1.0 means |
12575 | * right/bottom alignment, 0.5 means center. |
12576 | * |
12577 | * If @use_align is %FALSE, then the alignment arguments are ignored, and the |
12578 | * tree does the minimum amount of work to scroll the cell onto the screen. |
12579 | * This means that the cell will be scrolled to the edge closest to its current |
12580 | * position. If the cell is currently visible on the screen, nothing is done. |
12581 | * |
12582 | * This function only works if the model is set, and @path is a valid row on the |
12583 | * model. If the model changes before the @tree_view is realized, the centered |
12584 | * path will be modified to reflect this change. |
12585 | **/ |
12586 | void |
12587 | ctk_tree_view_scroll_to_cell (CtkTreeView *tree_view, |
12588 | CtkTreePath *path, |
12589 | CtkTreeViewColumn *column, |
12590 | gboolean use_align, |
12591 | gfloat row_align, |
12592 | gfloat col_align) |
12593 | { |
12594 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12595 | g_return_if_fail (tree_view->priv->model != NULL)do { if ((tree_view->priv->model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "tree_view->priv->model != NULL"); return; } } while (0); |
12596 | g_return_if_fail (tree_view->priv->tree != NULL)do { if ((tree_view->priv->tree != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "tree_view->priv->tree != NULL"); return; } } while ( 0); |
12597 | g_return_if_fail (row_align >= 0.0 && row_align <= 1.0)do { if ((row_align >= 0.0 && row_align <= 1.0) ) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "row_align >= 0.0 && row_align <= 1.0" ); return; } } while (0); |
12598 | g_return_if_fail (col_align >= 0.0 && col_align <= 1.0)do { if ((col_align >= 0.0 && col_align <= 1.0) ) { } else { g_return_if_fail_warning ("Ctk", ((const char*) ( __func__)), "col_align >= 0.0 && col_align <= 1.0" ); return; } } while (0); |
12599 | g_return_if_fail (path != NULL || column != NULL)do { if ((path != ((void*)0) || column != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "path != NULL || column != NULL"); return; } } while (0); |
12600 | |
12601 | row_align = CLAMP (row_align, 0.0, 1.0)(((row_align) > (1.0)) ? (1.0) : (((row_align) < (0.0)) ? (0.0) : (row_align))); |
12602 | col_align = CLAMP (col_align, 0.0, 1.0)(((col_align) > (1.0)) ? (1.0) : (((col_align) < (0.0)) ? (0.0) : (col_align))); |
12603 | |
12604 | |
12605 | /* Note: Despite the benefits that come from having one code path for the |
12606 | * scrolling code, we short-circuit validate_visible_area's immplementation as |
12607 | * it is much slower than just going to the point. |
12608 | */ |
12609 | if (!ctk_widget_get_visible (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) || |
12610 | !ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) || |
12611 | _ctk_widget_get_alloc_needed (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) || |
12612 | CTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, CTK_RBNODE_DESCENDANTS_INVALID)(tree_view->priv->tree->root?(((tree_view->priv-> tree->root->flags&CTK_RBNODE_DESCENDANTS_INVALID)== CTK_RBNODE_DESCENDANTS_INVALID)?(!(0)):(0)):(0))) |
12613 | { |
12614 | if (tree_view->priv->scroll_to_path) |
12615 | ctk_tree_row_reference_free (tree_view->priv->scroll_to_path); |
12616 | |
12617 | tree_view->priv->scroll_to_path = NULL((void*)0); |
12618 | tree_view->priv->scroll_to_column = NULL((void*)0); |
12619 | |
12620 | if (path) |
12621 | tree_view->priv->scroll_to_path = ctk_tree_row_reference_new_proxy (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view->priv->model, path); |
12622 | if (column) |
12623 | tree_view->priv->scroll_to_column = column; |
12624 | tree_view->priv->scroll_to_use_align = use_align; |
12625 | tree_view->priv->scroll_to_row_align = row_align; |
12626 | tree_view->priv->scroll_to_col_align = col_align; |
12627 | |
12628 | install_presize_handler (tree_view); |
12629 | } |
12630 | else |
12631 | { |
12632 | CdkRectangle cell_rect; |
12633 | CdkRectangle vis_rect; |
12634 | gint dest_x, dest_y; |
12635 | |
12636 | ctk_tree_view_get_background_area (tree_view, path, column, &cell_rect); |
12637 | ctk_tree_view_get_visible_rect (tree_view, &vis_rect); |
12638 | |
12639 | cell_rect.y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, cell_rect.y)((cell_rect.y) + tree_view->priv->dy); |
12640 | |
12641 | dest_x = vis_rect.x; |
12642 | dest_y = vis_rect.y; |
12643 | |
12644 | if (column) |
12645 | { |
12646 | if (use_align) |
12647 | { |
12648 | dest_x = cell_rect.x - ((vis_rect.width - cell_rect.width) * col_align); |
12649 | } |
12650 | else |
12651 | { |
12652 | if (cell_rect.x < vis_rect.x) |
12653 | dest_x = cell_rect.x; |
12654 | if (cell_rect.x + cell_rect.width > vis_rect.x + vis_rect.width) |
12655 | dest_x = cell_rect.x + cell_rect.width - vis_rect.width; |
12656 | } |
12657 | } |
12658 | |
12659 | if (path) |
12660 | { |
12661 | if (use_align) |
12662 | { |
12663 | dest_y = cell_rect.y - ((vis_rect.height - cell_rect.height) * row_align); |
12664 | dest_y = MAX (dest_y, 0)(((dest_y) > (0)) ? (dest_y) : (0)); |
12665 | } |
12666 | else |
12667 | { |
12668 | if (cell_rect.y < vis_rect.y) |
12669 | dest_y = cell_rect.y; |
12670 | if (cell_rect.y + cell_rect.height > vis_rect.y + vis_rect.height) |
12671 | dest_y = cell_rect.y + cell_rect.height - vis_rect.height; |
12672 | } |
12673 | } |
12674 | |
12675 | ctk_tree_view_scroll_to_point (tree_view, dest_x, dest_y); |
12676 | } |
12677 | } |
12678 | |
12679 | /** |
12680 | * ctk_tree_view_row_activated: |
12681 | * @tree_view: A #CtkTreeView |
12682 | * @path: The #CtkTreePath to be activated. |
12683 | * @column: The #CtkTreeViewColumn to be activated. |
12684 | * |
12685 | * Activates the cell determined by @path and @column. |
12686 | **/ |
12687 | void |
12688 | ctk_tree_view_row_activated (CtkTreeView *tree_view, |
12689 | CtkTreePath *path, |
12690 | CtkTreeViewColumn *column) |
12691 | { |
12692 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12693 | |
12694 | g_signal_emit (tree_view, tree_view_signals[ROW_ACTIVATED], 0, path, column); |
12695 | } |
12696 | |
12697 | |
12698 | static void |
12699 | ctk_tree_view_expand_all_emission_helper (CtkRBTree *tree, |
12700 | CtkRBNode *node, |
12701 | gpointer data) |
12702 | { |
12703 | CtkTreeView *tree_view = data; |
12704 | |
12705 | if ((node->flags & CTK_RBNODE_IS_PARENT) == CTK_RBNODE_IS_PARENT && |
12706 | node->children) |
12707 | { |
12708 | CtkTreePath *path; |
12709 | CtkTreeIter iter; |
12710 | |
12711 | path = _ctk_tree_path_new_from_rbtree (tree, node); |
12712 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
12713 | |
12714 | g_signal_emit (tree_view, tree_view_signals[ROW_EXPANDED], 0, &iter, path); |
12715 | |
12716 | ctk_tree_path_free (path); |
12717 | } |
12718 | |
12719 | if (node->children) |
12720 | _ctk_rbtree_traverse (node->children, |
12721 | node->children->root, |
12722 | G_PRE_ORDER, |
12723 | ctk_tree_view_expand_all_emission_helper, |
12724 | tree_view); |
12725 | } |
12726 | |
12727 | /** |
12728 | * ctk_tree_view_expand_all: |
12729 | * @tree_view: A #CtkTreeView. |
12730 | * |
12731 | * Recursively expands all nodes in the @tree_view. |
12732 | **/ |
12733 | void |
12734 | ctk_tree_view_expand_all (CtkTreeView *tree_view) |
12735 | { |
12736 | CtkTreePath *path; |
12737 | CtkRBTree *tree; |
12738 | CtkRBNode *node; |
12739 | |
12740 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12741 | |
12742 | if (tree_view->priv->tree == NULL((void*)0)) |
12743 | return; |
12744 | |
12745 | path = ctk_tree_path_new_first (); |
12746 | _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
12747 | |
12748 | while (node) |
12749 | { |
12750 | ctk_tree_view_real_expand_row (tree_view, path, tree, node, TRUE(!(0)), FALSE(0)); |
12751 | node = _ctk_rbtree_next (tree, node); |
12752 | ctk_tree_path_next (path); |
12753 | } |
12754 | |
12755 | ctk_tree_path_free (path); |
12756 | } |
12757 | |
12758 | /** |
12759 | * ctk_tree_view_collapse_all: |
12760 | * @tree_view: A #CtkTreeView. |
12761 | * |
12762 | * Recursively collapses all visible, expanded nodes in @tree_view. |
12763 | **/ |
12764 | void |
12765 | ctk_tree_view_collapse_all (CtkTreeView *tree_view) |
12766 | { |
12767 | CtkRBTree *tree; |
12768 | CtkRBNode *node; |
12769 | CtkTreePath *path; |
12770 | gint *indices; |
12771 | |
12772 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12773 | |
12774 | if (tree_view->priv->tree == NULL((void*)0)) |
12775 | return; |
12776 | |
12777 | path = ctk_tree_path_new (); |
12778 | ctk_tree_path_down (path); |
12779 | indices = ctk_tree_path_get_indices (path); |
12780 | |
12781 | tree = tree_view->priv->tree; |
12782 | node = _ctk_rbtree_first (tree); |
12783 | |
12784 | while (node) |
12785 | { |
12786 | if (node->children) |
12787 | ctk_tree_view_real_collapse_row (tree_view, path, tree, node, FALSE(0)); |
12788 | indices[0]++; |
12789 | node = _ctk_rbtree_next (tree, node); |
12790 | } |
12791 | |
12792 | ctk_tree_path_free (path); |
12793 | } |
12794 | |
12795 | /** |
12796 | * ctk_tree_view_expand_to_path: |
12797 | * @tree_view: A #CtkTreeView. |
12798 | * @path: path to a row. |
12799 | * |
12800 | * Expands the row at @path. This will also expand all parent rows of |
12801 | * @path as necessary. |
12802 | * |
12803 | * Since: 2.2 |
12804 | **/ |
12805 | void |
12806 | ctk_tree_view_expand_to_path (CtkTreeView *tree_view, |
12807 | CtkTreePath *path) |
12808 | { |
12809 | gint i, depth; |
12810 | gint *indices; |
12811 | CtkTreePath *tmp; |
12812 | |
12813 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
12814 | g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return; } } while (0); |
12815 | |
12816 | depth = ctk_tree_path_get_depth (path); |
12817 | indices = ctk_tree_path_get_indices (path); |
12818 | |
12819 | tmp = ctk_tree_path_new (); |
12820 | g_return_if_fail (tmp != NULL)do { if ((tmp != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "tmp != NULL"); return; } } while (0); |
12821 | |
12822 | for (i = 0; i < depth; i++) |
12823 | { |
12824 | ctk_tree_path_append_index (tmp, indices[i]); |
12825 | ctk_tree_view_expand_row (tree_view, tmp, FALSE(0)); |
12826 | } |
12827 | |
12828 | ctk_tree_path_free (tmp); |
12829 | } |
12830 | |
12831 | /* FIXME the bool return values for expand_row and collapse_row are |
12832 | * not analagous; they should be TRUE if the row had children and |
12833 | * was not already in the requested state. |
12834 | */ |
12835 | |
12836 | |
12837 | static gboolean |
12838 | ctk_tree_view_real_expand_row (CtkTreeView *tree_view, |
12839 | CtkTreePath *path, |
12840 | CtkRBTree *tree, |
12841 | CtkRBNode *node, |
12842 | gboolean open_all, |
12843 | gboolean animate) |
12844 | { |
12845 | CtkTreeIter iter; |
12846 | CtkTreeIter temp; |
12847 | gboolean expand; |
12848 | |
12849 | if (animate) |
12850 | animate = ctk_settings_get_enable_animations (ctk_widget_get_settings (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))); |
12851 | |
12852 | remove_auto_expand_timeout (tree_view); |
12853 | |
12854 | if (node->children && !open_all) |
12855 | return FALSE(0); |
12856 | |
12857 | if (! CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0))) |
12858 | return FALSE(0); |
12859 | |
12860 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
12861 | if (! ctk_tree_model_iter_has_child (tree_view->priv->model, &iter)) |
12862 | return FALSE(0); |
12863 | |
12864 | |
12865 | if (node->children && open_all) |
12866 | { |
12867 | gboolean retval = FALSE(0); |
12868 | CtkTreePath *tmp_path = ctk_tree_path_copy (path); |
12869 | |
12870 | ctk_tree_path_append_index (tmp_path, 0); |
12871 | tree = node->children; |
12872 | node = _ctk_rbtree_first (tree); |
12873 | /* try to expand the children */ |
12874 | do |
12875 | { |
12876 | gboolean t; |
12877 | t = ctk_tree_view_real_expand_row (tree_view, tmp_path, tree, node, |
12878 | TRUE(!(0)), animate); |
12879 | if (t) |
12880 | retval = TRUE(!(0)); |
12881 | |
12882 | ctk_tree_path_next (tmp_path); |
12883 | node = _ctk_rbtree_next (tree, node); |
12884 | } |
12885 | while (node != NULL((void*)0)); |
12886 | |
12887 | ctk_tree_path_free (tmp_path); |
12888 | |
12889 | return retval; |
12890 | } |
12891 | |
12892 | g_signal_emit (tree_view, tree_view_signals[TEST_EXPAND_ROW], 0, &iter, path, &expand); |
12893 | |
12894 | if (!ctk_tree_model_iter_has_child (tree_view->priv->model, &iter)) |
12895 | return FALSE(0); |
12896 | |
12897 | if (expand) |
12898 | return FALSE(0); |
12899 | |
12900 | node->children = _ctk_rbtree_new (); |
12901 | node->children->parent_tree = tree; |
12902 | node->children->parent_node = node; |
12903 | |
12904 | ctk_tree_model_iter_children (tree_view->priv->model, &temp, &iter); |
12905 | |
12906 | ctk_tree_view_build_tree (tree_view, |
12907 | node->children, |
12908 | &temp, |
12909 | ctk_tree_path_get_depth (path) + 1, |
12910 | open_all); |
12911 | |
12912 | _ctk_tree_view_accessible_add (tree_view, node->children, NULL((void*)0)); |
12913 | _ctk_tree_view_accessible_add_state (tree_view, |
12914 | tree, node, |
12915 | CTK_CELL_RENDERER_EXPANDED); |
12916 | |
12917 | install_presize_handler (tree_view); |
12918 | |
12919 | g_signal_emit (tree_view, tree_view_signals[ROW_EXPANDED], 0, &iter, path); |
12920 | if (open_all && node->children) |
12921 | { |
12922 | _ctk_rbtree_traverse (node->children, |
12923 | node->children->root, |
12924 | G_PRE_ORDER, |
12925 | ctk_tree_view_expand_all_emission_helper, |
12926 | tree_view); |
12927 | } |
12928 | return TRUE(!(0)); |
12929 | } |
12930 | |
12931 | |
12932 | /** |
12933 | * ctk_tree_view_expand_row: |
12934 | * @tree_view: a #CtkTreeView |
12935 | * @path: path to a row |
12936 | * @open_all: whether to recursively expand, or just expand immediate children |
12937 | * |
12938 | * Opens the row so its children are visible. |
12939 | * |
12940 | * Returns: %TRUE if the row existed and had children |
12941 | **/ |
12942 | gboolean |
12943 | ctk_tree_view_expand_row (CtkTreeView *tree_view, |
12944 | CtkTreePath *path, |
12945 | gboolean open_all) |
12946 | { |
12947 | CtkRBTree *tree; |
12948 | CtkRBNode *node; |
12949 | |
12950 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
12951 | g_return_val_if_fail (tree_view->priv->model != NULL, FALSE)do { if ((tree_view->priv->model != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "tree_view->priv->model != NULL"); return ((0)); } } while (0); |
12952 | g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return ( (0)); } } while (0); |
12953 | |
12954 | if (_ctk_tree_view_find_node (tree_view, |
12955 | path, |
12956 | &tree, |
12957 | &node)) |
12958 | return FALSE(0); |
12959 | |
12960 | if (tree != NULL((void*)0)) |
12961 | return ctk_tree_view_real_expand_row (tree_view, path, tree, node, open_all, FALSE(0)); |
12962 | else |
12963 | return FALSE(0); |
12964 | } |
12965 | |
12966 | static gboolean |
12967 | ctk_tree_view_real_collapse_row (CtkTreeView *tree_view, |
12968 | CtkTreePath *path, |
12969 | CtkRBTree *tree, |
12970 | CtkRBNode *node, |
12971 | gboolean animate) |
12972 | { |
12973 | CtkTreeIter iter; |
12974 | CtkTreeIter children; |
12975 | gboolean collapse; |
12976 | GList *list; |
12977 | gboolean selection_changed, cursor_changed; |
12978 | |
12979 | if (animate) |
12980 | animate = ctk_settings_get_enable_animations (ctk_widget_get_settings (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))); |
12981 | |
12982 | remove_auto_expand_timeout (tree_view); |
12983 | |
12984 | if (node->children == NULL((void*)0)) |
12985 | return FALSE(0); |
12986 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, path); |
12987 | |
12988 | g_signal_emit (tree_view, tree_view_signals[TEST_COLLAPSE_ROW], 0, &iter, path, &collapse); |
12989 | |
12990 | if (collapse) |
12991 | return FALSE(0); |
12992 | |
12993 | /* if the prelighted node is a child of us, we want to unprelight it. We have |
12994 | * a chance to prelight the correct node below */ |
12995 | |
12996 | if (tree_view->priv->prelight_tree) |
12997 | { |
12998 | CtkRBTree *parent_tree; |
12999 | CtkRBNode *parent_node; |
13000 | |
13001 | parent_tree = tree_view->priv->prelight_tree->parent_tree; |
13002 | parent_node = tree_view->priv->prelight_tree->parent_node; |
13003 | while (parent_tree) |
13004 | { |
13005 | if (parent_tree == tree && parent_node == node) |
13006 | { |
13007 | ensure_unprelighted (tree_view); |
13008 | break; |
13009 | } |
13010 | parent_node = parent_tree->parent_node; |
13011 | parent_tree = parent_tree->parent_tree; |
13012 | } |
13013 | } |
13014 | |
13015 | TREE_VIEW_INTERNAL_ASSERT (ctk_tree_model_iter_children (tree_view->priv->model, &children, &iter), FALSE)do{ if (!(ctk_tree_model_iter_children (tree_view->priv-> model, &children, &iter))) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL , "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "13015", ((const char *) (__func__)), "ctk_tree_model_iter_children (tree_view->priv->model, &children, &iter)" ); return (0); }; }while (0); |
13016 | |
13017 | for (list = tree_view->priv->columns; list; list = list->next) |
13018 | { |
13019 | CtkTreeViewColumn *column = list->data; |
13020 | |
13021 | if (ctk_tree_view_column_get_visible (column) == FALSE(0)) |
13022 | continue; |
13023 | if (ctk_tree_view_column_get_sizing (column) == CTK_TREE_VIEW_COLUMN_AUTOSIZE) |
13024 | _ctk_tree_view_column_cell_set_dirty (column, TRUE(!(0))); |
13025 | } |
13026 | |
13027 | if (tree_view->priv->destroy_count_func) |
13028 | { |
13029 | CtkTreePath *child_path; |
13030 | gint child_count = 0; |
13031 | child_path = ctk_tree_path_copy (path); |
13032 | ctk_tree_path_down (child_path); |
13033 | if (node->children) |
13034 | _ctk_rbtree_traverse (node->children, node->children->root, G_POST_ORDER, count_children_helper, &child_count); |
13035 | tree_view->priv->destroy_count_func (tree_view, child_path, child_count, tree_view->priv->destroy_count_data); |
13036 | ctk_tree_path_free (child_path); |
13037 | } |
13038 | |
13039 | if (tree_view->priv->cursor_node) |
13040 | { |
13041 | cursor_changed = (node->children == tree_view->priv->cursor_tree) |
13042 | || _ctk_rbtree_contains (node->children, tree_view->priv->cursor_tree); |
13043 | } |
13044 | else |
13045 | cursor_changed = FALSE(0); |
13046 | |
13047 | if (ctk_tree_row_reference_valid (tree_view->priv->anchor)) |
13048 | { |
13049 | CtkTreePath *anchor_path = ctk_tree_row_reference_get_path (tree_view->priv->anchor); |
13050 | if (ctk_tree_path_is_ancestor (path, anchor_path)) |
13051 | { |
13052 | ctk_tree_row_reference_free (tree_view->priv->anchor); |
13053 | tree_view->priv->anchor = NULL((void*)0); |
13054 | } |
13055 | ctk_tree_path_free (anchor_path); |
13056 | } |
13057 | |
13058 | selection_changed = ctk_tree_view_unref_and_check_selection_tree (tree_view, node->children); |
13059 | |
13060 | /* Stop a pending double click */ |
13061 | ctk_event_controller_reset (CTK_EVENT_CONTROLLER (tree_view->priv->multipress_gesture)((((CtkEventController*) (void *) g_type_check_instance_cast ( (GTypeInstance*) ((tree_view->priv->multipress_gesture) ), ((ctk_event_controller_get_type ()))))))); |
13062 | |
13063 | _ctk_tree_view_accessible_remove (tree_view, node->children, NULL((void*)0)); |
13064 | _ctk_tree_view_accessible_remove_state (tree_view, |
13065 | tree, node, |
13066 | CTK_CELL_RENDERER_EXPANDED); |
13067 | |
13068 | _ctk_rbtree_remove (node->children); |
13069 | |
13070 | if (cursor_changed) |
13071 | ctk_tree_view_real_set_cursor (tree_view, path, CLEAR_AND_SELECT | CURSOR_INVALID); |
13072 | if (selection_changed) |
13073 | g_signal_emit_by_name (tree_view->priv->selection, "changed"); |
13074 | |
13075 | if (ctk_widget_get_mapped (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
13076 | { |
13077 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
13078 | } |
13079 | |
13080 | g_signal_emit (tree_view, tree_view_signals[ROW_COLLAPSED], 0, &iter, path); |
13081 | |
13082 | if (ctk_widget_get_mapped (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
13083 | update_prelight (tree_view, |
13084 | tree_view->priv->event_last_x, |
13085 | tree_view->priv->event_last_y); |
13086 | |
13087 | return TRUE(!(0)); |
13088 | } |
13089 | |
13090 | /** |
13091 | * ctk_tree_view_collapse_row: |
13092 | * @tree_view: a #CtkTreeView |
13093 | * @path: path to a row in the @tree_view |
13094 | * |
13095 | * Collapses a row (hides its child rows, if they exist). |
13096 | * |
13097 | * Returns: %TRUE if the row was collapsed. |
13098 | **/ |
13099 | gboolean |
13100 | ctk_tree_view_collapse_row (CtkTreeView *tree_view, |
13101 | CtkTreePath *path) |
13102 | { |
13103 | CtkRBTree *tree; |
13104 | CtkRBNode *node; |
13105 | |
13106 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
13107 | g_return_val_if_fail (tree_view->priv->tree != NULL, FALSE)do { if ((tree_view->priv->tree != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__) ), "tree_view->priv->tree != NULL"); return ((0)); } } while (0); |
13108 | g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return ( (0)); } } while (0); |
13109 | |
13110 | if (_ctk_tree_view_find_node (tree_view, |
13111 | path, |
13112 | &tree, |
13113 | &node)) |
13114 | return FALSE(0); |
13115 | |
13116 | if (tree == NULL((void*)0) || node->children == NULL((void*)0)) |
13117 | return FALSE(0); |
13118 | |
13119 | return ctk_tree_view_real_collapse_row (tree_view, path, tree, node, FALSE(0)); |
13120 | } |
13121 | |
13122 | static void |
13123 | ctk_tree_view_map_expanded_rows_helper (CtkTreeView *tree_view, |
13124 | CtkRBTree *tree, |
13125 | CtkTreePath *path, |
13126 | CtkTreeViewMappingFunc func, |
13127 | gpointer user_data) |
13128 | { |
13129 | CtkRBNode *node; |
13130 | |
13131 | if (tree == NULL((void*)0) || tree->root == NULL((void*)0)) |
13132 | return; |
13133 | |
13134 | node = _ctk_rbtree_first (tree); |
13135 | |
13136 | while (node) |
13137 | { |
13138 | if (node->children) |
13139 | { |
13140 | (* func) (tree_view, path, user_data); |
13141 | ctk_tree_path_down (path); |
13142 | ctk_tree_view_map_expanded_rows_helper (tree_view, node->children, path, func, user_data); |
13143 | ctk_tree_path_up (path); |
13144 | } |
13145 | ctk_tree_path_next (path); |
13146 | node = _ctk_rbtree_next (tree, node); |
13147 | } |
13148 | } |
13149 | |
13150 | /** |
13151 | * ctk_tree_view_map_expanded_rows: |
13152 | * @tree_view: A #CtkTreeView |
13153 | * @func: (scope call): A function to be called |
13154 | * @data: User data to be passed to the function. |
13155 | * |
13156 | * Calls @func on all expanded rows. |
13157 | **/ |
13158 | void |
13159 | ctk_tree_view_map_expanded_rows (CtkTreeView *tree_view, |
13160 | CtkTreeViewMappingFunc func, |
13161 | gpointer user_data) |
13162 | { |
13163 | CtkTreePath *path; |
13164 | |
13165 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13166 | g_return_if_fail (func != NULL)do { if ((func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "func != NULL"); return; } } while (0); |
13167 | |
13168 | path = ctk_tree_path_new_first (); |
13169 | |
13170 | ctk_tree_view_map_expanded_rows_helper (tree_view, |
13171 | tree_view->priv->tree, |
13172 | path, func, user_data); |
13173 | |
13174 | ctk_tree_path_free (path); |
13175 | } |
13176 | |
13177 | /** |
13178 | * ctk_tree_view_row_expanded: |
13179 | * @tree_view: A #CtkTreeView. |
13180 | * @path: A #CtkTreePath to test expansion state. |
13181 | * |
13182 | * Returns %TRUE if the node pointed to by @path is expanded in @tree_view. |
13183 | * |
13184 | * Returns: %TRUE if #path is expanded. |
13185 | **/ |
13186 | gboolean |
13187 | ctk_tree_view_row_expanded (CtkTreeView *tree_view, |
13188 | CtkTreePath *path) |
13189 | { |
13190 | CtkRBTree *tree; |
13191 | CtkRBNode *node; |
13192 | |
13193 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
13194 | g_return_val_if_fail (path != NULL, FALSE)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return ( (0)); } } while (0); |
13195 | |
13196 | _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
13197 | |
13198 | if (node == NULL((void*)0)) |
13199 | return FALSE(0); |
13200 | |
13201 | return (node->children != NULL((void*)0)); |
13202 | } |
13203 | |
13204 | /** |
13205 | * ctk_tree_view_get_reorderable: |
13206 | * @tree_view: a #CtkTreeView |
13207 | * |
13208 | * Retrieves whether the user can reorder the tree via drag-and-drop. See |
13209 | * ctk_tree_view_set_reorderable(). |
13210 | * |
13211 | * Returns: %TRUE if the tree can be reordered. |
13212 | **/ |
13213 | gboolean |
13214 | ctk_tree_view_get_reorderable (CtkTreeView *tree_view) |
13215 | { |
13216 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
13217 | |
13218 | return tree_view->priv->reorderable; |
13219 | } |
13220 | |
13221 | /** |
13222 | * ctk_tree_view_set_reorderable: |
13223 | * @tree_view: A #CtkTreeView. |
13224 | * @reorderable: %TRUE, if the tree can be reordered. |
13225 | * |
13226 | * This function is a convenience function to allow you to reorder |
13227 | * models that support the #CtkTreeDragSourceIface and the |
13228 | * #CtkTreeDragDestIface. Both #CtkTreeStore and #CtkListStore support |
13229 | * these. If @reorderable is %TRUE, then the user can reorder the |
13230 | * model by dragging and dropping rows. The developer can listen to |
13231 | * these changes by connecting to the model’s #CtkTreeModel::row-inserted |
13232 | * and #CtkTreeModel::row-deleted signals. The reordering is implemented |
13233 | * by setting up the tree view as a drag source and destination. |
13234 | * Therefore, drag and drop can not be used in a reorderable view for any |
13235 | * other purpose. |
13236 | * |
13237 | * This function does not give you any degree of control over the order -- any |
13238 | * reordering is allowed. If more control is needed, you should probably |
13239 | * handle drag and drop manually. |
13240 | **/ |
13241 | void |
13242 | ctk_tree_view_set_reorderable (CtkTreeView *tree_view, |
13243 | gboolean reorderable) |
13244 | { |
13245 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13246 | |
13247 | reorderable = reorderable != FALSE(0); |
13248 | |
13249 | if (tree_view->priv->reorderable == reorderable) |
13250 | return; |
13251 | |
13252 | if (reorderable) |
13253 | { |
13254 | const CtkTargetEntry row_targets[] = { |
13255 | { "CTK_TREE_MODEL_ROW", CTK_TARGET_SAME_WIDGET, 0 } |
13256 | }; |
13257 | |
13258 | ctk_tree_view_enable_model_drag_source (tree_view, |
13259 | CDK_BUTTON1_MASK, |
13260 | row_targets, |
13261 | G_N_ELEMENTS (row_targets)(sizeof (row_targets) / sizeof ((row_targets)[0])), |
13262 | CDK_ACTION_MOVE); |
13263 | ctk_tree_view_enable_model_drag_dest (tree_view, |
13264 | row_targets, |
13265 | G_N_ELEMENTS (row_targets)(sizeof (row_targets) / sizeof ((row_targets)[0])), |
13266 | CDK_ACTION_MOVE); |
13267 | } |
13268 | else |
13269 | { |
13270 | ctk_tree_view_unset_rows_drag_source (tree_view); |
13271 | ctk_tree_view_unset_rows_drag_dest (tree_view); |
13272 | } |
13273 | |
13274 | tree_view->priv->reorderable = reorderable; |
13275 | |
13276 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_REORDERABLE]); |
13277 | } |
13278 | |
13279 | static void |
13280 | ctk_tree_view_real_set_cursor (CtkTreeView *tree_view, |
13281 | CtkTreePath *path, |
13282 | SetCursorFlags flags) |
13283 | { |
13284 | if (!(flags & CURSOR_INVALID) && tree_view->priv->cursor_node) |
13285 | { |
13286 | _ctk_tree_view_accessible_remove_state (tree_view, |
13287 | tree_view->priv->cursor_tree, |
13288 | tree_view->priv->cursor_node, |
13289 | CTK_CELL_RENDERER_FOCUSED); |
13290 | _ctk_tree_view_queue_draw_node (tree_view, |
13291 | tree_view->priv->cursor_tree, |
13292 | tree_view->priv->cursor_node, |
13293 | NULL((void*)0)); |
13294 | } |
13295 | |
13296 | /* One cannot set the cursor on a separator. Also, if |
13297 | * _ctk_tree_view_find_node returns TRUE, it ran out of tree |
13298 | * before finding the tree and node belonging to path. The |
13299 | * path maps to a non-existing path and we will silently bail out. |
13300 | * We unset tree and node to avoid further processing. |
13301 | */ |
13302 | if (path == NULL((void*)0) || |
13303 | row_is_separator (tree_view, NULL((void*)0), path) |
13304 | || _ctk_tree_view_find_node (tree_view, |
13305 | path, |
13306 | &tree_view->priv->cursor_tree, |
13307 | &tree_view->priv->cursor_node)) |
13308 | { |
13309 | tree_view->priv->cursor_tree = NULL((void*)0); |
13310 | tree_view->priv->cursor_node = NULL((void*)0); |
13311 | } |
13312 | |
13313 | if (tree_view->priv->cursor_node != NULL((void*)0)) |
13314 | { |
13315 | CtkRBTree *new_tree = NULL((void*)0); |
13316 | CtkRBNode *new_node = NULL((void*)0); |
13317 | |
13318 | if ((flags & CLEAR_AND_SELECT) && !tree_view->priv->modify_selection_pressed) |
13319 | { |
13320 | CtkTreeSelectMode mode = 0; |
13321 | |
13322 | if (tree_view->priv->extend_selection_pressed) |
13323 | mode |= CTK_TREE_SELECT_MODE_EXTEND; |
13324 | |
13325 | _ctk_tree_selection_internal_select_node (tree_view->priv->selection, |
13326 | tree_view->priv->cursor_node, |
13327 | tree_view->priv->cursor_tree, |
13328 | path, |
13329 | mode, |
13330 | FALSE(0)); |
13331 | } |
13332 | |
13333 | /* We have to re-find tree and node here again, somebody might have |
13334 | * cleared the node or the whole tree in the CtkTreeSelection::changed |
13335 | * callback. If the nodes differ we bail out here. |
13336 | */ |
13337 | _ctk_tree_view_find_node (tree_view, path, &new_tree, &new_node); |
13338 | |
13339 | if (tree_view->priv->cursor_node == NULL((void*)0) || |
13340 | tree_view->priv->cursor_node != new_node) |
13341 | return; |
13342 | |
13343 | if (flags & CLAMP_NODE) |
13344 | { |
13345 | ctk_tree_view_clamp_node_visible (tree_view, |
13346 | tree_view->priv->cursor_tree, |
13347 | tree_view->priv->cursor_node); |
13348 | _ctk_tree_view_queue_draw_node (tree_view, |
13349 | tree_view->priv->cursor_tree, |
13350 | tree_view->priv->cursor_node, |
13351 | NULL((void*)0)); |
13352 | } |
13353 | |
13354 | _ctk_tree_view_accessible_add_state (tree_view, |
13355 | tree_view->priv->cursor_tree, |
13356 | tree_view->priv->cursor_node, |
13357 | CTK_CELL_RENDERER_FOCUSED); |
13358 | } |
13359 | |
13360 | if (!ctk_widget_in_destruction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
13361 | g_signal_emit (tree_view, tree_view_signals[CURSOR_CHANGED], 0); |
13362 | } |
13363 | |
13364 | /** |
13365 | * ctk_tree_view_get_cursor: |
13366 | * @tree_view: A #CtkTreeView |
13367 | * @path: (out) (transfer full) (optional) (nullable): A pointer to be |
13368 | * filled with the current cursor path, or %NULL |
13369 | * @focus_column: (out) (transfer none) (optional) (nullable): A |
13370 | * pointer to be filled with the current focus column, or %NULL |
13371 | * |
13372 | * Fills in @path and @focus_column with the current path and focus column. If |
13373 | * the cursor isn’t currently set, then *@path will be %NULL. If no column |
13374 | * currently has focus, then *@focus_column will be %NULL. |
13375 | * |
13376 | * The returned #CtkTreePath must be freed with ctk_tree_path_free() when |
13377 | * you are done with it. |
13378 | **/ |
13379 | void |
13380 | ctk_tree_view_get_cursor (CtkTreeView *tree_view, |
13381 | CtkTreePath **path, |
13382 | CtkTreeViewColumn **focus_column) |
13383 | { |
13384 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13385 | |
13386 | if (path) |
13387 | { |
13388 | if (tree_view->priv->cursor_node) |
13389 | *path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
13390 | tree_view->priv->cursor_node); |
13391 | else |
13392 | *path = NULL((void*)0); |
13393 | } |
13394 | |
13395 | if (focus_column) |
13396 | { |
13397 | *focus_column = tree_view->priv->focus_column; |
13398 | } |
13399 | } |
13400 | |
13401 | /** |
13402 | * ctk_tree_view_set_cursor: |
13403 | * @tree_view: A #CtkTreeView |
13404 | * @path: A #CtkTreePath |
13405 | * @focus_column: (allow-none): A #CtkTreeViewColumn, or %NULL |
13406 | * @start_editing: %TRUE if the specified cell should start being edited. |
13407 | * |
13408 | * Sets the current keyboard focus to be at @path, and selects it. This is |
13409 | * useful when you want to focus the user’s attention on a particular row. If |
13410 | * @focus_column is not %NULL, then focus is given to the column specified by |
13411 | * it. Additionally, if @focus_column is specified, and @start_editing is |
13412 | * %TRUE, then editing should be started in the specified cell. |
13413 | * This function is often followed by @ctk_widget_grab_focus (@tree_view) |
13414 | * in order to give keyboard focus to the widget. Please note that editing |
13415 | * can only happen when the widget is realized. |
13416 | * |
13417 | * If @path is invalid for @model, the current cursor (if any) will be unset |
13418 | * and the function will return without failing. |
13419 | **/ |
13420 | void |
13421 | ctk_tree_view_set_cursor (CtkTreeView *tree_view, |
13422 | CtkTreePath *path, |
13423 | CtkTreeViewColumn *focus_column, |
13424 | gboolean start_editing) |
13425 | { |
13426 | ctk_tree_view_set_cursor_on_cell (tree_view, path, focus_column, |
13427 | NULL((void*)0), start_editing); |
13428 | } |
13429 | |
13430 | /** |
13431 | * ctk_tree_view_set_cursor_on_cell: |
13432 | * @tree_view: A #CtkTreeView |
13433 | * @path: A #CtkTreePath |
13434 | * @focus_column: (allow-none): A #CtkTreeViewColumn, or %NULL |
13435 | * @focus_cell: (allow-none): A #CtkCellRenderer, or %NULL |
13436 | * @start_editing: %TRUE if the specified cell should start being edited. |
13437 | * |
13438 | * Sets the current keyboard focus to be at @path, and selects it. This is |
13439 | * useful when you want to focus the user’s attention on a particular row. If |
13440 | * @focus_column is not %NULL, then focus is given to the column specified by |
13441 | * it. If @focus_column and @focus_cell are not %NULL, and @focus_column |
13442 | * contains 2 or more editable or activatable cells, then focus is given to |
13443 | * the cell specified by @focus_cell. Additionally, if @focus_column is |
13444 | * specified, and @start_editing is %TRUE, then editing should be started in |
13445 | * the specified cell. This function is often followed by |
13446 | * @ctk_widget_grab_focus (@tree_view) in order to give keyboard focus to the |
13447 | * widget. Please note that editing can only happen when the widget is |
13448 | * realized. |
13449 | * |
13450 | * If @path is invalid for @model, the current cursor (if any) will be unset |
13451 | * and the function will return without failing. |
13452 | * |
13453 | * Since: 2.2 |
13454 | **/ |
13455 | void |
13456 | ctk_tree_view_set_cursor_on_cell (CtkTreeView *tree_view, |
13457 | CtkTreePath *path, |
13458 | CtkTreeViewColumn *focus_column, |
13459 | CtkCellRenderer *focus_cell, |
13460 | gboolean start_editing) |
13461 | { |
13462 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13463 | g_return_if_fail (path != NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return; } } while (0); |
13464 | g_return_if_fail (focus_column == NULL || CTK_IS_TREE_VIEW_COLUMN (focus_column))do { if ((focus_column == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((focus_column)); GType __t = ((ctk_tree_view_column_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "focus_column == NULL || CTK_IS_TREE_VIEW_COLUMN (focus_column)" ); return; } } while (0); |
13465 | |
13466 | if (!tree_view->priv->model) |
13467 | return; |
13468 | |
13469 | if (focus_cell) |
13470 | { |
13471 | g_return_if_fail (focus_column)do { if ((focus_column)) { } else { g_return_if_fail_warning ( "Ctk", ((const char*) (__func__)), "focus_column"); return; } } while (0); |
13472 | g_return_if_fail (CTK_IS_CELL_RENDERER (focus_cell))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((focus_cell)); GType __t = ((ctk_cell_renderer_get_type ( ))); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "CTK_IS_CELL_RENDERER (focus_cell)"); return ; } } while (0); |
13473 | } |
13474 | |
13475 | /* cancel the current editing, if it exists */ |
13476 | if (tree_view->priv->edited_column && |
13477 | ctk_cell_area_get_edit_widget |
13478 | (ctk_cell_layout_get_area (CTK_CELL_LAYOUT (tree_view->priv->edited_column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->edited_column)), ((ctk_cell_layout_get_type ()))))))))) |
13479 | ctk_tree_view_stop_editing (tree_view, TRUE(!(0))); |
13480 | |
13481 | ctk_tree_view_real_set_cursor (tree_view, path, CLEAR_AND_SELECT | CLAMP_NODE); |
13482 | |
13483 | if (focus_column && |
13484 | ctk_tree_view_column_get_visible (focus_column)) |
13485 | { |
13486 | GList *list; |
13487 | gboolean column_in_tree = FALSE(0); |
13488 | |
13489 | for (list = tree_view->priv->columns; list; list = list->next) |
13490 | if (list->data == focus_column) |
13491 | { |
13492 | column_in_tree = TRUE(!(0)); |
13493 | break; |
13494 | } |
13495 | g_return_if_fail (column_in_tree)do { if ((column_in_tree)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column_in_tree"); return ; } } while (0); |
13496 | _ctk_tree_view_set_focus_column (tree_view, focus_column); |
13497 | if (focus_cell) |
13498 | ctk_tree_view_column_focus_cell (focus_column, focus_cell); |
13499 | if (start_editing) |
13500 | ctk_tree_view_start_editing (tree_view, path, TRUE(!(0))); |
13501 | } |
13502 | } |
13503 | |
13504 | /** |
13505 | * ctk_tree_view_get_bin_window: |
13506 | * @tree_view: A #CtkTreeView |
13507 | * |
13508 | * Returns the window that @tree_view renders to. |
13509 | * This is used primarily to compare to `event->window` |
13510 | * to confirm that the event on @tree_view is on the right window. |
13511 | * |
13512 | * Returns: (nullable) (transfer none): A #CdkWindow, or %NULL when @tree_view |
13513 | * hasn’t been realized yet. |
13514 | **/ |
13515 | CdkWindow * |
13516 | ctk_tree_view_get_bin_window (CtkTreeView *tree_view) |
13517 | { |
13518 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
13519 | |
13520 | return tree_view->priv->bin_window; |
13521 | } |
13522 | |
13523 | /** |
13524 | * ctk_tree_view_get_path_at_pos: |
13525 | * @tree_view: A #CtkTreeView. |
13526 | * @x: The x position to be identified (relative to bin_window). |
13527 | * @y: The y position to be identified (relative to bin_window). |
13528 | * @path: (out) (optional) (nullable): A pointer to a #CtkTreePath |
13529 | * pointer to be filled in, or %NULL |
13530 | * @column: (out) (transfer none) (optional) (nullable): A pointer to |
13531 | * a #CtkTreeViewColumn pointer to be filled in, or %NULL |
13532 | * @cell_x: (out) (optional): A pointer where the X coordinate |
13533 | * relative to the cell can be placed, or %NULL |
13534 | * @cell_y: (out) (optional): A pointer where the Y coordinate |
13535 | * relative to the cell can be placed, or %NULL |
13536 | * |
13537 | * Finds the path at the point (@x, @y), relative to bin_window coordinates |
13538 | * (please see ctk_tree_view_get_bin_window()). |
13539 | * That is, @x and @y are relative to an events coordinates. @x and @y must |
13540 | * come from an event on the @tree_view only where `event->window == |
13541 | * ctk_tree_view_get_bin_window ()`. It is primarily for |
13542 | * things like popup menus. If @path is non-%NULL, then it will be filled |
13543 | * with the #CtkTreePath at that point. This path should be freed with |
13544 | * ctk_tree_path_free(). If @column is non-%NULL, then it will be filled |
13545 | * with the column at that point. @cell_x and @cell_y return the coordinates |
13546 | * relative to the cell background (i.e. the @background_area passed to |
13547 | * ctk_cell_renderer_render()). This function is only meaningful if |
13548 | * @tree_view is realized. Therefore this function will always return %FALSE |
13549 | * if @tree_view is not realized or does not have a model. |
13550 | * |
13551 | * For converting widget coordinates (eg. the ones you get from |
13552 | * CtkWidget::query-tooltip), please see |
13553 | * ctk_tree_view_convert_widget_to_bin_window_coords(). |
13554 | * |
13555 | * Returns: %TRUE if a row exists at that coordinate. |
13556 | **/ |
13557 | gboolean |
13558 | ctk_tree_view_get_path_at_pos (CtkTreeView *tree_view, |
13559 | gint x, |
13560 | gint y, |
13561 | CtkTreePath **path, |
13562 | CtkTreeViewColumn **column, |
13563 | gint *cell_x, |
13564 | gint *cell_y) |
13565 | { |
13566 | CtkRBTree *tree; |
13567 | CtkRBNode *node; |
13568 | gint y_offset; |
13569 | |
13570 | g_return_val_if_fail (tree_view != NULL, FALSE)do { if ((tree_view != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "tree_view != NULL"); return ((0)); } } while (0); |
13571 | |
13572 | if (path) |
13573 | *path = NULL((void*)0); |
13574 | if (column) |
13575 | *column = NULL((void*)0); |
13576 | |
13577 | if (tree_view->priv->bin_window == NULL((void*)0)) |
13578 | return FALSE(0); |
13579 | |
13580 | if (tree_view->priv->tree == NULL((void*)0)) |
13581 | return FALSE(0); |
13582 | |
13583 | if (x > ctk_adjustment_get_upper (tree_view->priv->hadjustment)) |
13584 | return FALSE(0); |
13585 | |
13586 | if (x < 0 || y < 0) |
13587 | return FALSE(0); |
13588 | |
13589 | if (column || cell_x) |
13590 | { |
13591 | CtkTreeViewColumn *tmp_column; |
13592 | CtkTreeViewColumn *last_column = NULL((void*)0); |
13593 | GList *list; |
13594 | gint remaining_x = x; |
13595 | gboolean found = FALSE(0); |
13596 | gboolean rtl; |
13597 | gint width; |
13598 | |
13599 | rtl = (ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL); |
13600 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
13601 | list; |
13602 | list = (rtl ? list->prev : list->next)) |
13603 | { |
13604 | tmp_column = list->data; |
13605 | |
13606 | if (ctk_tree_view_column_get_visible (tmp_column) == FALSE(0)) |
13607 | continue; |
13608 | |
13609 | last_column = tmp_column; |
13610 | width = ctk_tree_view_column_get_width (tmp_column); |
13611 | if (remaining_x < width) |
13612 | { |
13613 | found = TRUE(!(0)); |
13614 | |
13615 | if (column) |
13616 | *column = tmp_column; |
13617 | |
13618 | if (cell_x) |
13619 | *cell_x = remaining_x; |
13620 | |
13621 | break; |
13622 | } |
13623 | remaining_x -= width; |
13624 | } |
13625 | |
13626 | /* If found is FALSE and there is a last_column, then it the remainder |
13627 | * space is in that area |
13628 | */ |
13629 | if (!found) |
13630 | { |
13631 | if (last_column) |
13632 | { |
13633 | if (column) |
13634 | *column = last_column; |
13635 | |
13636 | if (cell_x) |
13637 | *cell_x = ctk_tree_view_column_get_width (last_column) + remaining_x; |
13638 | } |
13639 | else |
13640 | { |
13641 | return FALSE(0); |
13642 | } |
13643 | } |
13644 | } |
13645 | |
13646 | y_offset = _ctk_rbtree_find_offset (tree_view->priv->tree, |
13647 | TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, y)((y) + tree_view->priv->dy), |
13648 | &tree, &node); |
13649 | |
13650 | if (tree == NULL((void*)0)) |
13651 | return FALSE(0); |
13652 | |
13653 | if (cell_y) |
13654 | *cell_y = y_offset; |
13655 | |
13656 | if (path) |
13657 | *path = _ctk_tree_path_new_from_rbtree (tree, node); |
13658 | |
13659 | return TRUE(!(0)); |
13660 | } |
13661 | |
13662 | |
13663 | static inline gint |
13664 | ctk_tree_view_get_cell_area_height (CtkTreeView *tree_view, |
13665 | CtkRBNode *node, |
13666 | gint vertical_separator) |
13667 | { |
13668 | int expander_size = ctk_tree_view_get_expander_size (tree_view); |
13669 | int height; |
13670 | |
13671 | /* The "cell" areas are the cell_area passed in to ctk_cell_renderer_render(), |
13672 | * i.e. just the cells, no spacing. |
13673 | * |
13674 | * The cell area height is at least expander_size - vertical_separator. |
13675 | * For regular nodes, the height is then at least expander_size. We should |
13676 | * be able to enforce the expander_size minimum here, because this |
13677 | * function will not be called for irregular (e.g. separator) rows. |
13678 | */ |
13679 | height = ctk_tree_view_get_row_height (tree_view, node); |
13680 | if (height < expander_size) |
13681 | height = expander_size; |
13682 | |
13683 | return height - vertical_separator; |
13684 | } |
13685 | |
13686 | static inline gint |
13687 | ctk_tree_view_get_cell_area_y_offset (CtkTreeView *tree_view, |
13688 | CtkRBTree *tree, |
13689 | CtkRBNode *node, |
13690 | gint vertical_separator) |
13691 | { |
13692 | int offset; |
13693 | |
13694 | offset = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
13695 | offset += vertical_separator / 2; |
13696 | |
13697 | return offset; |
13698 | } |
13699 | |
13700 | /** |
13701 | * ctk_tree_view_get_cell_area: |
13702 | * @tree_view: a #CtkTreeView |
13703 | * @path: (allow-none): a #CtkTreePath for the row, or %NULL to get only horizontal coordinates |
13704 | * @column: (allow-none): a #CtkTreeViewColumn for the column, or %NULL to get only vertical coordinates |
13705 | * @rect: (out): rectangle to fill with cell rect |
13706 | * |
13707 | * Fills the bounding rectangle in bin_window coordinates for the cell at the |
13708 | * row specified by @path and the column specified by @column. If @path is |
13709 | * %NULL, or points to a path not currently displayed, the @y and @height fields |
13710 | * of the rectangle will be filled with 0. If @column is %NULL, the @x and @width |
13711 | * fields will be filled with 0. The sum of all cell rects does not cover the |
13712 | * entire tree; there are extra pixels in between rows, for example. The |
13713 | * returned rectangle is equivalent to the @cell_area passed to |
13714 | * ctk_cell_renderer_render(). This function is only valid if @tree_view is |
13715 | * realized. |
13716 | **/ |
13717 | void |
13718 | ctk_tree_view_get_cell_area (CtkTreeView *tree_view, |
13719 | CtkTreePath *path, |
13720 | CtkTreeViewColumn *column, |
13721 | CdkRectangle *rect) |
13722 | { |
13723 | CtkRBTree *tree = NULL((void*)0); |
13724 | CtkRBNode *node = NULL((void*)0); |
13725 | gint vertical_separator; |
13726 | gint horizontal_separator; |
13727 | |
13728 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13729 | g_return_if_fail (column == NULL || CTK_IS_TREE_VIEW_COLUMN (column))do { if ((column == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((column)); GType __t = ((ctk_tree_view_column_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column == NULL || CTK_IS_TREE_VIEW_COLUMN (column)" ); return; } } while (0); |
13730 | g_return_if_fail (rect != NULL)do { if ((rect != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "rect != NULL"); return; } } while (0); |
13731 | g_return_if_fail (!column || ctk_tree_view_column_get_tree_view (column) == (CtkWidget *) tree_view)do { if ((!column || ctk_tree_view_column_get_tree_view (column ) == (CtkWidget *) tree_view)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "!column || ctk_tree_view_column_get_tree_view (column) == (CtkWidget *) tree_view" ); return; } } while (0); |
13732 | g_return_if_fail (ctk_widget_get_realized (CTK_WIDGET (tree_view)))do { if ((ctk_widget_get_realized (((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((tree_view)), ((ctk_widget_get_type ()))) )))))) { } else { g_return_if_fail_warning ("Ctk", ((const char *) (__func__)), "ctk_widget_get_realized (CTK_WIDGET (tree_view))" ); return; } } while (0); |
13733 | |
13734 | ctk_widget_style_get (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
13735 | "vertical-separator", &vertical_separator, |
13736 | "horizontal-separator", &horizontal_separator, |
13737 | NULL((void*)0)); |
13738 | |
13739 | rect->x = 0; |
13740 | rect->y = 0; |
13741 | rect->width = 0; |
13742 | rect->height = 0; |
13743 | |
13744 | if (column) |
13745 | { |
13746 | rect->x = ctk_tree_view_column_get_x_offset (column) + horizontal_separator/2; |
13747 | rect->width = ctk_tree_view_column_get_width (column) - horizontal_separator; |
13748 | } |
13749 | |
13750 | if (path) |
13751 | { |
13752 | gboolean ret = _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
13753 | |
13754 | /* Get vertical coords */ |
13755 | if ((!ret && tree == NULL((void*)0)) || ret) |
13756 | return; |
13757 | |
13758 | if (row_is_separator (tree_view, NULL((void*)0), path)) |
13759 | { |
13760 | /* There isn't really a "cell area" for separator, so we |
13761 | * return the y, height values for background area instead. |
13762 | */ |
13763 | rect->y = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
13764 | rect->height = ctk_tree_view_get_row_height (tree_view, node); |
13765 | } |
13766 | else |
13767 | { |
13768 | rect->y = ctk_tree_view_get_cell_area_y_offset (tree_view, tree, node, |
13769 | vertical_separator); |
13770 | rect->height = ctk_tree_view_get_cell_area_height (tree_view, node, |
13771 | vertical_separator); |
13772 | } |
13773 | |
13774 | if (column && |
13775 | ctk_tree_view_is_expander_column (tree_view, column)) |
13776 | { |
13777 | gint depth = ctk_tree_path_get_depth (path); |
13778 | gboolean rtl; |
13779 | |
13780 | rtl = ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL; |
13781 | |
13782 | if (!rtl) |
13783 | rect->x += (depth - 1) * tree_view->priv->level_indentation; |
13784 | rect->width -= (depth - 1) * tree_view->priv->level_indentation; |
13785 | |
13786 | if (ctk_tree_view_draw_expanders (tree_view)) |
13787 | { |
13788 | int expander_size = ctk_tree_view_get_expander_size (tree_view); |
13789 | if (!rtl) |
13790 | rect->x += depth * expander_size; |
13791 | rect->width -= depth * expander_size; |
13792 | } |
13793 | |
13794 | rect->width = MAX (rect->width, 0)(((rect->width) > (0)) ? (rect->width) : (0)); |
13795 | } |
13796 | } |
13797 | } |
13798 | |
13799 | static inline gint |
13800 | ctk_tree_view_get_row_height (CtkTreeView *tree_view, |
13801 | CtkRBNode *node) |
13802 | { |
13803 | int expander_size = ctk_tree_view_get_expander_size (tree_view); |
13804 | int height; |
13805 | |
13806 | /* The "background" areas of all rows/cells add up to cover the entire tree. |
13807 | * The background includes all inter-row and inter-cell spacing. |
13808 | * |
13809 | * If the row pointed at by node does not have a height set, we default |
13810 | * to expander_size, which is the minimum height for regular nodes. |
13811 | * Non-regular nodes (e.g. separators) can have a height set smaller |
13812 | * than expander_size and should not be overruled here. |
13813 | */ |
13814 | height = CTK_RBNODE_GET_HEIGHT (node)(node->offset-(node->left->offset+node->right-> offset+(node->children?node->children->root->offset :0))); |
13815 | if (height <= 0) |
13816 | height = expander_size; |
13817 | |
13818 | return height; |
13819 | } |
13820 | |
13821 | static inline gint |
13822 | ctk_tree_view_get_row_y_offset (CtkTreeView *tree_view, |
13823 | CtkRBTree *tree, |
13824 | CtkRBNode *node) |
13825 | { |
13826 | int offset; |
13827 | |
13828 | offset = _ctk_rbtree_node_find_offset (tree, node); |
13829 | |
13830 | return RBTREE_Y_TO_TREE_WINDOW_Y (tree_view, offset)((offset) - tree_view->priv->dy); |
13831 | } |
13832 | |
13833 | /** |
13834 | * ctk_tree_view_get_background_area: |
13835 | * @tree_view: a #CtkTreeView |
13836 | * @path: (allow-none): a #CtkTreePath for the row, or %NULL to get only horizontal coordinates |
13837 | * @column: (allow-none): a #CtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes |
13838 | * @rect: (out): rectangle to fill with cell background rect |
13839 | * |
13840 | * Fills the bounding rectangle in bin_window coordinates for the cell at the |
13841 | * row specified by @path and the column specified by @column. If @path is |
13842 | * %NULL, or points to a node not found in the tree, the @y and @height fields of |
13843 | * the rectangle will be filled with 0. If @column is %NULL, the @x and @width |
13844 | * fields will be filled with 0. The returned rectangle is equivalent to the |
13845 | * @background_area passed to ctk_cell_renderer_render(). These background |
13846 | * areas tile to cover the entire bin window. Contrast with the @cell_area, |
13847 | * returned by ctk_tree_view_get_cell_area(), which returns only the cell |
13848 | * itself, excluding surrounding borders and the tree expander area. |
13849 | * |
13850 | **/ |
13851 | void |
13852 | ctk_tree_view_get_background_area (CtkTreeView *tree_view, |
13853 | CtkTreePath *path, |
13854 | CtkTreeViewColumn *column, |
13855 | CdkRectangle *rect) |
13856 | { |
13857 | CtkRBTree *tree = NULL((void*)0); |
13858 | CtkRBNode *node = NULL((void*)0); |
13859 | |
13860 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13861 | g_return_if_fail (column == NULL || CTK_IS_TREE_VIEW_COLUMN (column))do { if ((column == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((column)); GType __t = ((ctk_tree_view_column_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column == NULL || CTK_IS_TREE_VIEW_COLUMN (column)" ); return; } } while (0); |
13862 | g_return_if_fail (rect != NULL)do { if ((rect != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "rect != NULL"); return; } } while (0); |
13863 | |
13864 | rect->x = 0; |
13865 | rect->y = 0; |
13866 | rect->width = 0; |
13867 | rect->height = 0; |
13868 | |
13869 | if (path) |
13870 | { |
13871 | /* Get vertical coords */ |
13872 | |
13873 | if (!_ctk_tree_view_find_node (tree_view, path, &tree, &node) && |
13874 | tree == NULL((void*)0)) |
13875 | return; |
13876 | |
13877 | rect->y = ctk_tree_view_get_row_y_offset (tree_view, tree, node); |
13878 | rect->height = ctk_tree_view_get_row_height (tree_view, node); |
13879 | } |
13880 | |
13881 | if (column) |
13882 | { |
13883 | gint x2 = 0; |
13884 | |
13885 | ctk_tree_view_get_background_xrange (tree_view, tree, column, &rect->x, &x2); |
13886 | rect->width = x2 - rect->x; |
13887 | } |
13888 | } |
13889 | |
13890 | /** |
13891 | * ctk_tree_view_get_visible_rect: |
13892 | * @tree_view: a #CtkTreeView |
13893 | * @visible_rect: (out): rectangle to fill |
13894 | * |
13895 | * Fills @visible_rect with the currently-visible region of the |
13896 | * buffer, in tree coordinates. Convert to bin_window coordinates with |
13897 | * ctk_tree_view_convert_tree_to_bin_window_coords(). |
13898 | * Tree coordinates start at 0,0 for row 0 of the tree, and cover the entire |
13899 | * scrollable area of the tree. |
13900 | **/ |
13901 | void |
13902 | ctk_tree_view_get_visible_rect (CtkTreeView *tree_view, |
13903 | CdkRectangle *visible_rect) |
13904 | { |
13905 | CtkAllocation allocation; |
13906 | CtkWidget *widget; |
13907 | |
13908 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13909 | |
13910 | widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
13911 | |
13912 | if (visible_rect) |
13913 | { |
13914 | ctk_widget_get_allocation (widget, &allocation); |
13915 | visible_rect->x = ctk_adjustment_get_value (tree_view->priv->hadjustment); |
13916 | visible_rect->y = ctk_adjustment_get_value (tree_view->priv->vadjustment); |
13917 | visible_rect->width = allocation.width; |
13918 | visible_rect->height = allocation.height - ctk_tree_view_get_effective_header_height (tree_view); |
13919 | } |
13920 | } |
13921 | |
13922 | /** |
13923 | * ctk_tree_view_convert_widget_to_tree_coords: |
13924 | * @tree_view: a #CtkTreeView |
13925 | * @wx: X coordinate relative to the widget |
13926 | * @wy: Y coordinate relative to the widget |
13927 | * @tx: (out): return location for tree X coordinate |
13928 | * @ty: (out): return location for tree Y coordinate |
13929 | * |
13930 | * Converts widget coordinates to coordinates for the |
13931 | * tree (the full scrollable area of the tree). |
13932 | * |
13933 | * Since: 2.12 |
13934 | **/ |
13935 | void |
13936 | ctk_tree_view_convert_widget_to_tree_coords (CtkTreeView *tree_view, |
13937 | gint wx, |
13938 | gint wy, |
13939 | gint *tx, |
13940 | gint *ty) |
13941 | { |
13942 | gint x, y; |
13943 | |
13944 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13945 | |
13946 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, |
13947 | wx, wy, |
13948 | &x, &y); |
13949 | ctk_tree_view_convert_bin_window_to_tree_coords (tree_view, |
13950 | x, y, |
13951 | tx, ty); |
13952 | } |
13953 | |
13954 | /** |
13955 | * ctk_tree_view_convert_tree_to_widget_coords: |
13956 | * @tree_view: a #CtkTreeView |
13957 | * @tx: X coordinate relative to the tree |
13958 | * @ty: Y coordinate relative to the tree |
13959 | * @wx: (out): return location for widget X coordinate |
13960 | * @wy: (out): return location for widget Y coordinate |
13961 | * |
13962 | * Converts tree coordinates (coordinates in full scrollable area of the tree) |
13963 | * to widget coordinates. |
13964 | * |
13965 | * Since: 2.12 |
13966 | **/ |
13967 | void |
13968 | ctk_tree_view_convert_tree_to_widget_coords (CtkTreeView *tree_view, |
13969 | gint tx, |
13970 | gint ty, |
13971 | gint *wx, |
13972 | gint *wy) |
13973 | { |
13974 | gint x, y; |
13975 | |
13976 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
13977 | |
13978 | ctk_tree_view_convert_tree_to_bin_window_coords (tree_view, |
13979 | tx, ty, |
13980 | &x, &y); |
13981 | ctk_tree_view_convert_bin_window_to_widget_coords (tree_view, |
13982 | x, y, |
13983 | wx, wy); |
13984 | } |
13985 | |
13986 | /** |
13987 | * ctk_tree_view_convert_widget_to_bin_window_coords: |
13988 | * @tree_view: a #CtkTreeView |
13989 | * @wx: X coordinate relative to the widget |
13990 | * @wy: Y coordinate relative to the widget |
13991 | * @bx: (out): return location for bin_window X coordinate |
13992 | * @by: (out): return location for bin_window Y coordinate |
13993 | * |
13994 | * Converts widget coordinates to coordinates for the bin_window |
13995 | * (see ctk_tree_view_get_bin_window()). |
13996 | * |
13997 | * Since: 2.12 |
13998 | **/ |
13999 | void |
14000 | ctk_tree_view_convert_widget_to_bin_window_coords (CtkTreeView *tree_view, |
14001 | gint wx, |
14002 | gint wy, |
14003 | gint *bx, |
14004 | gint *by) |
14005 | { |
14006 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14007 | |
14008 | if (bx) |
14009 | *bx = wx + ctk_adjustment_get_value (tree_view->priv->hadjustment); |
14010 | if (by) |
14011 | *by = wy - ctk_tree_view_get_effective_header_height (tree_view); |
14012 | } |
14013 | |
14014 | /** |
14015 | * ctk_tree_view_convert_bin_window_to_widget_coords: |
14016 | * @tree_view: a #CtkTreeView |
14017 | * @bx: bin_window X coordinate |
14018 | * @by: bin_window Y coordinate |
14019 | * @wx: (out): return location for widget X coordinate |
14020 | * @wy: (out): return location for widget Y coordinate |
14021 | * |
14022 | * Converts bin_window coordinates (see ctk_tree_view_get_bin_window()) |
14023 | * to widget relative coordinates. |
14024 | * |
14025 | * Since: 2.12 |
14026 | **/ |
14027 | void |
14028 | ctk_tree_view_convert_bin_window_to_widget_coords (CtkTreeView *tree_view, |
14029 | gint bx, |
14030 | gint by, |
14031 | gint *wx, |
14032 | gint *wy) |
14033 | { |
14034 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14035 | |
14036 | if (wx) |
14037 | *wx = bx - ctk_adjustment_get_value (tree_view->priv->hadjustment); |
14038 | if (wy) |
14039 | *wy = by + ctk_tree_view_get_effective_header_height (tree_view); |
14040 | } |
14041 | |
14042 | /** |
14043 | * ctk_tree_view_convert_tree_to_bin_window_coords: |
14044 | * @tree_view: a #CtkTreeView |
14045 | * @tx: tree X coordinate |
14046 | * @ty: tree Y coordinate |
14047 | * @bx: (out): return location for X coordinate relative to bin_window |
14048 | * @by: (out): return location for Y coordinate relative to bin_window |
14049 | * |
14050 | * Converts tree coordinates (coordinates in full scrollable area of the tree) |
14051 | * to bin_window coordinates. |
14052 | * |
14053 | * Since: 2.12 |
14054 | **/ |
14055 | void |
14056 | ctk_tree_view_convert_tree_to_bin_window_coords (CtkTreeView *tree_view, |
14057 | gint tx, |
14058 | gint ty, |
14059 | gint *bx, |
14060 | gint *by) |
14061 | { |
14062 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14063 | |
14064 | if (bx) |
14065 | *bx = tx; |
14066 | if (by) |
14067 | *by = ty - tree_view->priv->dy; |
14068 | } |
14069 | |
14070 | /** |
14071 | * ctk_tree_view_convert_bin_window_to_tree_coords: |
14072 | * @tree_view: a #CtkTreeView |
14073 | * @bx: X coordinate relative to bin_window |
14074 | * @by: Y coordinate relative to bin_window |
14075 | * @tx: (out): return location for tree X coordinate |
14076 | * @ty: (out): return location for tree Y coordinate |
14077 | * |
14078 | * Converts bin_window coordinates to coordinates for the |
14079 | * tree (the full scrollable area of the tree). |
14080 | * |
14081 | * Since: 2.12 |
14082 | **/ |
14083 | void |
14084 | ctk_tree_view_convert_bin_window_to_tree_coords (CtkTreeView *tree_view, |
14085 | gint bx, |
14086 | gint by, |
14087 | gint *tx, |
14088 | gint *ty) |
14089 | { |
14090 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14091 | |
14092 | if (tx) |
14093 | *tx = bx; |
14094 | if (ty) |
14095 | *ty = by + tree_view->priv->dy; |
14096 | } |
14097 | |
14098 | |
14099 | |
14100 | /** |
14101 | * ctk_tree_view_get_visible_range: |
14102 | * @tree_view: A #CtkTreeView |
14103 | * @start_path: (out) (allow-none): Return location for start of region, |
14104 | * or %NULL. |
14105 | * @end_path: (out) (allow-none): Return location for end of region, or %NULL. |
14106 | * |
14107 | * Sets @start_path and @end_path to be the first and last visible path. |
14108 | * Note that there may be invisible paths in between. |
14109 | * |
14110 | * The paths should be freed with ctk_tree_path_free() after use. |
14111 | * |
14112 | * Returns: %TRUE, if valid paths were placed in @start_path and @end_path. |
14113 | * |
14114 | * Since: 2.8 |
14115 | **/ |
14116 | gboolean |
14117 | ctk_tree_view_get_visible_range (CtkTreeView *tree_view, |
14118 | CtkTreePath **start_path, |
14119 | CtkTreePath **end_path) |
14120 | { |
14121 | CtkRBTree *tree; |
14122 | CtkRBNode *node; |
14123 | gboolean retval; |
14124 | |
14125 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
14126 | |
14127 | if (!tree_view->priv->tree) |
14128 | return FALSE(0); |
14129 | |
14130 | retval = TRUE(!(0)); |
14131 | |
14132 | if (start_path) |
14133 | { |
14134 | _ctk_rbtree_find_offset (tree_view->priv->tree, |
14135 | TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, 0)((0) + tree_view->priv->dy), |
14136 | &tree, &node); |
14137 | if (node) |
14138 | *start_path = _ctk_tree_path_new_from_rbtree (tree, node); |
14139 | else |
14140 | retval = FALSE(0); |
14141 | } |
14142 | |
14143 | if (end_path) |
14144 | { |
14145 | gint y; |
14146 | |
14147 | if (ctk_tree_view_get_height (tree_view) < ctk_adjustment_get_page_size (tree_view->priv->vadjustment)) |
14148 | y = ctk_tree_view_get_height (tree_view) - 1; |
14149 | else |
14150 | y = TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, ctk_adjustment_get_page_size (tree_view->priv->vadjustment))((ctk_adjustment_get_page_size (tree_view->priv->vadjustment )) + tree_view->priv->dy) - 1; |
14151 | |
14152 | _ctk_rbtree_find_offset (tree_view->priv->tree, y, &tree, &node); |
14153 | if (node) |
14154 | *end_path = _ctk_tree_path_new_from_rbtree (tree, node); |
14155 | else |
14156 | retval = FALSE(0); |
14157 | } |
14158 | |
14159 | return retval; |
14160 | } |
14161 | |
14162 | /** |
14163 | * ctk_tree_view_is_blank_at_pos: |
14164 | * @tree_view: A #CtkTreeView |
14165 | * @x: The x position to be identified (relative to bin_window) |
14166 | * @y: The y position to be identified (relative to bin_window) |
14167 | * @path: (out) (optional) (nullable): A pointer to a #CtkTreePath pointer to |
14168 | * be filled in, or %NULL |
14169 | * @column: (out) (transfer none) (optional) (nullable): A pointer to a |
14170 | * #CtkTreeViewColumn pointer to be filled in, or %NULL |
14171 | * @cell_x: (out) (optional): A pointer where the X coordinate relative to the |
14172 | * cell can be placed, or %NULL |
14173 | * @cell_y: (out) (optional): A pointer where the Y coordinate relative to the |
14174 | * cell can be placed, or %NULL |
14175 | * |
14176 | * Determine whether the point (@x, @y) in @tree_view is blank, that is no |
14177 | * cell content nor an expander arrow is drawn at the location. If so, the |
14178 | * location can be considered as the background. You might wish to take |
14179 | * special action on clicks on the background, such as clearing a current |
14180 | * selection, having a custom context menu or starting rubber banding. |
14181 | * |
14182 | * The @x and @y coordinate that are provided must be relative to bin_window |
14183 | * coordinates. That is, @x and @y must come from an event on @tree_view |
14184 | * where `event->window == ctk_tree_view_get_bin_window ()`. |
14185 | * |
14186 | * For converting widget coordinates (eg. the ones you get from |
14187 | * CtkWidget::query-tooltip), please see |
14188 | * ctk_tree_view_convert_widget_to_bin_window_coords(). |
14189 | * |
14190 | * The @path, @column, @cell_x and @cell_y arguments will be filled in |
14191 | * likewise as for ctk_tree_view_get_path_at_pos(). Please see |
14192 | * ctk_tree_view_get_path_at_pos() for more information. |
14193 | * |
14194 | * Returns: %TRUE if the area at the given coordinates is blank, |
14195 | * %FALSE otherwise. |
14196 | * |
14197 | * Since: 3.0 |
14198 | */ |
14199 | gboolean |
14200 | ctk_tree_view_is_blank_at_pos (CtkTreeView *tree_view, |
14201 | gint x, |
14202 | gint y, |
14203 | CtkTreePath **path, |
14204 | CtkTreeViewColumn **column, |
14205 | gint *cell_x, |
14206 | gint *cell_y) |
14207 | { |
14208 | CtkRBTree *tree; |
14209 | CtkRBNode *node; |
14210 | CtkTreeIter iter; |
14211 | CtkTreePath *real_path; |
14212 | CtkTreeViewColumn *real_column; |
14213 | CdkRectangle cell_area, background_area; |
14214 | |
14215 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
14216 | |
14217 | if (!ctk_tree_view_get_path_at_pos (tree_view, x, y, |
14218 | &real_path, &real_column, |
14219 | cell_x, cell_y)) |
14220 | /* If there's no path here, it is blank */ |
14221 | return TRUE(!(0)); |
14222 | |
14223 | if (path) |
14224 | *path = real_path; |
14225 | |
14226 | if (column) |
14227 | *column = real_column; |
14228 | |
14229 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, real_path); |
14230 | _ctk_tree_view_find_node (tree_view, real_path, &tree, &node); |
14231 | |
14232 | /* Check if there's an expander arrow at (x, y) */ |
14233 | if (real_column == tree_view->priv->expander_column |
14234 | && ctk_tree_view_draw_expanders (tree_view)) |
14235 | { |
14236 | gboolean over_arrow; |
14237 | |
14238 | over_arrow = coords_are_over_arrow (tree_view, tree, node, x, y); |
14239 | |
14240 | if (over_arrow) |
14241 | { |
14242 | if (!path) |
14243 | ctk_tree_path_free (real_path); |
14244 | return FALSE(0); |
14245 | } |
14246 | } |
14247 | |
14248 | /* Otherwise, have the column see if there's a cell at (x, y) */ |
14249 | ctk_tree_view_column_cell_set_cell_data (real_column, |
14250 | tree_view->priv->model, |
14251 | &iter, |
14252 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
14253 | node->children ? TRUE(!(0)) : FALSE(0)); |
14254 | |
14255 | ctk_tree_view_get_background_area (tree_view, real_path, real_column, |
14256 | &background_area); |
14257 | ctk_tree_view_get_cell_area (tree_view, real_path, real_column, |
14258 | &cell_area); |
14259 | |
14260 | if (!path) |
14261 | ctk_tree_path_free (real_path); |
14262 | |
14263 | return _ctk_tree_view_column_is_blank_at_pos (real_column, |
14264 | &cell_area, |
14265 | &background_area, |
14266 | x, y); |
14267 | } |
14268 | |
14269 | static void |
14270 | unset_reorderable (CtkTreeView *tree_view) |
14271 | { |
14272 | if (tree_view->priv->reorderable) |
14273 | { |
14274 | tree_view->priv->reorderable = FALSE(0); |
14275 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_REORDERABLE]); |
14276 | } |
14277 | } |
14278 | |
14279 | /** |
14280 | * ctk_tree_view_enable_model_drag_source: |
14281 | * @tree_view: a #CtkTreeView |
14282 | * @start_button_mask: Mask of allowed buttons to start drag |
14283 | * @targets: (array length=n_targets): the table of targets that the drag will support |
14284 | * @n_targets: the number of items in @targets |
14285 | * @actions: the bitmask of possible actions for a drag from this |
14286 | * widget |
14287 | * |
14288 | * Turns @tree_view into a drag source for automatic DND. Calling this |
14289 | * method sets #CtkTreeView:reorderable to %FALSE. |
14290 | **/ |
14291 | void |
14292 | ctk_tree_view_enable_model_drag_source (CtkTreeView *tree_view, |
14293 | CdkModifierType start_button_mask, |
14294 | const CtkTargetEntry *targets, |
14295 | gint n_targets, |
14296 | CdkDragAction actions) |
14297 | { |
14298 | TreeViewDragInfo *di; |
14299 | |
14300 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14301 | |
14302 | ctk_drag_source_set (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
14303 | 0, |
14304 | targets, |
14305 | n_targets, |
14306 | actions); |
14307 | |
14308 | di = ensure_info (tree_view); |
14309 | |
14310 | di->start_button_mask = start_button_mask; |
14311 | di->source_actions = actions; |
14312 | di->source_set = TRUE(!(0)); |
14313 | |
14314 | unset_reorderable (tree_view); |
14315 | } |
14316 | |
14317 | /** |
14318 | * ctk_tree_view_enable_model_drag_dest: |
14319 | * @tree_view: a #CtkTreeView |
14320 | * @targets: (array length=n_targets): the table of targets that |
14321 | * the drag will support |
14322 | * @n_targets: the number of items in @targets |
14323 | * @actions: the bitmask of possible actions for a drag from this |
14324 | * widget |
14325 | * |
14326 | * Turns @tree_view into a drop destination for automatic DND. Calling |
14327 | * this method sets #CtkTreeView:reorderable to %FALSE. |
14328 | **/ |
14329 | void |
14330 | ctk_tree_view_enable_model_drag_dest (CtkTreeView *tree_view, |
14331 | const CtkTargetEntry *targets, |
14332 | gint n_targets, |
14333 | CdkDragAction actions) |
14334 | { |
14335 | TreeViewDragInfo *di; |
14336 | |
14337 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14338 | |
14339 | ctk_drag_dest_set (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
14340 | 0, |
14341 | targets, |
14342 | n_targets, |
14343 | actions); |
14344 | |
14345 | di = ensure_info (tree_view); |
14346 | di->dest_set = TRUE(!(0)); |
14347 | |
14348 | unset_reorderable (tree_view); |
14349 | } |
14350 | |
14351 | /** |
14352 | * ctk_tree_view_unset_rows_drag_source: |
14353 | * @tree_view: a #CtkTreeView |
14354 | * |
14355 | * Undoes the effect of |
14356 | * ctk_tree_view_enable_model_drag_source(). Calling this method sets |
14357 | * #CtkTreeView:reorderable to %FALSE. |
14358 | **/ |
14359 | void |
14360 | ctk_tree_view_unset_rows_drag_source (CtkTreeView *tree_view) |
14361 | { |
14362 | TreeViewDragInfo *di; |
14363 | |
14364 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14365 | |
14366 | di = get_info (tree_view); |
14367 | |
14368 | if (di) |
14369 | { |
14370 | if (di->source_set) |
14371 | { |
14372 | ctk_drag_source_unset (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
14373 | di->source_set = FALSE(0); |
14374 | } |
14375 | |
14376 | if (!di->dest_set && !di->source_set) |
14377 | remove_info (tree_view); |
14378 | } |
14379 | |
14380 | unset_reorderable (tree_view); |
14381 | } |
14382 | |
14383 | /** |
14384 | * ctk_tree_view_unset_rows_drag_dest: |
14385 | * @tree_view: a #CtkTreeView |
14386 | * |
14387 | * Undoes the effect of |
14388 | * ctk_tree_view_enable_model_drag_dest(). Calling this method sets |
14389 | * #CtkTreeView:reorderable to %FALSE. |
14390 | **/ |
14391 | void |
14392 | ctk_tree_view_unset_rows_drag_dest (CtkTreeView *tree_view) |
14393 | { |
14394 | TreeViewDragInfo *di; |
14395 | |
14396 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14397 | |
14398 | di = get_info (tree_view); |
14399 | |
14400 | if (di) |
14401 | { |
14402 | if (di->dest_set) |
14403 | { |
14404 | ctk_drag_dest_unset (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
14405 | di->dest_set = FALSE(0); |
14406 | } |
14407 | |
14408 | if (!di->dest_set && !di->source_set) |
14409 | remove_info (tree_view); |
14410 | } |
14411 | |
14412 | unset_reorderable (tree_view); |
14413 | } |
14414 | |
14415 | /** |
14416 | * ctk_tree_view_set_drag_dest_row: |
14417 | * @tree_view: a #CtkTreeView |
14418 | * @path: (allow-none): The path of the row to highlight, or %NULL |
14419 | * @pos: Specifies whether to drop before, after or into the row |
14420 | * |
14421 | * Sets the row that is highlighted for feedback. |
14422 | * If @path is %NULL, an existing highlight is removed. |
14423 | */ |
14424 | void |
14425 | ctk_tree_view_set_drag_dest_row (CtkTreeView *tree_view, |
14426 | CtkTreePath *path, |
14427 | CtkTreeViewDropPosition pos) |
14428 | { |
14429 | CtkTreePath *current_dest; |
14430 | |
14431 | /* Note; this function is exported to allow a custom DND |
14432 | * implementation, so it can't touch TreeViewDragInfo |
14433 | */ |
14434 | |
14435 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14436 | |
14437 | current_dest = NULL((void*)0); |
14438 | |
14439 | if (tree_view->priv->drag_dest_row) |
14440 | { |
14441 | current_dest = ctk_tree_row_reference_get_path (tree_view->priv->drag_dest_row); |
14442 | ctk_tree_row_reference_free (tree_view->priv->drag_dest_row); |
14443 | } |
14444 | |
14445 | /* special case a drop on an empty model */ |
14446 | tree_view->priv->empty_view_drop = 0; |
14447 | |
14448 | if (pos == CTK_TREE_VIEW_DROP_BEFORE && path |
14449 | && ctk_tree_path_get_depth (path) == 1 |
14450 | && ctk_tree_path_get_indices (path)[0] == 0) |
14451 | { |
14452 | gint n_children; |
14453 | |
14454 | n_children = ctk_tree_model_iter_n_children (tree_view->priv->model, |
14455 | NULL((void*)0)); |
14456 | |
14457 | if (!n_children) |
14458 | tree_view->priv->empty_view_drop = 1; |
14459 | } |
14460 | |
14461 | tree_view->priv->drag_dest_pos = pos; |
14462 | |
14463 | if (path) |
14464 | { |
14465 | tree_view->priv->drag_dest_row = |
14466 | ctk_tree_row_reference_new_proxy (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view->priv->model, path); |
14467 | ctk_tree_view_queue_draw_path (tree_view, path, NULL((void*)0)); |
14468 | } |
14469 | else |
14470 | tree_view->priv->drag_dest_row = NULL((void*)0); |
14471 | |
14472 | if (current_dest) |
14473 | { |
14474 | CtkRBTree *tree, *new_tree; |
14475 | CtkRBNode *node, *new_node; |
14476 | |
14477 | _ctk_tree_view_find_node (tree_view, current_dest, &tree, &node); |
14478 | _ctk_tree_view_queue_draw_node (tree_view, tree, node, NULL((void*)0)); |
14479 | |
14480 | if (tree && node) |
14481 | { |
14482 | _ctk_rbtree_next_full (tree, node, &new_tree, &new_node); |
14483 | if (new_tree && new_node) |
14484 | _ctk_tree_view_queue_draw_node (tree_view, new_tree, new_node, NULL((void*)0)); |
14485 | |
14486 | _ctk_rbtree_prev_full (tree, node, &new_tree, &new_node); |
14487 | if (new_tree && new_node) |
14488 | _ctk_tree_view_queue_draw_node (tree_view, new_tree, new_node, NULL((void*)0)); |
14489 | } |
14490 | ctk_tree_path_free (current_dest); |
14491 | } |
14492 | } |
14493 | |
14494 | /** |
14495 | * ctk_tree_view_get_drag_dest_row: |
14496 | * @tree_view: a #CtkTreeView |
14497 | * @path: (out) (optional) (nullable): Return location for the path of the highlighted row, or %NULL. |
14498 | * @pos: (out) (optional): Return location for the drop position, or %NULL |
14499 | * |
14500 | * Gets information about the row that is highlighted for feedback. |
14501 | **/ |
14502 | void |
14503 | ctk_tree_view_get_drag_dest_row (CtkTreeView *tree_view, |
14504 | CtkTreePath **path, |
14505 | CtkTreeViewDropPosition *pos) |
14506 | { |
14507 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14508 | |
14509 | if (path) |
14510 | { |
14511 | if (tree_view->priv->drag_dest_row) |
14512 | *path = ctk_tree_row_reference_get_path (tree_view->priv->drag_dest_row); |
14513 | else |
14514 | { |
14515 | if (tree_view->priv->empty_view_drop) |
14516 | *path = ctk_tree_path_new_from_indices (0, -1); |
14517 | else |
14518 | *path = NULL((void*)0); |
14519 | } |
14520 | } |
14521 | |
14522 | if (pos) |
14523 | *pos = tree_view->priv->drag_dest_pos; |
14524 | } |
14525 | |
14526 | /** |
14527 | * ctk_tree_view_get_dest_row_at_pos: |
14528 | * @tree_view: a #CtkTreeView |
14529 | * @drag_x: the position to determine the destination row for |
14530 | * @drag_y: the position to determine the destination row for |
14531 | * @path: (out) (optional) (nullable): Return location for the path of |
14532 | * the highlighted row, or %NULL. |
14533 | * @pos: (out) (optional): Return location for the drop position, or |
14534 | * %NULL |
14535 | * |
14536 | * Determines the destination row for a given position. @drag_x and |
14537 | * @drag_y are expected to be in widget coordinates. This function is only |
14538 | * meaningful if @tree_view is realized. Therefore this function will always |
14539 | * return %FALSE if @tree_view is not realized or does not have a model. |
14540 | * |
14541 | * Returns: whether there is a row at the given position, %TRUE if this |
14542 | * is indeed the case. |
14543 | **/ |
14544 | gboolean |
14545 | ctk_tree_view_get_dest_row_at_pos (CtkTreeView *tree_view, |
14546 | gint drag_x, |
14547 | gint drag_y, |
14548 | CtkTreePath **path, |
14549 | CtkTreeViewDropPosition *pos) |
14550 | { |
14551 | gint cell_y; |
14552 | gint bin_x, bin_y; |
14553 | gdouble offset_into_row; |
14554 | gdouble fourth; |
14555 | CdkRectangle cell; |
14556 | CtkTreeViewColumn *column = NULL((void*)0); |
14557 | CtkTreePath *tmp_path = NULL((void*)0); |
14558 | |
14559 | /* Note; this function is exported to allow a custom DND |
14560 | * implementation, so it can't touch TreeViewDragInfo |
14561 | */ |
14562 | |
14563 | g_return_val_if_fail (tree_view != NULL, FALSE)do { if ((tree_view != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "tree_view != NULL"); return ((0)); } } while (0); |
14564 | g_return_val_if_fail (drag_x >= 0, FALSE)do { if ((drag_x >= 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "drag_x >= 0"); return ((0)); } } while (0); |
14565 | g_return_val_if_fail (drag_y >= 0, FALSE)do { if ((drag_y >= 0)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "drag_y >= 0"); return ((0)); } } while (0); |
14566 | |
14567 | if (path) |
14568 | *path = NULL((void*)0); |
14569 | |
14570 | if (tree_view->priv->bin_window == NULL((void*)0)) |
14571 | return FALSE(0); |
14572 | |
14573 | if (tree_view->priv->tree == NULL((void*)0)) |
14574 | return FALSE(0); |
14575 | |
14576 | /* If in the top fourth of a row, we drop before that row; if |
14577 | * in the bottom fourth, drop after that row; if in the middle, |
14578 | * and the row has children, drop into the row. |
14579 | */ |
14580 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, drag_x, drag_y, |
14581 | &bin_x, &bin_y); |
14582 | |
14583 | if (!ctk_tree_view_get_path_at_pos (tree_view, |
14584 | bin_x, |
14585 | bin_y, |
14586 | &tmp_path, |
14587 | &column, |
14588 | NULL((void*)0), |
14589 | &cell_y)) |
14590 | return FALSE(0); |
14591 | |
14592 | ctk_tree_view_get_background_area (tree_view, tmp_path, column, |
14593 | &cell); |
14594 | |
14595 | offset_into_row = cell_y; |
14596 | |
14597 | if (path) |
14598 | *path = tmp_path; |
14599 | else |
14600 | ctk_tree_path_free (tmp_path); |
14601 | |
14602 | tmp_path = NULL((void*)0); |
14603 | |
14604 | fourth = cell.height / 4.0; |
14605 | |
14606 | if (pos) |
14607 | { |
14608 | if (offset_into_row < fourth) |
14609 | { |
14610 | *pos = CTK_TREE_VIEW_DROP_BEFORE; |
14611 | } |
14612 | else if (offset_into_row < (cell.height / 2.0)) |
14613 | { |
14614 | *pos = CTK_TREE_VIEW_DROP_INTO_OR_BEFORE; |
14615 | } |
14616 | else if (offset_into_row < cell.height - fourth) |
14617 | { |
14618 | *pos = CTK_TREE_VIEW_DROP_INTO_OR_AFTER; |
14619 | } |
14620 | else |
14621 | { |
14622 | *pos = CTK_TREE_VIEW_DROP_AFTER; |
14623 | } |
14624 | } |
14625 | |
14626 | return TRUE(!(0)); |
14627 | } |
14628 | |
14629 | |
14630 | |
14631 | /* KEEP IN SYNC WITH CTK_TREE_VIEW_BIN_EXPOSE */ |
14632 | /** |
14633 | * ctk_tree_view_create_row_drag_icon: |
14634 | * @tree_view: a #CtkTreeView |
14635 | * @path: a #CtkTreePath in @tree_view |
14636 | * |
14637 | * Creates a #cairo_surface_t representation of the row at @path. |
14638 | * This image is used for a drag icon. |
14639 | * |
14640 | * Returns: (transfer full): a newly-allocated surface of the drag icon. |
14641 | **/ |
14642 | cairo_surface_t * |
14643 | ctk_tree_view_create_row_drag_icon (CtkTreeView *tree_view, |
14644 | CtkTreePath *path) |
14645 | { |
14646 | CtkTreeIter iter; |
14647 | CtkRBTree *tree; |
14648 | CtkRBNode *node; |
14649 | CtkStyleContext *context; |
14650 | gint cell_offset; |
14651 | GList *list; |
14652 | CdkRectangle background_area; |
14653 | CtkWidget *widget; |
14654 | gint depth; |
14655 | /* start drawing inside the black outline */ |
14656 | gint x = 1, y = 1; |
14657 | cairo_surface_t *surface; |
14658 | gint bin_window_width; |
14659 | gboolean is_separator = FALSE(0); |
14660 | gboolean rtl; |
14661 | cairo_t *cr; |
14662 | |
14663 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
14664 | g_return_val_if_fail (path != NULL, NULL)do { if ((path != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "path != NULL"); return ( ((void*)0)); } } while (0); |
14665 | |
14666 | widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
14667 | |
14668 | if (!ctk_widget_get_realized (widget)) |
14669 | return NULL((void*)0); |
14670 | |
14671 | depth = ctk_tree_path_get_depth (path); |
14672 | |
14673 | _ctk_tree_view_find_node (tree_view, |
14674 | path, |
14675 | &tree, |
14676 | &node); |
14677 | |
14678 | if (tree == NULL((void*)0)) |
14679 | return NULL((void*)0); |
14680 | |
14681 | if (!ctk_tree_model_get_iter (tree_view->priv->model, |
14682 | &iter, |
14683 | path)) |
14684 | return NULL((void*)0); |
14685 | |
14686 | context = ctk_widget_get_style_context (widget); |
14687 | |
14688 | is_separator = row_is_separator (tree_view, &iter, NULL((void*)0)); |
14689 | |
14690 | cell_offset = x; |
14691 | |
14692 | background_area.y = y; |
14693 | background_area.height = ctk_tree_view_get_row_height (tree_view, node); |
14694 | |
14695 | bin_window_width = cdk_window_get_width (tree_view->priv->bin_window); |
14696 | |
14697 | surface = cdk_window_create_similar_surface (tree_view->priv->bin_window, |
14698 | CAIRO_CONTENT_COLOR, |
14699 | bin_window_width + 2, |
14700 | background_area.height + 2); |
14701 | |
14702 | cr = cairo_create (surface); |
14703 | |
14704 | ctk_render_background (context, cr, 0, 0, |
14705 | bin_window_width + 2, |
14706 | background_area.height + 2); |
14707 | |
14708 | rtl = ctk_widget_get_direction (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))) == CTK_TEXT_DIR_RTL; |
14709 | |
14710 | for (list = (rtl ? g_list_last (tree_view->priv->columns) : g_list_first (tree_view->priv->columns)); |
14711 | list; |
14712 | list = (rtl ? list->prev : list->next)) |
14713 | { |
14714 | CtkTreeViewColumn *column = list->data; |
14715 | CdkRectangle cell_area; |
14716 | gint vertical_separator; |
14717 | |
14718 | if (!ctk_tree_view_column_get_visible (column)) |
14719 | continue; |
14720 | |
14721 | ctk_tree_view_column_cell_set_cell_data (column, tree_view->priv->model, &iter, |
14722 | CTK_RBNODE_FLAG_SET (node, CTK_RBNODE_IS_PARENT)(node?(((node->flags&CTK_RBNODE_IS_PARENT)==CTK_RBNODE_IS_PARENT )?(!(0)):(0)):(0)), |
14723 | node->children?TRUE(!(0)):FALSE(0)); |
14724 | |
14725 | background_area.x = cell_offset; |
14726 | background_area.width = ctk_tree_view_column_get_width (column); |
14727 | |
14728 | ctk_widget_style_get (widget, |
14729 | "vertical-separator", &vertical_separator, |
14730 | NULL((void*)0)); |
14731 | |
14732 | cell_area = background_area; |
14733 | |
14734 | cell_area.y += vertical_separator / 2; |
14735 | cell_area.height -= vertical_separator; |
14736 | |
14737 | if (ctk_tree_view_is_expander_column (tree_view, column)) |
14738 | { |
14739 | if (!rtl) |
14740 | cell_area.x += (depth - 1) * tree_view->priv->level_indentation; |
14741 | cell_area.width -= (depth - 1) * tree_view->priv->level_indentation; |
14742 | |
14743 | if (ctk_tree_view_draw_expanders (tree_view)) |
14744 | { |
14745 | int expander_size = ctk_tree_view_get_expander_size (tree_view); |
14746 | if (!rtl) |
14747 | cell_area.x += depth * expander_size; |
14748 | cell_area.width -= depth * expander_size; |
14749 | } |
14750 | } |
14751 | |
14752 | if (ctk_tree_view_column_cell_is_visible (column)) |
14753 | { |
14754 | if (is_separator) |
14755 | { |
14756 | ctk_style_context_save (context); |
14757 | ctk_style_context_add_class (context, CTK_STYLE_CLASS_SEPARATOR"separator"); |
14758 | |
14759 | ctk_render_line (context, cr, |
14760 | cell_area.x, |
14761 | cell_area.y + cell_area.height / 2, |
14762 | cell_area.x + cell_area.width, |
14763 | cell_area.y + cell_area.height / 2); |
14764 | |
14765 | ctk_style_context_restore (context); |
14766 | } |
14767 | else |
14768 | { |
14769 | _ctk_tree_view_column_cell_render (column, |
14770 | cr, |
14771 | &background_area, |
14772 | &cell_area, |
14773 | 0, FALSE(0)); |
14774 | } |
14775 | } |
14776 | cell_offset += ctk_tree_view_column_get_width (column); |
14777 | } |
14778 | |
14779 | cairo_set_source_rgb (cr, 0, 0, 0); |
14780 | cairo_rectangle (cr, |
14781 | 0.5, 0.5, |
14782 | bin_window_width + 1, |
14783 | background_area.height + 1); |
14784 | cairo_set_line_width (cr, 1.0); |
14785 | cairo_stroke (cr); |
14786 | |
14787 | cairo_destroy (cr); |
14788 | |
14789 | cairo_surface_set_device_offset (surface, 2, 2); |
14790 | |
14791 | return surface; |
14792 | } |
14793 | |
14794 | |
14795 | /** |
14796 | * ctk_tree_view_set_destroy_count_func: |
14797 | * @tree_view: A #CtkTreeView |
14798 | * @func: (allow-none): Function to be called when a view row is destroyed, or %NULL |
14799 | * @data: (allow-none): User data to be passed to @func, or %NULL |
14800 | * @destroy: (allow-none): Destroy notifier for @data, or %NULL |
14801 | * |
14802 | * This function should almost never be used. It is meant for private use by |
14803 | * ATK for determining the number of visible children that are removed when the |
14804 | * user collapses a row, or a row is deleted. |
14805 | * |
14806 | * Deprecated: 3.4: Accessibility does not need the function anymore. |
14807 | **/ |
14808 | void |
14809 | ctk_tree_view_set_destroy_count_func (CtkTreeView *tree_view, |
14810 | CtkTreeDestroyCountFunc func, |
14811 | gpointer data, |
14812 | GDestroyNotify destroy) |
14813 | { |
14814 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14815 | |
14816 | if (tree_view->priv->destroy_count_destroy) |
14817 | tree_view->priv->destroy_count_destroy (tree_view->priv->destroy_count_data); |
14818 | |
14819 | tree_view->priv->destroy_count_func = func; |
14820 | tree_view->priv->destroy_count_data = data; |
14821 | tree_view->priv->destroy_count_destroy = destroy; |
14822 | } |
14823 | |
14824 | |
14825 | /* |
14826 | * Interactive search |
14827 | */ |
14828 | |
14829 | /** |
14830 | * ctk_tree_view_set_enable_search: |
14831 | * @tree_view: A #CtkTreeView |
14832 | * @enable_search: %TRUE, if the user can search interactively |
14833 | * |
14834 | * If @enable_search is set, then the user can type in text to search through |
14835 | * the tree interactively (this is sometimes called "typeahead find"). |
14836 | * |
14837 | * Note that even if this is %FALSE, the user can still initiate a search |
14838 | * using the “start-interactive-search” key binding. |
14839 | */ |
14840 | void |
14841 | ctk_tree_view_set_enable_search (CtkTreeView *tree_view, |
14842 | gboolean enable_search) |
14843 | { |
14844 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14845 | |
14846 | enable_search = !!enable_search; |
14847 | |
14848 | if (tree_view->priv->enable_search != enable_search) |
14849 | { |
14850 | tree_view->priv->enable_search = enable_search; |
14851 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_ENABLE_SEARCH]); |
14852 | } |
14853 | } |
14854 | |
14855 | /** |
14856 | * ctk_tree_view_get_enable_search: |
14857 | * @tree_view: A #CtkTreeView |
14858 | * |
14859 | * Returns whether or not the tree allows to start interactive searching |
14860 | * by typing in text. |
14861 | * |
14862 | * Returns: whether or not to let the user search interactively |
14863 | */ |
14864 | gboolean |
14865 | ctk_tree_view_get_enable_search (CtkTreeView *tree_view) |
14866 | { |
14867 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
14868 | |
14869 | return tree_view->priv->enable_search; |
14870 | } |
14871 | |
14872 | |
14873 | /** |
14874 | * ctk_tree_view_get_search_column: |
14875 | * @tree_view: A #CtkTreeView |
14876 | * |
14877 | * Gets the column searched on by the interactive search code. |
14878 | * |
14879 | * Returns: the column the interactive search code searches in. |
14880 | */ |
14881 | gint |
14882 | ctk_tree_view_get_search_column (CtkTreeView *tree_view) |
14883 | { |
14884 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), -1)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (-1); } } while ( 0); |
14885 | |
14886 | return (tree_view->priv->search_column); |
14887 | } |
14888 | |
14889 | /** |
14890 | * ctk_tree_view_set_search_column: |
14891 | * @tree_view: A #CtkTreeView |
14892 | * @column: the column of the model to search in, or -1 to disable searching |
14893 | * |
14894 | * Sets @column as the column where the interactive search code should |
14895 | * search in for the current model. |
14896 | * |
14897 | * If the search column is set, users can use the “start-interactive-search” |
14898 | * key binding to bring up search popup. The enable-search property controls |
14899 | * whether simply typing text will also start an interactive search. |
14900 | * |
14901 | * Note that @column refers to a column of the current model. The search |
14902 | * column is reset to -1 when the model is changed. |
14903 | */ |
14904 | void |
14905 | ctk_tree_view_set_search_column (CtkTreeView *tree_view, |
14906 | gint column) |
14907 | { |
14908 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14909 | g_return_if_fail (column >= -1)do { if ((column >= -1)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column >= -1"); return ; } } while (0); |
14910 | |
14911 | if (tree_view->priv->search_column == column) |
14912 | return; |
14913 | |
14914 | tree_view->priv->search_column = column; |
14915 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_SEARCH_COLUMN]); |
14916 | } |
14917 | |
14918 | /** |
14919 | * ctk_tree_view_get_search_equal_func: (skip) |
14920 | * @tree_view: A #CtkTreeView |
14921 | * |
14922 | * Returns the compare function currently in use. |
14923 | * |
14924 | * Returns: the currently used compare function for the search code. |
14925 | */ |
14926 | |
14927 | CtkTreeViewSearchEqualFunc |
14928 | ctk_tree_view_get_search_equal_func (CtkTreeView *tree_view) |
14929 | { |
14930 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
14931 | |
14932 | return tree_view->priv->search_equal_func; |
14933 | } |
14934 | |
14935 | /** |
14936 | * ctk_tree_view_set_search_equal_func: |
14937 | * @tree_view: A #CtkTreeView |
14938 | * @search_equal_func: the compare function to use during the search |
14939 | * @search_user_data: (allow-none): user data to pass to @search_equal_func, or %NULL |
14940 | * @search_destroy: (allow-none): Destroy notifier for @search_user_data, or %NULL |
14941 | * |
14942 | * Sets the compare function for the interactive search capabilities; note |
14943 | * that somewhat like strcmp() returning 0 for equality |
14944 | * #CtkTreeViewSearchEqualFunc returns %FALSE on matches. |
14945 | **/ |
14946 | void |
14947 | ctk_tree_view_set_search_equal_func (CtkTreeView *tree_view, |
14948 | CtkTreeViewSearchEqualFunc search_equal_func, |
14949 | gpointer search_user_data, |
14950 | GDestroyNotify search_destroy) |
14951 | { |
14952 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
14953 | g_return_if_fail (search_equal_func != NULL)do { if ((search_equal_func != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "search_equal_func != NULL" ); return; } } while (0); |
14954 | |
14955 | if (tree_view->priv->search_destroy) |
14956 | tree_view->priv->search_destroy (tree_view->priv->search_user_data); |
14957 | |
14958 | tree_view->priv->search_equal_func = search_equal_func; |
14959 | tree_view->priv->search_user_data = search_user_data; |
14960 | tree_view->priv->search_destroy = search_destroy; |
14961 | if (tree_view->priv->search_equal_func == NULL((void*)0)) |
14962 | tree_view->priv->search_equal_func = ctk_tree_view_search_equal_func; |
14963 | } |
14964 | |
14965 | /** |
14966 | * ctk_tree_view_get_search_entry: |
14967 | * @tree_view: A #CtkTreeView |
14968 | * |
14969 | * Returns the #CtkEntry which is currently in use as interactive search |
14970 | * entry for @tree_view. In case the built-in entry is being used, %NULL |
14971 | * will be returned. |
14972 | * |
14973 | * Returns: (transfer none): the entry currently in use as search entry. |
14974 | * |
14975 | * Since: 2.10 |
14976 | */ |
14977 | CtkEntry * |
14978 | ctk_tree_view_get_search_entry (CtkTreeView *tree_view) |
14979 | { |
14980 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
14981 | |
14982 | if (tree_view->priv->search_custom_entry_set) |
14983 | return CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ())))))); |
14984 | |
14985 | return NULL((void*)0); |
14986 | } |
14987 | |
14988 | /** |
14989 | * ctk_tree_view_set_search_entry: |
14990 | * @tree_view: A #CtkTreeView |
14991 | * @entry: (allow-none): the entry the interactive search code of @tree_view should use or %NULL |
14992 | * |
14993 | * Sets the entry which the interactive search code will use for this |
14994 | * @tree_view. This is useful when you want to provide a search entry |
14995 | * in our interface at all time at a fixed position. Passing %NULL for |
14996 | * @entry will make the interactive search code use the built-in popup |
14997 | * entry again. |
14998 | * |
14999 | * Since: 2.10 |
15000 | */ |
15001 | void |
15002 | ctk_tree_view_set_search_entry (CtkTreeView *tree_view, |
15003 | CtkEntry *entry) |
15004 | { |
15005 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
15006 | g_return_if_fail (entry == NULL || CTK_IS_ENTRY (entry))do { if ((entry == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((entry)); GType __t = ((ctk_entry_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "entry == NULL || CTK_IS_ENTRY (entry)") ; return; } } while (0); |
15007 | |
15008 | if (tree_view->priv->search_custom_entry_set) |
15009 | { |
15010 | if (tree_view->priv->search_entry_changed_id) |
15011 | { |
15012 | g_signal_handler_disconnect (tree_view->priv->search_entry, |
15013 | tree_view->priv->search_entry_changed_id); |
15014 | tree_view->priv->search_entry_changed_id = 0; |
15015 | } |
15016 | g_signal_handlers_disconnect_by_func (tree_view->priv->search_entry,g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view)) |
15017 | G_CALLBACK (ctk_tree_view_search_key_press_event),g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view)) |
15018 | tree_view)g_signal_handlers_disconnect_matched ((tree_view->priv-> search_entry), (GSignalMatchType) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA ), 0, 0, ((void*)0), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view)); |
15019 | |
15020 | g_object_unref (tree_view->priv->search_entry); |
15021 | } |
15022 | else if (tree_view->priv->search_window) |
15023 | { |
15024 | ctk_tree_view_destroy_search_window (tree_view); |
15025 | } |
15026 | |
15027 | if (entry) |
15028 | { |
15029 | tree_view->priv->search_entry = CTK_WIDGET (g_object_ref (entry))((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((((__typeof__ (entry)) (g_object_ref) (entry)))), ((ctk_widget_get_type ())))))); |
15030 | tree_view->priv->search_custom_entry_set = TRUE(!(0)); |
15031 | |
15032 | if (tree_view->priv->search_entry_changed_id == 0) |
15033 | { |
15034 | tree_view->priv->search_entry_changed_id = |
15035 | g_signal_connect (tree_view->priv->search_entry, "changed",g_signal_connect_data ((tree_view->priv->search_entry), ("changed"), (((GCallback) (ctk_tree_view_search_init))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
15036 | G_CALLBACK (ctk_tree_view_search_init),g_signal_connect_data ((tree_view->priv->search_entry), ("changed"), (((GCallback) (ctk_tree_view_search_init))), (tree_view ), ((void*)0), (GConnectFlags) 0) |
15037 | tree_view)g_signal_connect_data ((tree_view->priv->search_entry), ("changed"), (((GCallback) (ctk_tree_view_search_init))), (tree_view ), ((void*)0), (GConnectFlags) 0); |
15038 | } |
15039 | |
15040 | g_signal_connect (tree_view->priv->search_entry, "key-press-event",g_signal_connect_data ((tree_view->priv->search_entry), ("key-press-event"), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
15041 | G_CALLBACK (ctk_tree_view_search_key_press_event),g_signal_connect_data ((tree_view->priv->search_entry), ("key-press-event"), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0) |
15042 | tree_view)g_signal_connect_data ((tree_view->priv->search_entry), ("key-press-event"), (((GCallback) (ctk_tree_view_search_key_press_event ))), (tree_view), ((void*)0), (GConnectFlags) 0); |
15043 | |
15044 | ctk_tree_view_search_init (tree_view->priv->search_entry, tree_view); |
15045 | } |
15046 | else |
15047 | { |
15048 | tree_view->priv->search_entry = NULL((void*)0); |
15049 | tree_view->priv->search_custom_entry_set = FALSE(0); |
15050 | } |
15051 | } |
15052 | |
15053 | /** |
15054 | * ctk_tree_view_set_search_position_func: |
15055 | * @tree_view: A #CtkTreeView |
15056 | * @func: (allow-none): the function to use to position the search dialog, or %NULL |
15057 | * to use the default search position function |
15058 | * @data: (allow-none): user data to pass to @func, or %NULL |
15059 | * @destroy: (allow-none): Destroy notifier for @data, or %NULL |
15060 | * |
15061 | * Sets the function to use when positioning the search dialog. |
15062 | * |
15063 | * Since: 2.10 |
15064 | **/ |
15065 | void |
15066 | ctk_tree_view_set_search_position_func (CtkTreeView *tree_view, |
15067 | CtkTreeViewSearchPositionFunc func, |
15068 | gpointer user_data, |
15069 | GDestroyNotify destroy) |
15070 | { |
15071 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
15072 | |
15073 | if (tree_view->priv->search_position_destroy) |
15074 | tree_view->priv->search_position_destroy (tree_view->priv->search_position_user_data); |
15075 | |
15076 | tree_view->priv->search_position_func = func; |
15077 | tree_view->priv->search_position_user_data = user_data; |
15078 | tree_view->priv->search_position_destroy = destroy; |
15079 | if (tree_view->priv->search_position_func == NULL((void*)0)) |
15080 | tree_view->priv->search_position_func = ctk_tree_view_search_position_func; |
15081 | } |
15082 | |
15083 | /** |
15084 | * ctk_tree_view_get_search_position_func: (skip) |
15085 | * @tree_view: A #CtkTreeView |
15086 | * |
15087 | * Returns the positioning function currently in use. |
15088 | * |
15089 | * Returns: the currently used function for positioning the search dialog. |
15090 | * |
15091 | * Since: 2.10 |
15092 | */ |
15093 | CtkTreeViewSearchPositionFunc |
15094 | ctk_tree_view_get_search_position_func (CtkTreeView *tree_view) |
15095 | { |
15096 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
15097 | |
15098 | return tree_view->priv->search_position_func; |
15099 | } |
15100 | |
15101 | |
15102 | static void |
15103 | ctk_tree_view_search_window_hide (CtkWidget *search_window, |
15104 | CtkTreeView *tree_view, |
15105 | CdkDevice *device) |
15106 | { |
15107 | if (tree_view->priv->disable_popdown) |
15108 | return; |
15109 | |
15110 | if (tree_view->priv->search_entry_changed_id) |
15111 | { |
15112 | g_signal_handler_disconnect (tree_view->priv->search_entry, |
15113 | tree_view->priv->search_entry_changed_id); |
15114 | tree_view->priv->search_entry_changed_id = 0; |
15115 | } |
15116 | if (tree_view->priv->typeselect_flush_timeout) |
15117 | { |
15118 | g_source_remove (tree_view->priv->typeselect_flush_timeout); |
15119 | tree_view->priv->typeselect_flush_timeout = 0; |
15120 | } |
15121 | |
15122 | if (ctk_widget_get_visible (search_window)) |
15123 | { |
15124 | /* send focus-in event */ |
15125 | send_focus_change (CTK_WIDGET (tree_view->priv->search_entry)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_widget_get_type ())))))), device, FALSE(0)); |
15126 | ctk_widget_hide (search_window); |
15127 | ctk_entry_set_text (CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ())))))), ""); |
15128 | send_focus_change (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), device, TRUE(!(0))); |
15129 | } |
15130 | } |
15131 | |
15132 | static void |
15133 | ctk_tree_view_search_position_func (CtkTreeView *tree_view, |
15134 | CtkWidget *search_window, |
15135 | gpointer user_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
15136 | { |
15137 | gint x, y; |
15138 | gint tree_x, tree_y; |
15139 | gint tree_width, tree_height; |
15140 | CdkDisplay *display; |
15141 | CdkMonitor *monitor; |
15142 | CdkRectangle workarea; |
15143 | CdkWindow *tree_window = ctk_widget_get_window (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
15144 | CtkRequisition requisition; |
15145 | |
15146 | ctk_widget_realize (search_window); |
15147 | |
15148 | display = ctk_widget_get_display (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
15149 | monitor = cdk_display_get_monitor_at_window (display, tree_window); |
15150 | cdk_monitor_get_workarea (monitor, &workarea); |
15151 | |
15152 | cdk_window_get_origin (tree_window, &tree_x, &tree_y); |
15153 | tree_width = cdk_window_get_width (tree_window); |
15154 | tree_height = cdk_window_get_height (tree_window); |
15155 | ctk_widget_get_preferred_size (search_window, &requisition, NULL((void*)0)); |
15156 | |
15157 | if (tree_x + tree_width > workarea.x + workarea.width) |
15158 | x = workarea.x + workarea.width - requisition.width; |
15159 | else if (tree_x + tree_width - requisition.width < workarea.x) |
15160 | x = workarea.x; |
15161 | else |
15162 | x = tree_x + tree_width - requisition.width; |
15163 | |
15164 | if (tree_y + tree_height + requisition.height > workarea.y + workarea.height) |
15165 | y = workarea.y + workarea.height - requisition.height; |
15166 | else if (tree_y + tree_height < workarea.y) /* isn't really possible ... */ |
15167 | y = workarea.y; |
15168 | else |
15169 | y = tree_y + tree_height; |
15170 | |
15171 | ctk_window_move (CTK_WINDOW (search_window)((((CtkWindow*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((search_window)), ((ctk_window_get_type ())))))), x, y); |
15172 | } |
15173 | |
15174 | static void |
15175 | ctk_tree_view_search_disable_popdown (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)), |
15176 | CtkMenu *menu, |
15177 | gpointer data) |
15178 | { |
15179 | CtkTreeView *tree_view = (CtkTreeView *)data; |
15180 | |
15181 | tree_view->priv->disable_popdown = 1; |
15182 | g_signal_connect (menu, "hide",g_signal_connect_data ((menu), ("hide"), (((GCallback) (ctk_tree_view_search_enable_popdown ))), (data), ((void*)0), (GConnectFlags) 0) |
15183 | G_CALLBACK (ctk_tree_view_search_enable_popdown), data)g_signal_connect_data ((menu), ("hide"), (((GCallback) (ctk_tree_view_search_enable_popdown ))), (data), ((void*)0), (GConnectFlags) 0); |
15184 | } |
15185 | |
15186 | /* Because we're visible but offscreen, we just set a flag in the preedit |
15187 | * callback. |
15188 | */ |
15189 | static void |
15190 | ctk_tree_view_search_preedit_changed (CtkIMContext *im_context G_GNUC_UNUSED__attribute__ ((__unused__)), |
15191 | CtkTreeView *tree_view) |
15192 | { |
15193 | tree_view->priv->imcontext_changed = 1; |
15194 | if (tree_view->priv->typeselect_flush_timeout) |
15195 | { |
15196 | g_source_remove (tree_view->priv->typeselect_flush_timeout); |
15197 | tree_view->priv->typeselect_flush_timeout = |
15198 | cdk_threads_add_timeout (CTK_TREE_VIEW_SEARCH_DIALOG_TIMEOUT5000, |
15199 | (GSourceFunc) ctk_tree_view_search_entry_flush_timeout, |
15200 | tree_view); |
15201 | g_source_set_name_by_id (tree_view->priv->typeselect_flush_timeout, "[ctk+] ctk_tree_view_search_entry_flush_timeout"); |
15202 | } |
15203 | |
15204 | } |
15205 | |
15206 | static void |
15207 | ctk_tree_view_search_commit (CtkIMContext *im_context G_GNUC_UNUSED__attribute__ ((__unused__)), |
15208 | gchar *buf G_GNUC_UNUSED__attribute__ ((__unused__)), |
15209 | CtkTreeView *tree_view) |
15210 | { |
15211 | tree_view->priv->imcontext_changed = 1; |
15212 | } |
15213 | |
15214 | static void |
15215 | ctk_tree_view_search_activate (CtkEntry *entry G_GNUC_UNUSED__attribute__ ((__unused__)), |
15216 | CtkTreeView *tree_view) |
15217 | { |
15218 | CtkTreePath *path; |
15219 | |
15220 | ctk_tree_view_search_window_hide (tree_view->priv->search_window, |
15221 | tree_view, |
15222 | ctk_get_current_event_device ()); |
15223 | |
15224 | /* If we have a row selected and it's the cursor row, we activate |
15225 | * the row XXX */ |
15226 | if (tree_view->priv->cursor_node && |
15227 | CTK_RBNODE_FLAG_SET (tree_view->priv->cursor_node, CTK_RBNODE_IS_SELECTED)(tree_view->priv->cursor_node?(((tree_view->priv-> cursor_node->flags&CTK_RBNODE_IS_SELECTED)==CTK_RBNODE_IS_SELECTED )?(!(0)):(0)):(0))) |
15228 | { |
15229 | path = _ctk_tree_path_new_from_rbtree (tree_view->priv->cursor_tree, |
15230 | tree_view->priv->cursor_node); |
15231 | |
15232 | ctk_tree_view_row_activated (tree_view, path, tree_view->priv->focus_column); |
15233 | |
15234 | ctk_tree_path_free (path); |
15235 | } |
15236 | } |
15237 | |
15238 | static gboolean |
15239 | ctk_tree_view_real_search_enable_popdown (gpointer data) |
15240 | { |
15241 | CtkTreeView *tree_view = (CtkTreeView *)data; |
15242 | |
15243 | tree_view->priv->disable_popdown = 0; |
15244 | |
15245 | return FALSE(0); |
15246 | } |
15247 | |
15248 | static void |
15249 | ctk_tree_view_search_enable_popdown (CtkWidget *widget G_GNUC_UNUSED__attribute__ ((__unused__)), |
15250 | gpointer data) |
15251 | { |
15252 | guint id; |
15253 | id = cdk_threads_add_timeout_full (G_PRIORITY_HIGH-100, 200, ctk_tree_view_real_search_enable_popdown, g_object_ref (data)((__typeof__ (data)) (g_object_ref) (data)), g_object_unref); |
15254 | g_source_set_name_by_id (id, "[ctk+] ctk_tree_view_real_search_enable_popdown"); |
15255 | } |
15256 | |
15257 | static gboolean |
15258 | ctk_tree_view_search_delete_event (CtkWidget *widget, |
15259 | CdkEventAny *event G_GNUC_UNUSED__attribute__ ((__unused__)), |
15260 | CtkTreeView *tree_view) |
15261 | { |
15262 | g_return_val_if_fail (CTK_IS_WIDGET (widget), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return ((0)); } } while (0); |
15263 | |
15264 | ctk_tree_view_search_window_hide (widget, tree_view, NULL((void*)0)); |
15265 | |
15266 | return TRUE(!(0)); |
15267 | } |
15268 | |
15269 | static gboolean |
15270 | ctk_tree_view_search_button_press_event (CtkWidget *widget, |
15271 | CdkEventButton *event, |
15272 | CtkTreeView *tree_view) |
15273 | { |
15274 | CdkDevice *keyb_device; |
15275 | |
15276 | g_return_val_if_fail (CTK_IS_WIDGET (widget), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return ((0)); } } while (0); |
15277 | |
15278 | keyb_device = cdk_device_get_associated_device (event->device); |
15279 | ctk_tree_view_search_window_hide (widget, tree_view, keyb_device); |
15280 | |
15281 | return TRUE(!(0)); |
15282 | } |
15283 | |
15284 | static gboolean |
15285 | ctk_tree_view_search_scroll_event (CtkWidget *widget, |
15286 | CdkEventScroll *event, |
15287 | CtkTreeView *tree_view) |
15288 | { |
15289 | gboolean retval = FALSE(0); |
15290 | |
15291 | if (event->direction == CDK_SCROLL_UP) |
15292 | { |
15293 | ctk_tree_view_search_move (widget, tree_view, TRUE(!(0))); |
15294 | retval = TRUE(!(0)); |
15295 | } |
15296 | else if (event->direction == CDK_SCROLL_DOWN) |
15297 | { |
15298 | ctk_tree_view_search_move (widget, tree_view, FALSE(0)); |
15299 | retval = TRUE(!(0)); |
15300 | } |
15301 | |
15302 | /* renew the flush timeout */ |
15303 | if (retval && tree_view->priv->typeselect_flush_timeout |
15304 | && !tree_view->priv->search_custom_entry_set) |
15305 | { |
15306 | g_source_remove (tree_view->priv->typeselect_flush_timeout); |
15307 | tree_view->priv->typeselect_flush_timeout = |
15308 | cdk_threads_add_timeout (CTK_TREE_VIEW_SEARCH_DIALOG_TIMEOUT5000, |
15309 | (GSourceFunc) ctk_tree_view_search_entry_flush_timeout, |
15310 | tree_view); |
15311 | g_source_set_name_by_id (tree_view->priv->typeselect_flush_timeout, "[ctk+] ctk_tree_view_search_entry_flush_timeout"); |
15312 | } |
15313 | |
15314 | return retval; |
15315 | } |
15316 | |
15317 | static gboolean |
15318 | ctk_tree_view_search_key_press_event (CtkWidget *widget, |
15319 | CdkEventKey *event, |
15320 | CtkTreeView *tree_view) |
15321 | { |
15322 | CdkModifierType default_accel; |
15323 | gboolean retval = FALSE(0); |
15324 | |
15325 | g_return_val_if_fail (CTK_IS_WIDGET (widget), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((widget)); GType __t = ((ctk_widget_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_WIDGET (widget)"); return ((0)); } } while (0); |
15326 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
15327 | |
15328 | /* close window and cancel the search */ |
15329 | if (!tree_view->priv->search_custom_entry_set |
15330 | && ctk_tree_view_search_key_cancels_search (event->keyval)) |
15331 | { |
15332 | ctk_tree_view_search_window_hide (widget, tree_view, |
15333 | cdk_event_get_device ((CdkEvent *) event)); |
15334 | return TRUE(!(0)); |
15335 | } |
15336 | |
15337 | default_accel = ctk_widget_get_modifier_mask (widget, |
15338 | CDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR); |
15339 | |
15340 | /* select previous matching iter */ |
15341 | if (event->keyval == CDK_KEY_Up0xff52 || event->keyval == CDK_KEY_KP_Up0xff97) |
15342 | { |
15343 | if (!ctk_tree_view_search_move (widget, tree_view, TRUE(!(0)))) |
15344 | ctk_widget_error_bell (widget); |
15345 | |
15346 | retval = TRUE(!(0)); |
15347 | } |
15348 | |
15349 | if (((event->state & (default_accel | CDK_SHIFT_MASK)) == (default_accel | CDK_SHIFT_MASK)) |
15350 | && (event->keyval == CDK_KEY_g0x067 || event->keyval == CDK_KEY_G0x047)) |
15351 | { |
15352 | if (!ctk_tree_view_search_move (widget, tree_view, TRUE(!(0)))) |
15353 | ctk_widget_error_bell (widget); |
15354 | |
15355 | retval = TRUE(!(0)); |
15356 | } |
15357 | |
15358 | /* select next matching iter */ |
15359 | if (event->keyval == CDK_KEY_Down0xff54 || event->keyval == CDK_KEY_KP_Down0xff99) |
15360 | { |
15361 | if (!ctk_tree_view_search_move (widget, tree_view, FALSE(0))) |
15362 | ctk_widget_error_bell (widget); |
15363 | |
15364 | retval = TRUE(!(0)); |
15365 | } |
15366 | |
15367 | if (((event->state & (default_accel | CDK_SHIFT_MASK)) == default_accel) |
15368 | && (event->keyval == CDK_KEY_g0x067 || event->keyval == CDK_KEY_G0x047)) |
15369 | { |
15370 | if (!ctk_tree_view_search_move (widget, tree_view, FALSE(0))) |
15371 | ctk_widget_error_bell (widget); |
15372 | |
15373 | retval = TRUE(!(0)); |
15374 | } |
15375 | |
15376 | /* renew the flush timeout */ |
15377 | if (retval && tree_view->priv->typeselect_flush_timeout |
15378 | && !tree_view->priv->search_custom_entry_set) |
15379 | { |
15380 | g_source_remove (tree_view->priv->typeselect_flush_timeout); |
15381 | tree_view->priv->typeselect_flush_timeout = |
15382 | cdk_threads_add_timeout (CTK_TREE_VIEW_SEARCH_DIALOG_TIMEOUT5000, |
15383 | (GSourceFunc) ctk_tree_view_search_entry_flush_timeout, |
15384 | tree_view); |
15385 | g_source_set_name_by_id (tree_view->priv->typeselect_flush_timeout, "[ctk+] ctk_tree_view_search_entry_flush_timeout"); |
15386 | } |
15387 | |
15388 | return retval; |
15389 | } |
15390 | |
15391 | /* this function returns FALSE if there is a search string but |
15392 | * nothing was found, and TRUE otherwise. |
15393 | */ |
15394 | static gboolean |
15395 | ctk_tree_view_search_move (CtkWidget *window G_GNUC_UNUSED__attribute__ ((__unused__)), |
15396 | CtkTreeView *tree_view, |
15397 | gboolean up) |
15398 | { |
15399 | gboolean ret; |
15400 | gint len; |
15401 | gint count = 0; |
15402 | const gchar *text; |
15403 | CtkTreeIter iter; |
15404 | CtkTreeModel *model; |
15405 | CtkTreeSelection *selection; |
15406 | |
15407 | text = ctk_entry_get_text (CTK_ENTRY (tree_view->priv->search_entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view->priv->search_entry)), ((ctk_entry_get_type ()))))))); |
15408 | |
15409 | g_return_val_if_fail (text != NULL, FALSE)do { if ((text != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "text != NULL"); return ( (0)); } } while (0); |
15410 | |
15411 | len = strlen (text); |
15412 | |
15413 | if (up && tree_view->priv->selected_iter == 1) |
15414 | return len < 1; |
15415 | |
15416 | if (len < 1) |
15417 | return TRUE(!(0)); |
15418 | |
15419 | model = ctk_tree_view_get_model (tree_view); |
15420 | selection = ctk_tree_view_get_selection (tree_view); |
15421 | |
15422 | /* search */ |
15423 | ctk_tree_selection_unselect_all (selection); |
15424 | if (!ctk_tree_model_get_iter_first (model, &iter)) |
15425 | return TRUE(!(0)); |
15426 | |
15427 | ret = ctk_tree_view_search_iter (model, selection, &iter, text, |
15428 | &count, up?((tree_view->priv->selected_iter) - 1):((tree_view->priv->selected_iter + 1))); |
15429 | |
15430 | if (ret) |
15431 | { |
15432 | /* found */ |
15433 | tree_view->priv->selected_iter += up?(-1):(1); |
15434 | return TRUE(!(0)); |
15435 | } |
15436 | else |
15437 | { |
15438 | /* return to old iter */ |
15439 | count = 0; |
15440 | ctk_tree_model_get_iter_first (model, &iter); |
15441 | ctk_tree_view_search_iter (model, selection, |
15442 | &iter, text, |
15443 | &count, tree_view->priv->selected_iter); |
15444 | return FALSE(0); |
15445 | } |
15446 | } |
15447 | |
15448 | static gboolean |
15449 | ctk_tree_view_search_equal_func (CtkTreeModel *model, |
15450 | gint column, |
15451 | const gchar *key, |
15452 | CtkTreeIter *iter, |
15453 | gpointer search_data G_GNUC_UNUSED__attribute__ ((__unused__))) |
15454 | { |
15455 | gboolean retval = TRUE(!(0)); |
15456 | const gchar *str; |
15457 | gchar *normalized_string; |
15458 | gchar *normalized_key; |
15459 | gchar *case_normalized_string = NULL((void*)0); |
15460 | gchar *case_normalized_key = NULL((void*)0); |
15461 | GValue value = G_VALUE_INIT{ 0, { { 0 } } }; |
15462 | GValue transformed = G_VALUE_INIT{ 0, { { 0 } } }; |
15463 | |
15464 | ctk_tree_model_get_value (model, iter, column, &value); |
15465 | |
15466 | g_value_init (&transformed, G_TYPE_STRING((GType) ((16) << (2)))); |
15467 | |
15468 | if (!g_value_transform (&value, &transformed)) |
15469 | { |
15470 | g_value_unset (&value); |
15471 | return TRUE(!(0)); |
15472 | } |
15473 | |
15474 | g_value_unset (&value); |
15475 | |
15476 | str = g_value_get_string (&transformed); |
15477 | if (!str) |
15478 | { |
15479 | g_value_unset (&transformed); |
15480 | return TRUE(!(0)); |
15481 | } |
15482 | |
15483 | normalized_string = g_utf8_normalize (str, -1, G_NORMALIZE_ALL); |
15484 | normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL); |
15485 | |
15486 | if (normalized_string && normalized_key) |
15487 | { |
15488 | case_normalized_string = g_utf8_casefold (normalized_string, -1); |
15489 | case_normalized_key = g_utf8_casefold (normalized_key, -1); |
15490 | |
15491 | if (strncmp (case_normalized_key, case_normalized_string, strlen (case_normalized_key)) == 0) |
15492 | retval = FALSE(0); |
15493 | } |
15494 | |
15495 | g_value_unset (&transformed); |
15496 | g_free (normalized_key); |
15497 | g_free (normalized_string); |
15498 | g_free (case_normalized_key); |
15499 | g_free (case_normalized_string); |
15500 | |
15501 | return retval; |
15502 | } |
15503 | |
15504 | static gboolean |
15505 | ctk_tree_view_search_iter (CtkTreeModel *model, |
15506 | CtkTreeSelection *selection, |
15507 | CtkTreeIter *iter, |
15508 | const gchar *text, |
15509 | gint *count, |
15510 | gint n) |
15511 | { |
15512 | CtkRBTree *tree = NULL((void*)0); |
15513 | CtkRBNode *node = NULL((void*)0); |
15514 | CtkTreePath *path; |
15515 | |
15516 | CtkTreeView *tree_view = ctk_tree_selection_get_tree_view (selection); |
15517 | |
15518 | path = ctk_tree_model_get_path (model, iter); |
15519 | _ctk_tree_view_find_node (tree_view, path, &tree, &node); |
15520 | |
15521 | do |
15522 | { |
15523 | if (! tree_view->priv->search_equal_func (model, tree_view->priv->search_column, text, iter, tree_view->priv->search_user_data)) |
15524 | { |
15525 | (*count)++; |
15526 | if (*count == n) |
15527 | { |
15528 | ctk_tree_view_scroll_to_cell (tree_view, path, NULL((void*)0), |
15529 | TRUE(!(0)), 0.5, 0.0); |
15530 | ctk_tree_selection_select_iter (selection, iter); |
15531 | ctk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE); |
15532 | |
15533 | if (path) |
15534 | ctk_tree_path_free (path); |
15535 | |
15536 | return TRUE(!(0)); |
15537 | } |
15538 | } |
15539 | |
15540 | if (node->children) |
15541 | { |
15542 | gboolean has_child; |
15543 | CtkTreeIter tmp; |
15544 | |
15545 | tree = node->children; |
15546 | node = _ctk_rbtree_first (tree); |
15547 | |
15548 | tmp = *iter; |
15549 | has_child = ctk_tree_model_iter_children (model, iter, &tmp); |
15550 | ctk_tree_path_down (path); |
15551 | |
15552 | /* sanity check */ |
15553 | TREE_VIEW_INTERNAL_ASSERT (has_child, FALSE)do{ if (!(has_child)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "15553", ((const char *) (__func__)), "has_child"); return (0); }; }while (0); |
15554 | } |
15555 | else |
15556 | { |
15557 | gboolean done = FALSE(0); |
15558 | |
15559 | do |
15560 | { |
15561 | node = _ctk_rbtree_next (tree, node); |
15562 | |
15563 | if (node) |
15564 | { |
15565 | gboolean has_next; |
15566 | |
15567 | has_next = ctk_tree_model_iter_next (model, iter); |
15568 | |
15569 | done = TRUE(!(0)); |
15570 | ctk_tree_path_next (path); |
15571 | |
15572 | /* sanity check */ |
15573 | TREE_VIEW_INTERNAL_ASSERT (has_next, FALSE)do{ if (!(has_next)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "15573", ((const char *) (__func__)), "has_next"); return (0); }; }while (0); |
15574 | } |
15575 | else |
15576 | { |
15577 | gboolean has_parent; |
15578 | CtkTreeIter tmp_iter = *iter; |
15579 | |
15580 | node = tree->parent_node; |
15581 | tree = tree->parent_tree; |
15582 | |
15583 | if (!tree) |
15584 | { |
15585 | if (path) |
15586 | ctk_tree_path_free (path); |
15587 | |
15588 | /* we've run out of tree, done with this func */ |
15589 | return FALSE(0); |
15590 | } |
15591 | |
15592 | has_parent = ctk_tree_model_iter_parent (model, |
15593 | iter, |
15594 | &tmp_iter); |
15595 | ctk_tree_path_up (path); |
15596 | |
15597 | /* sanity check */ |
15598 | TREE_VIEW_INTERNAL_ASSERT (has_parent, FALSE)do{ if (!(has_parent)) { g_log ("Ctk", G_LOG_LEVEL_CRITICAL, "%s (%s): assertion `%s' failed.\n" "There is a disparity between the internal view of the CtkTreeView,\n" "and the CtkTreeModel. This generally means that the model has changed\n" "without letting the view know. Any display from now on is likely to\n" "be incorrect.\n", "ctktreeview.c" ":" "15598", ((const char *) (__func__)), "has_parent"); return (0); }; }while (0); |
15599 | } |
15600 | } |
15601 | while (!done); |
15602 | } |
15603 | } |
15604 | while (1); |
15605 | |
15606 | return FALSE(0); |
15607 | } |
15608 | |
15609 | static void |
15610 | ctk_tree_view_search_init (CtkWidget *entry, |
15611 | CtkTreeView *tree_view) |
15612 | { |
15613 | gint ret; |
15614 | gint count = 0; |
15615 | const gchar *text; |
15616 | CtkTreeIter iter; |
15617 | CtkTreeModel *model; |
15618 | CtkTreeSelection *selection; |
15619 | |
15620 | g_return_if_fail (CTK_IS_ENTRY (entry))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((entry)); GType __t = ((ctk_entry_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_ENTRY (entry)"); return; } } while (0); |
15621 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
15622 | |
15623 | text = ctk_entry_get_text (CTK_ENTRY (entry)((((CtkEntry*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((entry)), ((ctk_entry_get_type ()))))))); |
15624 | |
15625 | model = ctk_tree_view_get_model (tree_view); |
15626 | selection = ctk_tree_view_get_selection (tree_view); |
15627 | |
15628 | /* search */ |
15629 | ctk_tree_selection_unselect_all (selection); |
15630 | if (tree_view->priv->typeselect_flush_timeout |
15631 | && !tree_view->priv->search_custom_entry_set) |
15632 | { |
15633 | g_source_remove (tree_view->priv->typeselect_flush_timeout); |
15634 | tree_view->priv->typeselect_flush_timeout = |
15635 | cdk_threads_add_timeout (CTK_TREE_VIEW_SEARCH_DIALOG_TIMEOUT5000, |
15636 | (GSourceFunc) ctk_tree_view_search_entry_flush_timeout, |
15637 | tree_view); |
15638 | g_source_set_name_by_id (tree_view->priv->typeselect_flush_timeout, "[ctk+] ctk_tree_view_search_entry_flush_timeout"); |
15639 | } |
15640 | |
15641 | if (*text == '\0') |
15642 | return; |
15643 | |
15644 | if (!ctk_tree_model_get_iter_first (model, &iter)) |
15645 | return; |
15646 | |
15647 | ret = ctk_tree_view_search_iter (model, selection, |
15648 | &iter, text, |
15649 | &count, 1); |
15650 | |
15651 | if (ret) |
15652 | tree_view->priv->selected_iter = 1; |
15653 | } |
15654 | |
15655 | void |
15656 | _ctk_tree_view_remove_editable (CtkTreeView *tree_view, |
15657 | CtkTreeViewColumn *column, |
15658 | CtkCellEditable *cell_editable) |
15659 | { |
15660 | if (tree_view->priv->edited_column == NULL((void*)0)) |
15661 | return; |
15662 | |
15663 | g_return_if_fail (column == tree_view->priv->edited_column)do { if ((column == tree_view->priv->edited_column)) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "column == tree_view->priv->edited_column"); return ; } } while (0); |
15664 | |
15665 | tree_view->priv->edited_column = NULL((void*)0); |
15666 | |
15667 | if (ctk_widget_has_focus (CTK_WIDGET (cell_editable)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cell_editable)), ((ctk_widget_get_type ())))))))) |
15668 | ctk_widget_grab_focus (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
15669 | |
15670 | ctk_container_remove (CTK_CONTAINER (tree_view)((((CtkContainer*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_container_get_type ())))))), |
15671 | CTK_WIDGET (cell_editable)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cell_editable)), ((ctk_widget_get_type ()))))))); |
15672 | |
15673 | /* FIXME should only redraw a single node */ |
15674 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
15675 | } |
15676 | |
15677 | static gboolean |
15678 | ctk_tree_view_start_editing (CtkTreeView *tree_view, |
15679 | CtkTreePath *cursor_path, |
15680 | gboolean edit_only) |
15681 | { |
15682 | CtkTreeIter iter; |
15683 | CdkRectangle cell_area; |
15684 | CtkTreeViewColumn *focus_column; |
15685 | guint flags = 0; /* can be 0, as the flags are primarily for rendering */ |
15686 | gint retval = FALSE(0); |
15687 | CtkRBTree *cursor_tree; |
15688 | CtkRBNode *cursor_node; |
15689 | |
15690 | g_assert (tree_view->priv->focus_column)do { if (tree_view->priv->focus_column) ; else g_assertion_message_expr ("Ctk", "ctktreeview.c", 15690, ((const char*) (__func__)), "tree_view->priv->focus_column" ); } while (0); |
15691 | focus_column = tree_view->priv->focus_column; |
15692 | |
15693 | if (!ctk_widget_get_realized (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))))) |
15694 | return FALSE(0); |
15695 | |
15696 | if (_ctk_tree_view_find_node (tree_view, cursor_path, &cursor_tree, &cursor_node) || |
15697 | cursor_node == NULL((void*)0)) |
15698 | return FALSE(0); |
15699 | |
15700 | ctk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path); |
15701 | |
15702 | validate_row (tree_view, cursor_tree, cursor_node, &iter, cursor_path); |
15703 | |
15704 | ctk_tree_view_column_cell_set_cell_data (focus_column, |
15705 | tree_view->priv->model, |
15706 | &iter, |
15707 | CTK_RBNODE_FLAG_SET (cursor_node, CTK_RBNODE_IS_PARENT)(cursor_node?(((cursor_node->flags&CTK_RBNODE_IS_PARENT )==CTK_RBNODE_IS_PARENT)?(!(0)):(0)):(0)), |
15708 | cursor_node->children ? TRUE(!(0)) : FALSE(0)); |
15709 | ctk_tree_view_get_cell_area (tree_view, |
15710 | cursor_path, |
15711 | focus_column, |
15712 | &cell_area); |
15713 | |
15714 | if (ctk_cell_area_activate (ctk_cell_layout_get_area (CTK_CELL_LAYOUT (focus_column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((focus_column)), ((ctk_cell_layout_get_type ()))))))), |
15715 | _ctk_tree_view_column_get_context (focus_column), |
15716 | CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), |
15717 | &cell_area, |
15718 | flags, edit_only)) |
15719 | retval = TRUE(!(0)); |
15720 | |
15721 | return retval; |
15722 | } |
15723 | |
15724 | void |
15725 | _ctk_tree_view_add_editable (CtkTreeView *tree_view, |
15726 | CtkTreeViewColumn *column, |
15727 | CtkTreePath *path, |
15728 | CtkCellEditable *cell_editable, |
15729 | CdkRectangle *cell_area) |
15730 | { |
15731 | CdkRectangle full_area; |
15732 | CtkBorder border; |
15733 | |
15734 | tree_view->priv->edited_column = column; |
15735 | |
15736 | ctk_tree_view_real_set_cursor (tree_view, path, CLAMP_NODE); |
15737 | |
15738 | tree_view->priv->draw_keyfocus = TRUE(!(0)); |
15739 | |
15740 | ctk_tree_view_get_cell_area (tree_view, path, column, &full_area); |
15741 | border.left = cell_area->x - full_area.x; |
15742 | border.top = cell_area->y - full_area.y; |
15743 | border.right = (full_area.x + full_area.width) - (cell_area->x + cell_area->width); |
15744 | border.bottom = (full_area.y + full_area.height) - (cell_area->y + cell_area->height); |
15745 | |
15746 | ctk_tree_view_put (tree_view, |
15747 | CTK_WIDGET (cell_editable)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((cell_editable)), ((ctk_widget_get_type ())))))), |
15748 | path, |
15749 | column, |
15750 | &border); |
15751 | } |
15752 | |
15753 | static void |
15754 | ctk_tree_view_stop_editing (CtkTreeView *tree_view, |
15755 | gboolean cancel_editing) |
15756 | { |
15757 | CtkTreeViewColumn *column; |
15758 | |
15759 | if (tree_view->priv->edited_column == NULL((void*)0)) |
15760 | return; |
15761 | |
15762 | /* |
15763 | * This is very evil. We need to do this, because |
15764 | * ctk_cell_editable_editing_done may trigger ctk_tree_view_row_changed |
15765 | * later on. If ctk_tree_view_row_changed notices |
15766 | * tree_view->priv->edited_column != NULL, it'll call |
15767 | * ctk_tree_view_stop_editing again. Bad things will happen then. |
15768 | * |
15769 | * Please read that again if you intend to modify anything here. |
15770 | */ |
15771 | |
15772 | column = tree_view->priv->edited_column; |
15773 | ctk_cell_area_stop_editing (ctk_cell_layout_get_area (CTK_CELL_LAYOUT (column)((((CtkCellLayout*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((column)), ((ctk_cell_layout_get_type ()))))))), cancel_editing); |
15774 | tree_view->priv->edited_column = NULL((void*)0); |
15775 | } |
15776 | |
15777 | |
15778 | /** |
15779 | * ctk_tree_view_set_hover_selection: |
15780 | * @tree_view: a #CtkTreeView |
15781 | * @hover: %TRUE to enable hover selection mode |
15782 | * |
15783 | * Enables or disables the hover selection mode of @tree_view. |
15784 | * Hover selection makes the selected row follow the pointer. |
15785 | * Currently, this works only for the selection modes |
15786 | * %CTK_SELECTION_SINGLE and %CTK_SELECTION_BROWSE. |
15787 | * |
15788 | * Since: 2.6 |
15789 | **/ |
15790 | void |
15791 | ctk_tree_view_set_hover_selection (CtkTreeView *tree_view, |
15792 | gboolean hover) |
15793 | { |
15794 | hover = hover != FALSE(0); |
15795 | |
15796 | if (hover != tree_view->priv->hover_selection) |
15797 | { |
15798 | tree_view->priv->hover_selection = hover; |
15799 | |
15800 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_HOVER_SELECTION]); |
15801 | } |
15802 | } |
15803 | |
15804 | /** |
15805 | * ctk_tree_view_get_hover_selection: |
15806 | * @tree_view: a #CtkTreeView |
15807 | * |
15808 | * Returns whether hover selection mode is turned on for @tree_view. |
15809 | * |
15810 | * Returns: %TRUE if @tree_view is in hover selection mode |
15811 | * |
15812 | * Since: 2.6 |
15813 | **/ |
15814 | gboolean |
15815 | ctk_tree_view_get_hover_selection (CtkTreeView *tree_view) |
15816 | { |
15817 | return tree_view->priv->hover_selection; |
15818 | } |
15819 | |
15820 | /** |
15821 | * ctk_tree_view_set_hover_expand: |
15822 | * @tree_view: a #CtkTreeView |
15823 | * @expand: %TRUE to enable hover selection mode |
15824 | * |
15825 | * Enables or disables the hover expansion mode of @tree_view. |
15826 | * Hover expansion makes rows expand or collapse if the pointer |
15827 | * moves over them. |
15828 | * |
15829 | * Since: 2.6 |
15830 | **/ |
15831 | void |
15832 | ctk_tree_view_set_hover_expand (CtkTreeView *tree_view, |
15833 | gboolean expand) |
15834 | { |
15835 | expand = expand != FALSE(0); |
15836 | |
15837 | if (expand != tree_view->priv->hover_expand) |
15838 | { |
15839 | tree_view->priv->hover_expand = expand; |
15840 | |
15841 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_HOVER_EXPAND]); |
15842 | } |
15843 | } |
15844 | |
15845 | /** |
15846 | * ctk_tree_view_get_hover_expand: |
15847 | * @tree_view: a #CtkTreeView |
15848 | * |
15849 | * Returns whether hover expansion mode is turned on for @tree_view. |
15850 | * |
15851 | * Returns: %TRUE if @tree_view is in hover expansion mode |
15852 | * |
15853 | * Since: 2.6 |
15854 | **/ |
15855 | gboolean |
15856 | ctk_tree_view_get_hover_expand (CtkTreeView *tree_view) |
15857 | { |
15858 | return tree_view->priv->hover_expand; |
15859 | } |
15860 | |
15861 | /** |
15862 | * ctk_tree_view_set_rubber_banding: |
15863 | * @tree_view: a #CtkTreeView |
15864 | * @enable: %TRUE to enable rubber banding |
15865 | * |
15866 | * Enables or disables rubber banding in @tree_view. If the selection mode |
15867 | * is #CTK_SELECTION_MULTIPLE, rubber banding will allow the user to select |
15868 | * multiple rows by dragging the mouse. |
15869 | * |
15870 | * Since: 2.10 |
15871 | **/ |
15872 | void |
15873 | ctk_tree_view_set_rubber_banding (CtkTreeView *tree_view, |
15874 | gboolean enable) |
15875 | { |
15876 | enable = enable != FALSE(0); |
15877 | |
15878 | if (enable != tree_view->priv->rubber_banding_enable) |
15879 | { |
15880 | tree_view->priv->rubber_banding_enable = enable; |
15881 | |
15882 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_RUBBER_BANDING]); |
15883 | } |
15884 | } |
15885 | |
15886 | /** |
15887 | * ctk_tree_view_get_rubber_banding: |
15888 | * @tree_view: a #CtkTreeView |
15889 | * |
15890 | * Returns whether rubber banding is turned on for @tree_view. If the |
15891 | * selection mode is #CTK_SELECTION_MULTIPLE, rubber banding will allow the |
15892 | * user to select multiple rows by dragging the mouse. |
15893 | * |
15894 | * Returns: %TRUE if rubber banding in @tree_view is enabled. |
15895 | * |
15896 | * Since: 2.10 |
15897 | **/ |
15898 | gboolean |
15899 | ctk_tree_view_get_rubber_banding (CtkTreeView *tree_view) |
15900 | { |
15901 | return tree_view->priv->rubber_banding_enable; |
15902 | } |
15903 | |
15904 | /** |
15905 | * ctk_tree_view_is_rubber_banding_active: |
15906 | * @tree_view: a #CtkTreeView |
15907 | * |
15908 | * Returns whether a rubber banding operation is currently being done |
15909 | * in @tree_view. |
15910 | * |
15911 | * Returns: %TRUE if a rubber banding operation is currently being |
15912 | * done in @tree_view. |
15913 | * |
15914 | * Since: 2.12 |
15915 | **/ |
15916 | gboolean |
15917 | ctk_tree_view_is_rubber_banding_active (CtkTreeView *tree_view) |
15918 | { |
15919 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
15920 | |
15921 | if (tree_view->priv->rubber_banding_enable |
15922 | && tree_view->priv->rubber_band_status == RUBBER_BAND_ACTIVE) |
15923 | return TRUE(!(0)); |
15924 | |
15925 | return FALSE(0); |
15926 | } |
15927 | |
15928 | /** |
15929 | * ctk_tree_view_get_row_separator_func: (skip) |
15930 | * @tree_view: a #CtkTreeView |
15931 | * |
15932 | * Returns the current row separator function. |
15933 | * |
15934 | * Returns: the current row separator function. |
15935 | * |
15936 | * Since: 2.6 |
15937 | **/ |
15938 | CtkTreeViewRowSeparatorFunc |
15939 | ctk_tree_view_get_row_separator_func (CtkTreeView *tree_view) |
15940 | { |
15941 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), NULL)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (((void*)0)); } } while (0); |
15942 | |
15943 | return tree_view->priv->row_separator_func; |
15944 | } |
15945 | |
15946 | /** |
15947 | * ctk_tree_view_set_row_separator_func: |
15948 | * @tree_view: a #CtkTreeView |
15949 | * @func: (allow-none): a #CtkTreeViewRowSeparatorFunc |
15950 | * @data: (allow-none): user data to pass to @func, or %NULL |
15951 | * @destroy: (allow-none): destroy notifier for @data, or %NULL |
15952 | * |
15953 | * Sets the row separator function, which is used to determine |
15954 | * whether a row should be drawn as a separator. If the row separator |
15955 | * function is %NULL, no separators are drawn. This is the default value. |
15956 | * |
15957 | * Since: 2.6 |
15958 | **/ |
15959 | void |
15960 | ctk_tree_view_set_row_separator_func (CtkTreeView *tree_view, |
15961 | CtkTreeViewRowSeparatorFunc func, |
15962 | gpointer data, |
15963 | GDestroyNotify destroy) |
15964 | { |
15965 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
15966 | |
15967 | if (tree_view->priv->row_separator_destroy) |
15968 | tree_view->priv->row_separator_destroy (tree_view->priv->row_separator_data); |
15969 | |
15970 | tree_view->priv->row_separator_func = func; |
15971 | tree_view->priv->row_separator_data = data; |
15972 | tree_view->priv->row_separator_destroy = destroy; |
15973 | |
15974 | /* Have the tree recalculate heights */ |
15975 | _ctk_rbtree_mark_invalid (tree_view->priv->tree); |
15976 | ctk_widget_queue_resize (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
15977 | } |
15978 | |
15979 | /** |
15980 | * ctk_tree_view_get_grid_lines: |
15981 | * @tree_view: a #CtkTreeView |
15982 | * |
15983 | * Returns which grid lines are enabled in @tree_view. |
15984 | * |
15985 | * Returns: a #CtkTreeViewGridLines value indicating which grid lines |
15986 | * are enabled. |
15987 | * |
15988 | * Since: 2.10 |
15989 | */ |
15990 | CtkTreeViewGridLines |
15991 | ctk_tree_view_get_grid_lines (CtkTreeView *tree_view) |
15992 | { |
15993 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (0); } } while (0 ); |
15994 | |
15995 | return tree_view->priv->grid_lines; |
15996 | } |
15997 | |
15998 | /** |
15999 | * ctk_tree_view_set_grid_lines: |
16000 | * @tree_view: a #CtkTreeView |
16001 | * @grid_lines: a #CtkTreeViewGridLines value indicating which grid lines to |
16002 | * enable. |
16003 | * |
16004 | * Sets which grid lines to draw in @tree_view. |
16005 | * |
16006 | * Since: 2.10 |
16007 | */ |
16008 | void |
16009 | ctk_tree_view_set_grid_lines (CtkTreeView *tree_view, |
16010 | CtkTreeViewGridLines grid_lines) |
16011 | { |
16012 | CtkTreeViewPrivate *priv; |
16013 | CtkWidget *widget; |
16014 | CtkTreeViewGridLines old_grid_lines; |
16015 | |
16016 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
16017 | |
16018 | priv = tree_view->priv; |
16019 | widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
16020 | |
16021 | old_grid_lines = priv->grid_lines; |
16022 | priv->grid_lines = grid_lines; |
16023 | |
16024 | if (ctk_widget_get_realized (widget)) |
16025 | { |
16026 | if (grid_lines == CTK_TREE_VIEW_GRID_LINES_NONE && |
16027 | priv->grid_line_width) |
16028 | { |
16029 | priv->grid_line_width = 0; |
16030 | } |
16031 | |
16032 | if (grid_lines != CTK_TREE_VIEW_GRID_LINES_NONE && |
16033 | !priv->grid_line_width) |
16034 | { |
16035 | gint8 *dash_list; |
16036 | |
16037 | ctk_widget_style_get (widget, |
16038 | "grid-line-width", &priv->grid_line_width, |
16039 | "grid-line-pattern", (gchar *)&dash_list, |
16040 | NULL((void*)0)); |
16041 | |
16042 | if (dash_list) |
16043 | { |
16044 | priv->grid_line_dashes[0] = dash_list[0]; |
16045 | if (dash_list[0]) |
16046 | priv->grid_line_dashes[1] = dash_list[1]; |
16047 | |
16048 | g_free (dash_list); |
16049 | } |
16050 | else |
16051 | { |
16052 | priv->grid_line_dashes[0] = 1; |
16053 | priv->grid_line_dashes[1] = 1; |
16054 | } |
16055 | } |
16056 | } |
16057 | |
16058 | if (old_grid_lines != grid_lines) |
16059 | { |
16060 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
16061 | |
16062 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_ENABLE_GRID_LINES]); |
16063 | } |
16064 | } |
16065 | |
16066 | /** |
16067 | * ctk_tree_view_get_enable_tree_lines: |
16068 | * @tree_view: a #CtkTreeView. |
16069 | * |
16070 | * Returns whether or not tree lines are drawn in @tree_view. |
16071 | * |
16072 | * Returns: %TRUE if tree lines are drawn in @tree_view, %FALSE |
16073 | * otherwise. |
16074 | * |
16075 | * Since: 2.10 |
16076 | */ |
16077 | gboolean |
16078 | ctk_tree_view_get_enable_tree_lines (CtkTreeView *tree_view) |
16079 | { |
16080 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
16081 | |
16082 | return tree_view->priv->tree_lines_enabled; |
16083 | } |
16084 | |
16085 | /** |
16086 | * ctk_tree_view_set_enable_tree_lines: |
16087 | * @tree_view: a #CtkTreeView |
16088 | * @enabled: %TRUE to enable tree line drawing, %FALSE otherwise. |
16089 | * |
16090 | * Sets whether to draw lines interconnecting the expanders in @tree_view. |
16091 | * This does not have any visible effects for lists. |
16092 | * |
16093 | * Since: 2.10 |
16094 | */ |
16095 | void |
16096 | ctk_tree_view_set_enable_tree_lines (CtkTreeView *tree_view, |
16097 | gboolean enabled) |
16098 | { |
16099 | CtkTreeViewPrivate *priv; |
16100 | CtkWidget *widget; |
16101 | gboolean was_enabled; |
16102 | |
16103 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
16104 | |
16105 | enabled = enabled != FALSE(0); |
16106 | |
16107 | priv = tree_view->priv; |
16108 | widget = CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))); |
16109 | |
16110 | was_enabled = priv->tree_lines_enabled; |
16111 | |
16112 | priv->tree_lines_enabled = enabled; |
16113 | |
16114 | if (ctk_widget_get_realized (widget)) |
16115 | { |
16116 | if (!enabled && priv->tree_line_width) |
16117 | { |
16118 | priv->tree_line_width = 0; |
16119 | } |
16120 | |
16121 | if (enabled && !priv->tree_line_width) |
16122 | { |
16123 | gint8 *dash_list; |
16124 | ctk_widget_style_get (widget, |
16125 | "tree-line-width", &priv->tree_line_width, |
16126 | "tree-line-pattern", (gchar *)&dash_list, |
16127 | NULL((void*)0)); |
16128 | |
16129 | if (dash_list) |
16130 | { |
16131 | priv->tree_line_dashes[0] = dash_list[0]; |
16132 | if (dash_list[0]) |
16133 | priv->tree_line_dashes[1] = dash_list[1]; |
16134 | |
16135 | g_free (dash_list); |
16136 | } |
16137 | else |
16138 | { |
16139 | priv->tree_line_dashes[0] = 1; |
16140 | priv->tree_line_dashes[1] = 1; |
16141 | } |
16142 | } |
16143 | } |
16144 | |
16145 | if (was_enabled != enabled) |
16146 | { |
16147 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
16148 | |
16149 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_ENABLE_TREE_LINES]); |
16150 | } |
16151 | } |
16152 | |
16153 | |
16154 | /** |
16155 | * ctk_tree_view_set_show_expanders: |
16156 | * @tree_view: a #CtkTreeView |
16157 | * @enabled: %TRUE to enable expander drawing, %FALSE otherwise. |
16158 | * |
16159 | * Sets whether to draw and enable expanders and indent child rows in |
16160 | * @tree_view. When disabled there will be no expanders visible in trees |
16161 | * and there will be no way to expand and collapse rows by default. Also |
16162 | * note that hiding the expanders will disable the default indentation. You |
16163 | * can set a custom indentation in this case using |
16164 | * ctk_tree_view_set_level_indentation(). |
16165 | * This does not have any visible effects for lists. |
16166 | * |
16167 | * Since: 2.12 |
16168 | */ |
16169 | void |
16170 | ctk_tree_view_set_show_expanders (CtkTreeView *tree_view, |
16171 | gboolean enabled) |
16172 | { |
16173 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
16174 | |
16175 | enabled = enabled != FALSE(0); |
16176 | if (tree_view->priv->show_expanders != enabled) |
16177 | { |
16178 | tree_view->priv->show_expanders = enabled; |
16179 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
16180 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_SHOW_EXPANDERS]); |
16181 | } |
16182 | } |
16183 | |
16184 | /** |
16185 | * ctk_tree_view_get_show_expanders: |
16186 | * @tree_view: a #CtkTreeView. |
16187 | * |
16188 | * Returns whether or not expanders are drawn in @tree_view. |
16189 | * |
16190 | * Returns: %TRUE if expanders are drawn in @tree_view, %FALSE |
16191 | * otherwise. |
16192 | * |
16193 | * Since: 2.12 |
16194 | */ |
16195 | gboolean |
16196 | ctk_tree_view_get_show_expanders (CtkTreeView *tree_view) |
16197 | { |
16198 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
16199 | |
16200 | return tree_view->priv->show_expanders; |
16201 | } |
16202 | |
16203 | /** |
16204 | * ctk_tree_view_set_level_indentation: |
16205 | * @tree_view: a #CtkTreeView |
16206 | * @indentation: the amount, in pixels, of extra indentation in @tree_view. |
16207 | * |
16208 | * Sets the amount of extra indentation for child levels to use in @tree_view |
16209 | * in addition to the default indentation. The value should be specified in |
16210 | * pixels, a value of 0 disables this feature and in this case only the default |
16211 | * indentation will be used. |
16212 | * This does not have any visible effects for lists. |
16213 | * |
16214 | * Since: 2.12 |
16215 | */ |
16216 | void |
16217 | ctk_tree_view_set_level_indentation (CtkTreeView *tree_view, |
16218 | gint indentation) |
16219 | { |
16220 | tree_view->priv->level_indentation = indentation; |
16221 | |
16222 | ctk_widget_queue_draw (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ()))))))); |
16223 | } |
16224 | |
16225 | /** |
16226 | * ctk_tree_view_get_level_indentation: |
16227 | * @tree_view: a #CtkTreeView. |
16228 | * |
16229 | * Returns the amount, in pixels, of extra indentation for child levels |
16230 | * in @tree_view. |
16231 | * |
16232 | * Returns: the amount of extra indentation for child levels in |
16233 | * @tree_view. A return value of 0 means that this feature is disabled. |
16234 | * |
16235 | * Since: 2.12 |
16236 | */ |
16237 | gint |
16238 | ctk_tree_view_get_level_indentation (CtkTreeView *tree_view) |
16239 | { |
16240 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (0); } } while (0 ); |
16241 | |
16242 | return tree_view->priv->level_indentation; |
16243 | } |
16244 | |
16245 | /** |
16246 | * ctk_tree_view_set_tooltip_row: |
16247 | * @tree_view: a #CtkTreeView |
16248 | * @tooltip: a #CtkTooltip |
16249 | * @path: a #CtkTreePath |
16250 | * |
16251 | * Sets the tip area of @tooltip to be the area covered by the row at @path. |
16252 | * See also ctk_tree_view_set_tooltip_column() for a simpler alternative. |
16253 | * See also ctk_tooltip_set_tip_area(). |
16254 | * |
16255 | * Since: 2.12 |
16256 | */ |
16257 | void |
16258 | ctk_tree_view_set_tooltip_row (CtkTreeView *tree_view, |
16259 | CtkTooltip *tooltip, |
16260 | CtkTreePath *path) |
16261 | { |
16262 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
16263 | g_return_if_fail (CTK_IS_TOOLTIP (tooltip))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tooltip)); GType __t = ((ctk_tooltip_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TOOLTIP (tooltip)"); return; } } while (0); |
16264 | |
16265 | ctk_tree_view_set_tooltip_cell (tree_view, tooltip, path, NULL((void*)0), NULL((void*)0)); |
16266 | } |
16267 | |
16268 | /** |
16269 | * ctk_tree_view_set_tooltip_cell: |
16270 | * @tree_view: a #CtkTreeView |
16271 | * @tooltip: a #CtkTooltip |
16272 | * @path: (allow-none): a #CtkTreePath or %NULL |
16273 | * @column: (allow-none): a #CtkTreeViewColumn or %NULL |
16274 | * @cell: (allow-none): a #CtkCellRenderer or %NULL |
16275 | * |
16276 | * Sets the tip area of @tooltip to the area @path, @column and @cell have |
16277 | * in common. For example if @path is %NULL and @column is set, the tip |
16278 | * area will be set to the full area covered by @column. See also |
16279 | * ctk_tooltip_set_tip_area(). |
16280 | * |
16281 | * Note that if @path is not specified and @cell is set and part of a column |
16282 | * containing the expander, the tooltip might not show and hide at the correct |
16283 | * position. In such cases @path must be set to the current node under the |
16284 | * mouse cursor for this function to operate correctly. |
16285 | * |
16286 | * See also ctk_tree_view_set_tooltip_column() for a simpler alternative. |
16287 | * |
16288 | * Since: 2.12 |
16289 | */ |
16290 | void |
16291 | ctk_tree_view_set_tooltip_cell (CtkTreeView *tree_view, |
16292 | CtkTooltip *tooltip, |
16293 | CtkTreePath *path, |
16294 | CtkTreeViewColumn *column, |
16295 | CtkCellRenderer *cell) |
16296 | { |
16297 | CtkAllocation allocation; |
16298 | CdkRectangle rect; |
16299 | |
16300 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
16301 | g_return_if_fail (CTK_IS_TOOLTIP (tooltip))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tooltip)); GType __t = ((ctk_tooltip_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TOOLTIP (tooltip)"); return; } } while (0); |
16302 | g_return_if_fail (column == NULL || CTK_IS_TREE_VIEW_COLUMN (column))do { if ((column == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((column)); GType __t = ((ctk_tree_view_column_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "column == NULL || CTK_IS_TREE_VIEW_COLUMN (column)" ); return; } } while (0); |
16303 | g_return_if_fail (cell == NULL || CTK_IS_CELL_RENDERER (cell))do { if ((cell == ((void*)0) || (((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ((cell)); GType __t = ((ctk_cell_renderer_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "cell == NULL || CTK_IS_CELL_RENDERER (cell)" ); return; } } while (0); |
16304 | |
16305 | /* Determine x values. */ |
16306 | if (column && cell) |
16307 | { |
16308 | CdkRectangle tmp; |
16309 | gint start, width; |
16310 | |
16311 | /* We always pass in path here, whether it is NULL or not. |
16312 | * For cells in expander columns path must be specified so that |
16313 | * we can correctly account for the indentation. This also means |
16314 | * that the tooltip is constrained vertically by the "Determine y |
16315 | * values" code below; this is not a real problem since cells actually |
16316 | * don't stretch vertically in constrast to columns. |
16317 | */ |
16318 | ctk_tree_view_get_cell_area (tree_view, path, column, &tmp); |
16319 | ctk_tree_view_column_cell_get_position (column, cell, &start, &width); |
16320 | |
16321 | ctk_tree_view_convert_bin_window_to_widget_coords (tree_view, |
16322 | tmp.x + start, 0, |
16323 | &rect.x, NULL((void*)0)); |
16324 | rect.width = width; |
16325 | } |
16326 | else if (column) |
16327 | { |
16328 | CdkRectangle tmp; |
16329 | |
16330 | ctk_tree_view_get_background_area (tree_view, NULL((void*)0), column, &tmp); |
16331 | ctk_tree_view_convert_bin_window_to_widget_coords (tree_view, |
16332 | tmp.x, 0, |
16333 | &rect.x, NULL((void*)0)); |
16334 | rect.width = tmp.width; |
16335 | } |
16336 | else |
16337 | { |
16338 | ctk_widget_get_allocation (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), &allocation); |
16339 | rect.x = 0; |
16340 | rect.width = allocation.width; |
16341 | } |
16342 | |
16343 | /* Determine y values. */ |
16344 | if (path) |
16345 | { |
16346 | CdkRectangle tmp; |
16347 | |
16348 | ctk_tree_view_get_background_area (tree_view, path, NULL((void*)0), &tmp); |
16349 | ctk_tree_view_convert_bin_window_to_widget_coords (tree_view, |
16350 | 0, tmp.y, |
16351 | NULL((void*)0), &rect.y); |
16352 | rect.height = tmp.height; |
16353 | } |
16354 | else |
16355 | { |
16356 | rect.y = 0; |
16357 | rect.height = ctk_adjustment_get_page_size (tree_view->priv->vadjustment); |
16358 | } |
16359 | |
16360 | ctk_tooltip_set_tip_area (tooltip, &rect); |
16361 | } |
16362 | |
16363 | /** |
16364 | * ctk_tree_view_get_tooltip_context: |
16365 | * @tree_view: a #CtkTreeView |
16366 | * @x: (inout): the x coordinate (relative to widget coordinates) |
16367 | * @y: (inout): the y coordinate (relative to widget coordinates) |
16368 | * @keyboard_tip: whether this is a keyboard tooltip or not |
16369 | * @model: (out) (optional) (nullable) (transfer none): a pointer to |
16370 | * receive a #CtkTreeModel or %NULL |
16371 | * @path: (out) (optional): a pointer to receive a #CtkTreePath or %NULL |
16372 | * @iter: (out) (optional): a pointer to receive a #CtkTreeIter or %NULL |
16373 | * |
16374 | * This function is supposed to be used in a #CtkWidget::query-tooltip |
16375 | * signal handler for #CtkTreeView. The @x, @y and @keyboard_tip values |
16376 | * which are received in the signal handler, should be passed to this |
16377 | * function without modification. |
16378 | * |
16379 | * The return value indicates whether there is a tree view row at the given |
16380 | * coordinates (%TRUE) or not (%FALSE) for mouse tooltips. For keyboard |
16381 | * tooltips the row returned will be the cursor row. When %TRUE, then any of |
16382 | * @model, @path and @iter which have been provided will be set to point to |
16383 | * that row and the corresponding model. @x and @y will always be converted |
16384 | * to be relative to @tree_view’s bin_window if @keyboard_tooltip is %FALSE. |
16385 | * |
16386 | * Returns: whether or not the given tooltip context points to a row. |
16387 | * |
16388 | * Since: 2.12 |
16389 | */ |
16390 | gboolean |
16391 | ctk_tree_view_get_tooltip_context (CtkTreeView *tree_view, |
16392 | gint *x, |
16393 | gint *y, |
16394 | gboolean keyboard_tip, |
16395 | CtkTreeModel **model, |
16396 | CtkTreePath **path, |
16397 | CtkTreeIter *iter) |
16398 | { |
16399 | CtkTreePath *tmppath = NULL((void*)0); |
16400 | |
16401 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), FALSE)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return ((0)); } } while ( 0); |
16402 | g_return_val_if_fail (x != NULL, FALSE)do { if ((x != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "x != NULL"); return ((0 )); } } while (0); |
16403 | g_return_val_if_fail (y != NULL, FALSE)do { if ((y != ((void*)0))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__)), "y != NULL"); return ((0 )); } } while (0); |
16404 | |
16405 | if (keyboard_tip) |
16406 | { |
16407 | ctk_tree_view_get_cursor (tree_view, &tmppath, NULL((void*)0)); |
16408 | |
16409 | if (!tmppath) |
16410 | return FALSE(0); |
16411 | } |
16412 | else |
16413 | { |
16414 | ctk_tree_view_convert_widget_to_bin_window_coords (tree_view, *x, *y, |
16415 | x, y); |
16416 | |
16417 | if (!ctk_tree_view_get_path_at_pos (tree_view, *x, *y, |
16418 | &tmppath, NULL((void*)0), NULL((void*)0), NULL((void*)0))) |
16419 | return FALSE(0); |
16420 | } |
16421 | |
16422 | if (model) |
16423 | *model = ctk_tree_view_get_model (tree_view); |
16424 | |
16425 | if (iter) |
16426 | ctk_tree_model_get_iter (ctk_tree_view_get_model (tree_view), |
16427 | iter, tmppath); |
16428 | |
16429 | if (path) |
16430 | *path = tmppath; |
16431 | else |
16432 | ctk_tree_path_free (tmppath); |
16433 | |
16434 | return TRUE(!(0)); |
16435 | } |
16436 | |
16437 | static gboolean |
16438 | ctk_tree_view_set_tooltip_query_cb (CtkWidget *widget, |
16439 | gint x, |
16440 | gint y, |
16441 | gboolean keyboard_tip, |
16442 | CtkTooltip *tooltip, |
16443 | gpointer data G_GNUC_UNUSED__attribute__ ((__unused__))) |
16444 | { |
16445 | GValue value = G_VALUE_INIT{ 0, { { 0 } } }; |
16446 | GValue transformed = G_VALUE_INIT{ 0, { { 0 } } }; |
16447 | CtkTreeIter iter; |
16448 | CtkTreePath *path; |
16449 | CtkTreeModel *model; |
16450 | CtkTreeView *tree_view = CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))); |
16451 | const char *transformed_str = NULL((void*)0); |
16452 | |
16453 | if (!ctk_tree_view_get_tooltip_context (CTK_TREE_VIEW (widget)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((widget)), ((ctk_tree_view_get_type ())))))), |
16454 | &x, &y, |
16455 | keyboard_tip, |
16456 | &model, &path, &iter)) |
16457 | return FALSE(0); |
16458 | |
16459 | ctk_tree_model_get_value (model, &iter, |
16460 | tree_view->priv->tooltip_column, &value); |
16461 | |
16462 | g_value_init (&transformed, G_TYPE_STRING((GType) ((16) << (2)))); |
16463 | |
16464 | if (!g_value_transform (&value, &transformed)) |
16465 | { |
16466 | g_value_unset (&value); |
16467 | ctk_tree_path_free (path); |
16468 | |
16469 | return FALSE(0); |
16470 | } |
16471 | |
16472 | g_value_unset (&value); |
16473 | |
16474 | transformed_str = g_value_get_string (&transformed); |
16475 | if (transformed_str == NULL((void*)0) || *transformed_str == '\0') |
16476 | { |
16477 | g_value_unset (&transformed); |
16478 | ctk_tree_path_free (path); |
16479 | |
16480 | return FALSE(0); |
16481 | } |
16482 | |
16483 | ctk_tooltip_set_markup (tooltip, transformed_str); |
16484 | ctk_tree_view_set_tooltip_row (tree_view, tooltip, path); |
16485 | |
16486 | ctk_tree_path_free (path); |
16487 | g_value_unset (&transformed); |
16488 | |
16489 | return TRUE(!(0)); |
16490 | } |
16491 | |
16492 | /** |
16493 | * ctk_tree_view_set_tooltip_column: |
16494 | * @tree_view: a #CtkTreeView |
16495 | * @column: an integer, which is a valid column number for @tree_view’s model |
16496 | * |
16497 | * If you only plan to have simple (text-only) tooltips on full rows, you |
16498 | * can use this function to have #CtkTreeView handle these automatically |
16499 | * for you. @column should be set to the column in @tree_view’s model |
16500 | * containing the tooltip texts, or -1 to disable this feature. |
16501 | * |
16502 | * When enabled, #CtkWidget:has-tooltip will be set to %TRUE and |
16503 | * @tree_view will connect a #CtkWidget::query-tooltip signal handler. |
16504 | * |
16505 | * Note that the signal handler sets the text with ctk_tooltip_set_markup(), |
16506 | * so &, <, etc have to be escaped in the text. |
16507 | * |
16508 | * Since: 2.12 |
16509 | */ |
16510 | void |
16511 | ctk_tree_view_set_tooltip_column (CtkTreeView *tree_view, |
16512 | gint column) |
16513 | { |
16514 | g_return_if_fail (CTK_IS_TREE_VIEW (tree_view))do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return; } } while (0); |
16515 | |
16516 | if (column == tree_view->priv->tooltip_column) |
16517 | return; |
16518 | |
16519 | if (column == -1) |
16520 | { |
16521 | g_signal_handlers_disconnect_by_func (tree_view,g_signal_handlers_disconnect_matched ((tree_view), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (ctk_tree_view_set_tooltip_query_cb), (((void*)0))) |
16522 | ctk_tree_view_set_tooltip_query_cb,g_signal_handlers_disconnect_matched ((tree_view), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (ctk_tree_view_set_tooltip_query_cb), (((void*)0))) |
16523 | NULL)g_signal_handlers_disconnect_matched ((tree_view), (GSignalMatchType ) (G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA), 0, 0, ((void*) 0), (ctk_tree_view_set_tooltip_query_cb), (((void*)0))); |
16524 | ctk_widget_set_has_tooltip (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), FALSE(0)); |
16525 | } |
16526 | else |
16527 | { |
16528 | if (tree_view->priv->tooltip_column == -1) |
16529 | { |
16530 | g_signal_connect (tree_view, "query-tooltip",g_signal_connect_data ((tree_view), ("query-tooltip"), (((GCallback ) (ctk_tree_view_set_tooltip_query_cb))), (((void*)0)), ((void *)0), (GConnectFlags) 0) |
16531 | G_CALLBACK (ctk_tree_view_set_tooltip_query_cb), NULL)g_signal_connect_data ((tree_view), ("query-tooltip"), (((GCallback ) (ctk_tree_view_set_tooltip_query_cb))), (((void*)0)), ((void *)0), (GConnectFlags) 0); |
16532 | ctk_widget_set_has_tooltip (CTK_WIDGET (tree_view)((((CtkWidget*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), ((ctk_widget_get_type ())))))), TRUE(!(0))); |
16533 | } |
16534 | } |
16535 | |
16536 | tree_view->priv->tooltip_column = column; |
16537 | g_object_notify_by_pspec (G_OBJECT (tree_view)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((tree_view)), (((GType) ((20) << (2)))))))), tree_view_props[PROP_TOOLTIP_COLUMN]); |
16538 | } |
16539 | |
16540 | /** |
16541 | * ctk_tree_view_get_tooltip_column: |
16542 | * @tree_view: a #CtkTreeView |
16543 | * |
16544 | * Returns the column of @tree_view’s model which is being used for |
16545 | * displaying tooltips on @tree_view’s rows. |
16546 | * |
16547 | * Returns: the index of the tooltip column that is currently being |
16548 | * used, or -1 if this is disabled. |
16549 | * |
16550 | * Since: 2.12 |
16551 | */ |
16552 | gint |
16553 | ctk_tree_view_get_tooltip_column (CtkTreeView *tree_view) |
16554 | { |
16555 | g_return_val_if_fail (CTK_IS_TREE_VIEW (tree_view), 0)do { if (((((__extension__ ({ GTypeInstance *__inst = (GTypeInstance *) ((tree_view)); GType __t = ((ctk_tree_view_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; })))))) { } else { g_return_if_fail_warning ("Ctk", ((const char*) (__func__ )), "CTK_IS_TREE_VIEW (tree_view)"); return (0); } } while (0 ); |
16556 | |
16557 | return tree_view->priv->tooltip_column; |
16558 | } |
16559 | |
16560 | static gboolean |
16561 | ctk_tree_view_get_border (CtkScrollable *scrollable, |
16562 | CtkBorder *border) |
16563 | { |
16564 | border->top = _ctk_tree_view_get_header_height (CTK_TREE_VIEW (scrollable)((((CtkTreeView*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((scrollable)), ((ctk_tree_view_get_type ()))))))); |
16565 | |
16566 | return TRUE(!(0)); |
16567 | } |
16568 | |
16569 | static void |
16570 | ctk_tree_view_scrollable_init (CtkScrollableInterface *iface) |
16571 | { |
16572 | iface->get_border = ctk_tree_view_get_border; |
16573 | } |