source: tags/ms_r16q3/NTREE/NT_sync_scroll.cxx

Last change on this file was 15340, checked in by westram, 8 years ago
File size: 4.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_sync_scroll.cxx                                //
4//   Purpose   : Sync tree scrolling                               //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in October 2016   //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "ScrollSynchronizer.h"
12#include "NT_sync_scroll.h"
13
14#include <aw_msg.hxx>
15#include <aw_root.hxx>
16#include <aw_awar.hxx>
17#include <aw_select.hxx>
18
19#include <downcast.h>
20
21#define AWAR_TEMPL_SYNCED_WITH_WINDOW "tmp/sync%i/with"
22#define AWAR_TEMPL_AUTO_SYNCED        "tmp/sync%i/auto"
23
24#define MAX_AWARNAME_LENGTH (3+1+5+1+4)
25
26static ScrollSynchronizer synchronizer;
27
28inline const char *awarname(const char *awarname_template, int idx) {
29    nt_assert(idx>=0 && idx<MAX_NT_WINDOWS);
30    static char buffer[MAX_AWARNAME_LENGTH+1];
31
32#if defined(ASSERTION_USED)
33    int printed =
34#endif
35        sprintf(buffer, awarname_template, idx);
36    nt_assert(printed<=MAX_AWARNAME_LENGTH);
37
38    return buffer;
39}
40
41static void refill_syncWithList_cb(AW_root *, AW_selection_list *sellst, TREE_canvas *ntw) {
42    sellst->clear();
43    NT_fill_canvas_selection_list(sellst, ntw);
44    sellst->insert_default("<don't sync>", NO_SCROLL_SYNC);
45    sellst->update();
46}
47
48static unsigned auto_refresh_cb(AW_root*) {
49    synchronizer.auto_update();
50    return 0; // do not call again
51}
52
53static void canvas_updated_cb(AWT_canvas *ntw, AW_CL /*cd*/) {
54    TREE_canvas *tw = DOWNCAST(TREE_canvas*, ntw);
55    synchronizer.announce_update(tw->get_index());
56
57    AW_root *awr = ntw->awr;
58    awr->add_timed_callback(250, makeTimedCallback(auto_refresh_cb));
59}
60
61static void sync_changed_cb(AW_root *awr, int slave_idx) {
62    AW_awar *awar_sync_with = awr->awar(awarname(AWAR_TEMPL_SYNCED_WITH_WINDOW, slave_idx));
63    AW_awar *awar_autosync  = awr->awar(awarname(AWAR_TEMPL_AUTO_SYNCED,        slave_idx));
64
65    int  master_idx = awar_sync_with->read_int();
66    bool autosync   = awar_autosync->read_int();
67
68    if (valid_canvas_index(master_idx)) {
69        TREE_canvas *master = NT_get_canvas_by_index(master_idx);
70        master->at_screen_update_call(canvas_updated_cb, 0);
71    }
72
73    GB_ERROR error = synchronizer.define_dependency(slave_idx, master_idx, autosync);
74    nt_assert(implicated(error, autosync)); // error may only occur if autosync is ON
75
76    if (error) {
77        aw_message(GBS_global_string("Auto-sync turned off (%s)", error));
78        awar_autosync->write_int(0);
79    }
80    else {
81        synchronizer.update_implicit(slave_idx);
82    }
83}
84
85static void explicit_scroll_sync_cb(AW_window*, int tgt_idx) {
86    aw_message_if(synchronizer.update_explicit(tgt_idx));
87}
88
89AW_window *NT_create_syncScroll_window(AW_root *awr, TREE_canvas *ntw) {
90    AW_window_simple *aws = new AW_window_simple;
91
92    int ntw_idx = ntw->get_index();
93    nt_assert(ntw_idx>=0);
94
95    AW_awar *awar_sync_with = awr->awar_int(awarname(AWAR_TEMPL_SYNCED_WITH_WINDOW, ntw_idx), NO_SCROLL_SYNC, AW_ROOT_DEFAULT);
96    AW_awar *awar_autosync  = awr->awar_int(awarname(AWAR_TEMPL_AUTO_SYNCED,        ntw_idx), 0,              AW_ROOT_DEFAULT);
97
98    {
99        char *wid = GBS_global_string_copy("SYNC_TREE_SCROLL_%i", ntw_idx);
100        aws->init(awr, wid,
101                  ntw_idx>0
102                  ? GBS_global_string("Synchronize tree scrolling (%i)", ntw_idx)
103                  : "Synchronize tree scrolling");
104        free(wid);
105    }
106    aws->load_xfig("syncscroll.fig");
107
108    aws->at("close");
109    aws->callback(AW_POPDOWN);
110    aws->create_button("CLOSE", "CLOSE", "C");
111
112    aws->at("help");
113    aws->callback(makeHelpCallback("syncscroll.hlp"));
114    aws->create_button("HELP", "HELP", "H");
115
116    RootCallback sync_changed_rcb = makeRootCallback(sync_changed_cb, ntw_idx);
117    {
118        aws->at("box");
119        AW_selection_list *sellist = aws->create_selection_list(awar_sync_with->awar_name, true);
120
121        // refill list when new main-windows are created:
122        RootCallback refill_sellist_cb = makeRootCallback(refill_syncWithList_cb, sellist, ntw);
123        awr->awar(AWAR_NTREE_MAIN_WINDOW_COUNT)->add_callback(refill_sellist_cb);
124        refill_sellist_cb(awr);
125
126        awar_sync_with->add_callback(sync_changed_rcb); // resync when source changes
127    }
128
129    aws->at("dosync");
130    aws->callback(makeWindowCallback(explicit_scroll_sync_cb, ntw_idx));
131    aws->create_autosize_button("SYNC_SCROLL", "Sync scroll");
132
133    aws->at("autosync");
134    aws->label("Auto-sync?");
135    aws->create_toggle(awar_autosync->awar_name);
136
137    awar_autosync->add_callback(sync_changed_rcb); // resync when auto-sync changes (master may have been scrolled since last sync)
138
139    return aws;
140}
141
142
Note: See TracBrowser for help on using the repository browser.