Merge lp:~elementary-apps/granite/dynamicnotebook into lp:~elementary-pantheon/granite/granite
- dynamicnotebook
- Merge into granite
Proposed by
Rico Tzschichholz
Status: | Work in progress |
---|---|
Proposed branch: | lp:~elementary-apps/granite/dynamicnotebook |
Merge into: | lp:~elementary-pantheon/granite/granite |
Diff against target: |
323 lines (+147/-73) 1 file modified
lib/Widgets/DynamicNotebook.vala (+147/-73) |
To merge this branch: | bzr merge lp:~elementary-apps/granite/dynamicnotebook |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cody Garver (community) | Needs Information | ||
Tom Beckmann | Pending | ||
Review via email: mp+157874@code.launchpad.net |
Commit message
Description of the change
Just here to see a nice diff against trunk.
To post a comment you must log in.
- 559. By Rico Tzschichholz
-
Move dummy new_window callback for tab
Revision history for this message
David Gomes (davidgomes) wrote : | # |
It's not perfect yet. I've been wanting to work on time but I still didn't have enough free time.
Revision history for this message
Cody Garver (codygarver) wrote : | # |
Should the status of this branch be Rejected now that xapantu has got a DN fix in trunk?
review:
Needs Information
Revision history for this message
xapantu (xapantu) wrote : | # |
This branch does not fix the same bug, while my code just fixed the current bug, this is a larger refactoring of the way the DynamicNotebook works, which is interesting since this way is much more logical. The tab_moved signal is really not practical (the only good point in it is that everything can be handled with one signal, but I am not sure it is a very good idea).
Unmerged revisions
- 559. By Rico Tzschichholz
-
Move dummy new_window callback for tab
- 558. By Rico Tzschichholz
-
Avoid breaking ABI/API
- 557. By Tom Beckmann
-
Do proper signal handling fixing detaching tabs
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/Widgets/DynamicNotebook.vala' | |||
2 | --- lib/Widgets/DynamicNotebook.vala 2013-04-05 07:11:07 +0000 | |||
3 | +++ lib/Widgets/DynamicNotebook.vala 2013-04-10 09:31:27 +0000 | |||
4 | @@ -314,13 +314,40 @@ | |||
5 | 314 | private int tab_width = 150; | 314 | private int tab_width = 150; |
6 | 315 | private int max_tab_width = 150; | 315 | private int max_tab_width = 150; |
7 | 316 | 316 | ||
8 | 317 | /** | ||
9 | 318 | * A new tab was added | ||
10 | 319 | * @param tab the new Tab | ||
11 | 320 | */ | ||
12 | 317 | public signal void tab_added (Tab tab); | 321 | public signal void tab_added (Tab tab); |
13 | 322 | |||
14 | 323 | /** | ||
15 | 324 | * A new tab was added | ||
16 | 325 | * Note: The return value has no meaning! | ||
17 | 326 | * @param tab the removed Tab | ||
18 | 327 | */ | ||
19 | 318 | public signal bool tab_removed (Tab tab); | 328 | public signal bool tab_removed (Tab tab); |
21 | 319 | Tab? old_tab; //stores a reference for tab_switched | 329 | |
22 | 330 | unowned Tab? old_tab; //stores a reference for tab_switched | ||
23 | 320 | public signal void tab_switched (Tab? old_tab, Tab new_tab); | 331 | public signal void tab_switched (Tab? old_tab, Tab new_tab); |
24 | 332 | |||
25 | 333 | //FIXME can be removed on API cleaning | ||
26 | 334 | /** | ||
27 | 335 | * Connect to tab_create_window and tab_reordered instead | ||
28 | 336 | */ | ||
29 | 337 | [Deprecated (since=0.2)] | ||
30 | 321 | public signal void tab_moved (Tab tab, int new_pos, bool new_window, int x, int y); | 338 | public signal void tab_moved (Tab tab, int new_pos, bool new_window, int x, int y); |
31 | 339 | |||
32 | 322 | public signal void tab_duplicated (Tab duplicated_tab); | 340 | public signal void tab_duplicated (Tab duplicated_tab); |
33 | 323 | 341 | ||
34 | 342 | public signal void tab_reordered (Tab tab, int new_pos); | ||
35 | 343 | |||
36 | 344 | /** | ||
37 | 345 | * A tab was detached. You're supposed to connect to this signal | ||
38 | 346 | * and return the notebook this tab should be added or null, if | ||
39 | 347 | * you want to handle adding it manually | ||
40 | 348 | */ | ||
41 | 349 | public signal DynamicNotebook? tab_detached (Tab tab, int x, int y); | ||
42 | 350 | |||
43 | 324 | private static const string CLOSE_BUTTON_STYLE = """ | 351 | private static const string CLOSE_BUTTON_STYLE = """ |
44 | 325 | * { | 352 | * { |
45 | 326 | -GtkButton-default-border : 0; | 353 | -GtkButton-default-border : 0; |
46 | @@ -366,14 +393,12 @@ | |||
47 | 366 | new_tab_m.activate.connect (() => { | 393 | new_tab_m.activate.connect (() => { |
48 | 367 | var t = new Tab (); | 394 | var t = new Tab (); |
49 | 368 | notebook.page = (int) this.insert_tab (t, -1); | 395 | notebook.page = (int) this.insert_tab (t, -1); |
50 | 369 | this.tab_added (t); | ||
51 | 370 | }); | 396 | }); |
52 | 371 | 397 | ||
53 | 372 | this.button_press_event.connect ((e) => { | 398 | this.button_press_event.connect ((e) => { |
54 | 373 | if (e.type == Gdk.EventType.2BUTTON_PRESS && e.button == 1) { | 399 | if (e.type == Gdk.EventType.2BUTTON_PRESS && e.button == 1) { |
55 | 374 | var t = new Tab (); | 400 | var t = new Tab (); |
56 | 375 | notebook.page = (int) this.insert_tab (t, -1); | 401 | notebook.page = (int) this.insert_tab (t, -1); |
57 | 376 | this.tab_added (t); | ||
58 | 377 | } else if (e.button == 3) { | 402 | } else if (e.button == 3) { |
59 | 378 | menu.popup (null, null, null, 3, e.time); | 403 | menu.popup (null, null, null, 3, e.time); |
60 | 379 | } | 404 | } |
61 | @@ -393,7 +418,6 @@ | |||
62 | 393 | add.clicked.connect ( () => { | 418 | add.clicked.connect ( () => { |
63 | 394 | var t = new Tab (); | 419 | var t = new Tab (); |
64 | 395 | notebook.page = (int) this.insert_tab (t, -1); | 420 | notebook.page = (int) this.insert_tab (t, -1); |
65 | 396 | this.tab_added (t); | ||
66 | 397 | }); | 421 | }); |
67 | 398 | 422 | ||
68 | 399 | this.size_allocate.connect (() => { | 423 | this.size_allocate.connect (() => { |
69 | @@ -416,7 +440,6 @@ | |||
70 | 416 | case Gdk.Key.@T: | 440 | case Gdk.Key.@T: |
71 | 417 | if ((e.state & Gdk.ModifierType.CONTROL_MASK) == Gdk.ModifierType.CONTROL_MASK) { | 441 | if ((e.state & Gdk.ModifierType.CONTROL_MASK) == Gdk.ModifierType.CONTROL_MASK) { |
72 | 418 | var t = new Tab (); | 442 | var t = new Tab (); |
73 | 419 | this.tab_added (t); | ||
74 | 420 | notebook.page = (int) this.insert_tab (t, -1); | 443 | notebook.page = (int) this.insert_tab (t, -1); |
75 | 421 | return true; | 444 | return true; |
76 | 422 | } | 445 | } |
77 | @@ -467,35 +490,80 @@ | |||
78 | 467 | return false; | 490 | return false; |
79 | 468 | }); | 491 | }); |
80 | 469 | 492 | ||
81 | 493 | notebook.page_added.connect (on_page_added); | ||
82 | 494 | notebook.page_removed.connect (on_page_removed); | ||
83 | 470 | notebook.switch_page.connect (on_switch_page); | 495 | notebook.switch_page.connect (on_switch_page); |
84 | 471 | notebook.page_reordered.connect (on_page_reordered); | 496 | notebook.page_reordered.connect (on_page_reordered); |
85 | 472 | notebook.create_window.connect (on_create_window); | 497 | notebook.create_window.connect (on_create_window); |
86 | 473 | } | 498 | } |
87 | 474 | 499 | ||
88 | 475 | ~Notebook () { | 500 | ~Notebook () { |
89 | 501 | notebook.page_added.disconnect (on_page_added); | ||
90 | 502 | notebook.page_removed.disconnect (on_page_removed); | ||
91 | 476 | notebook.switch_page.disconnect (on_switch_page); | 503 | notebook.switch_page.disconnect (on_switch_page); |
92 | 477 | notebook.page_reordered.disconnect (on_page_reordered); | 504 | notebook.page_reordered.disconnect (on_page_reordered); |
93 | 478 | notebook.create_window.disconnect (on_create_window); | 505 | notebook.create_window.disconnect (on_create_window); |
94 | 479 | } | 506 | } |
95 | 480 | 507 | ||
98 | 481 | void on_switch_page (Gtk.Widget page, uint pagenum) { | 508 | void on_switch_page (Gtk.Notebook notebook, Gtk.Widget page, uint pagenum) { |
99 | 482 | var new_tab = notebook.get_tab_label (page) as Tab; | 509 | unowned Tab? new_tab = notebook.get_tab_label (page) as Tab; |
100 | 510 | if (new_tab == null) | ||
101 | 511 | return; | ||
102 | 483 | 512 | ||
104 | 484 | tab_switched (old_tab, new_tab); | 513 | unowned Tab? current_tab = old_tab as Tab; |
105 | 485 | old_tab = new_tab; | 514 | old_tab = new_tab; |
110 | 486 | } | 515 | |
111 | 487 | 516 | tab_switched (current_tab, new_tab); | |
112 | 488 | void on_page_reordered (Gtk.Widget page, uint pagenum) { | 517 | } |
113 | 489 | tab_moved (notebook.get_tab_label (page) as Tab, (int) pagenum, false, -1, -1); | 518 | |
114 | 519 | void on_page_reordered (Gtk.Notebook notebook, Gtk.Widget page, uint pagenum) { | ||
115 | 520 | unowned Tab? tab = notebook.get_tab_label (page) as Tab; | ||
116 | 521 | if (tab == null) | ||
117 | 522 | return; | ||
118 | 523 | |||
119 | 524 | //FIXME must be removed on API cleaning | ||
120 | 525 | if (Signal.has_handler_pending (this, Signal.lookup ("tab-moved", typeof (DynamicNotebook)), 0, true)) { | ||
121 | 526 | // Filled up with dummy values to preserve API | ||
122 | 527 | tab_moved (tab, (int)pagenum, false, 0, 0); | ||
123 | 528 | return; | ||
124 | 529 | } | ||
125 | 530 | |||
126 | 531 | tab_reordered (tab, (int)pagenum); | ||
127 | 532 | } | ||
128 | 533 | |||
129 | 534 | void on_page_removed (Gtk.Notebook notebook, Gtk.Widget page, uint pagenum) { | ||
130 | 535 | unowned Tab? tab = page as Tab; | ||
131 | 536 | if (tab == null) | ||
132 | 537 | return; | ||
133 | 538 | |||
134 | 539 | disconnect_tab_signals (tab); | ||
135 | 540 | tab_removed (tab); | ||
136 | 541 | } | ||
137 | 542 | |||
138 | 543 | void on_page_added (Gtk.Notebook notebook, Gtk.Widget page, uint pagenum) { | ||
139 | 544 | unowned Tab? tab = notebook.get_tab_label (page) as Tab; | ||
140 | 545 | if (tab == null) | ||
141 | 546 | return; | ||
142 | 547 | |||
143 | 548 | connect_tab_signals (tab); | ||
144 | 549 | tab_added (tab); | ||
145 | 490 | } | 550 | } |
146 | 491 | 551 | ||
147 | 492 | unowned Gtk.Notebook on_create_window (Gtk.Widget page, int x, int y) { | 552 | unowned Gtk.Notebook on_create_window (Gtk.Widget page, int x, int y) { |
154 | 493 | var tab = notebook.get_tab_label (page) as Tab; | 553 | Tab? tab = notebook.get_tab_label (page) as Tab; |
155 | 494 | notebook.remove_page (notebook.page_num (tab.page_container)); | 554 | if (tab == null) |
156 | 495 | tab.page_container.destroy (); | 555 | return null; |
157 | 496 | 556 | ||
158 | 497 | tab_moved (tab, 0, true, x, y); | 557 | remove_tab (tab); |
159 | 498 | return null; | 558 | |
160 | 559 | //FIXME must be removed on API cleaning | ||
161 | 560 | if (Signal.has_handler_pending (this, Signal.lookup ("tab-moved", typeof (DynamicNotebook)), 0, true)) { | ||
162 | 561 | tab_moved (tab, 0, true, x, y); | ||
163 | 562 | return null; | ||
164 | 563 | } | ||
165 | 564 | |||
166 | 565 | var new_notebook = tab_detached (notebook.get_tab_label (page) as Tab, x, y); | ||
167 | 566 | return new_notebook != null ? new_notebook.notebook : null; | ||
168 | 499 | } | 567 | } |
169 | 500 | 568 | ||
170 | 501 | private void recalc_size () { | 569 | private void recalc_size () { |
171 | @@ -516,25 +584,19 @@ | |||
172 | 516 | } | 584 | } |
173 | 517 | 585 | ||
174 | 518 | public void remove_tab (Tab tab) { | 586 | public void remove_tab (Tab tab) { |
175 | 519 | if (Signal.has_handler_pending (this, Signal.lookup ("tab-removed", typeof (DynamicNotebook)), 0, true)) { | ||
176 | 520 | var sure = tab_removed (tab); | ||
177 | 521 | if (!sure) | ||
178 | 522 | return; | ||
179 | 523 | } | ||
180 | 524 | |||
181 | 525 | var pos = get_tab_position (tab); | 587 | var pos = get_tab_position (tab); |
185 | 526 | if (pos != -1) | 588 | if (pos < 0) |
186 | 527 | notebook.remove_page (pos); | 589 | return; |
187 | 528 | tab.page_container.destroy (); | 590 | |
188 | 591 | notebook.remove_page (pos); | ||
189 | 529 | } | 592 | } |
190 | 530 | 593 | ||
191 | 531 | public void next_page () { | 594 | public void next_page () { |
193 | 532 | this.notebook.page = this.notebook.page + 1 >= this.notebook.get_n_pages () ? this.notebook.page = 0 : this.notebook.page + 1; | 595 | notebook.next_page (); |
194 | 533 | } | 596 | } |
195 | 534 | 597 | ||
196 | 535 | public void previous_page () { | 598 | public void previous_page () { |
199 | 536 | this.notebook.page = this.notebook.page - 1 < 0 ? | 599 | notebook.prev_page (); |
198 | 537 | this.notebook.page = this.notebook.get_n_pages () - 1 : this.notebook.page - 1; | ||
200 | 538 | } | 600 | } |
201 | 539 | 601 | ||
202 | 540 | public override void show () { | 602 | public override void show () { |
203 | @@ -558,7 +620,6 @@ | |||
204 | 558 | 620 | ||
205 | 559 | public void set_tab_position (Tab tab, int position) { | 621 | public void set_tab_position (Tab tab, int position) { |
206 | 560 | notebook.reorder_child (tab.page_container, position); | 622 | notebook.reorder_child (tab.page_container, position); |
207 | 561 | tab_moved (tab, position, false, -1, -1); | ||
208 | 562 | } | 623 | } |
209 | 563 | 624 | ||
210 | 564 | public Tab? get_tab_by_index (int index) { | 625 | public Tab? get_tab_by_index (int index) { |
211 | @@ -576,15 +637,6 @@ | |||
212 | 576 | public uint insert_tab (Tab tab, int index) { | 637 | public uint insert_tab (Tab tab, int index) { |
213 | 577 | return_if_fail (tabs.index (tab) < 0); | 638 | return_if_fail (tabs.index (tab) < 0); |
214 | 578 | 639 | ||
215 | 579 | var i = 0; | ||
216 | 580 | if (index == -1) | ||
217 | 581 | i = this.notebook.insert_page (tab.page_container, tab, this.notebook.get_n_pages ()); | ||
218 | 582 | else | ||
219 | 583 | i = this.notebook.insert_page (tab.page_container, tab, index); | ||
220 | 584 | |||
221 | 585 | this.notebook.set_tab_reorderable (tab.page_container, this.allow_drag); | ||
222 | 586 | this.notebook.set_tab_detachable (tab.page_container, this.allow_new_window); | ||
223 | 587 | |||
224 | 588 | tab._icon.visible = show_icons; | 640 | tab._icon.visible = show_icons; |
225 | 589 | tab.duplicate_m.visible = allow_duplication; | 641 | tab.duplicate_m.visible = allow_duplication; |
226 | 590 | tab.new_window_m.visible = allow_new_window; | 642 | tab.new_window_m.visible = allow_new_window; |
227 | @@ -592,41 +644,63 @@ | |||
228 | 592 | tab.width_request = tab_width; | 644 | tab.width_request = tab_width; |
229 | 593 | tab.close.get_style_context ().add_provider (button_fix, | 645 | tab.close.get_style_context ().add_provider (button_fix, |
230 | 594 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); | 646 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); |
264 | 595 | 647 | tab.close.visible = tabs_closable; | |
265 | 596 | tab.closed.connect ( () => { | 648 | |
266 | 597 | remove_tab (tab); | 649 | uint i = 0; |
267 | 598 | }); | 650 | if (index == -1) |
268 | 599 | 651 | i = notebook.insert_page (tab.page_container, tab, notebook.get_n_pages ()); | |
269 | 600 | tab.close_others.connect ( () => { | 652 | else |
270 | 601 | var num = 0; //save num, in case a tab refused to close so we don't end up in an infinite loop | 653 | i = notebook.insert_page (tab.page_container, tab, index); |
271 | 602 | 654 | ||
272 | 603 | for (var j = 0; j < tabs.length (); j++) { | 655 | notebook.set_tab_reorderable (tab.page_container, allow_drag); |
273 | 604 | if (tab != tabs.nth_data (j)) { | 656 | notebook.set_tab_detachable (tab.page_container, allow_new_window); |
274 | 605 | tabs.nth_data (j).closed (); | 657 | |
275 | 606 | if (num == n_tabs) break; | 658 | recalc_size (); |
243 | 607 | j--; | ||
244 | 608 | } | ||
245 | 609 | |||
246 | 610 | num = n_tabs; | ||
247 | 611 | } | ||
248 | 612 | }); | ||
249 | 613 | |||
250 | 614 | tab.new_window.connect (() => { | ||
251 | 615 | notebook.remove_page (notebook.page_num (tab.page_container)); | ||
252 | 616 | tab.page_container.destroy (); | ||
253 | 617 | tab_moved (tab, 0, true, 0, 0); | ||
254 | 618 | }); | ||
255 | 619 | |||
256 | 620 | tab.duplicate.connect (() => { | ||
257 | 621 | tab_duplicated (tab); | ||
258 | 622 | }); | ||
259 | 623 | |||
260 | 624 | this.recalc_size (); | ||
261 | 625 | |||
262 | 626 | if (!tabs_closable) | ||
263 | 627 | tab.close.visible = false; | ||
276 | 628 | 659 | ||
277 | 629 | return i; | 660 | return i; |
278 | 630 | } | 661 | } |
279 | 662 | |||
280 | 663 | void connect_tab_signals (Tab tab) { | ||
281 | 664 | tab.closed.connect (on_tab_closed); | ||
282 | 665 | tab.close_others.connect (on_close_others); | ||
283 | 666 | tab.new_window.connect (on_tab_new_window); | ||
284 | 667 | tab.duplicate.connect (on_tab_duplicated); | ||
285 | 668 | } | ||
286 | 669 | |||
287 | 670 | void disconnect_tab_signals (Tab tab) { | ||
288 | 671 | tab.closed.disconnect (on_tab_closed); | ||
289 | 672 | tab.close_others.disconnect (on_close_others); | ||
290 | 673 | tab.new_window.disconnect (on_tab_new_window); | ||
291 | 674 | tab.duplicate.disconnect (on_tab_duplicated); | ||
292 | 675 | } | ||
293 | 676 | |||
294 | 677 | void on_tab_duplicated (Tab tab) { | ||
295 | 678 | tab_duplicated (tab); | ||
296 | 679 | } | ||
297 | 680 | |||
298 | 681 | void on_tab_new_window (Tab tab) { | ||
299 | 682 | //notebook.remove_page (notebook.page_num (tab.page_container)); | ||
300 | 683 | //tab.page_container.destroy (); | ||
301 | 684 | //notebook.create_window (tab.page_container, -1, -1); | ||
302 | 685 | } | ||
303 | 686 | |||
304 | 687 | void on_tab_closed (Tab tab) { | ||
305 | 688 | remove_tab (tab); | ||
306 | 689 | } | ||
307 | 690 | |||
308 | 691 | void on_close_others (Tab tab) { | ||
309 | 692 | var num = 0; //save num, in case a tab refused to close so we don't end up in an infinite loop | ||
310 | 693 | |||
311 | 694 | for (var j = 0; j < tabs.length (); j++) { | ||
312 | 695 | unowned Tab t = tabs.nth_data (j); | ||
313 | 696 | if (tab != t) { | ||
314 | 697 | t.closed (); | ||
315 | 698 | if (num == n_tabs) break; | ||
316 | 699 | j--; | ||
317 | 700 | } | ||
318 | 701 | |||
319 | 702 | num = n_tabs; | ||
320 | 703 | } | ||
321 | 704 | } | ||
322 | 631 | } | 705 | } |
323 | 632 | } | 706 | } |
What's the hold up here?