ARB
NT_sync_scroll.cxx
Go to the documentation of this file.
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 <TreeDisplay.hxx>
15 
16 #include <aw_msg.hxx>
17 #include <aw_root.hxx>
18 #include <aw_awar.hxx>
19 #include <aw_select.hxx>
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 
27 
28 inline 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);
37 
38  return buffer;
39 }
40 
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 
48 static unsigned auto_refresh_cb(AW_root*) {
49  synchronizer.auto_update();
50  return 0; // do not call again
51 }
52 
53 static 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 
61 static 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);
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 
85 static void explicit_scroll_sync_cb(AW_window*, int tgt_idx) {
86  aw_message_if(synchronizer.update_explicit(tgt_idx));
87 }
88 
90  AW_window_simple *aws = new AW_window_simple;
91 
92  int ntw_idx = ntw->get_index();
93  nt_assert(ntw_idx>=0);
94 
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 
CONSTEXPR_INLINE bool valid_canvas_index(int idx)
const char * GB_ERROR
Definition: arb_core.h:25
static unsigned auto_refresh_cb(AW_root *)
#define implicated(hypothesis, conclusion)
Definition: arb_assert.h:289
void insert_default(const char *displayed, const AW_scalar &value)
Definition: AW_select.cxx:385
const char * awarname(const char *awarname_template, int idx)
void announce_update(int canvas_idx)
long read_int() const
Definition: AW_awar.cxx:187
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
AW_root * awr
Definition: awt_canvas.hxx:338
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
static void explicit_scroll_sync_cb(AW_window *, int tgt_idx)
static ScrollSynchronizer synchronizer
void add_timed_callback(int ms, const TimedCallback &tcb)
Definition: AW_root.cxx:538
AW_window * NT_create_syncScroll_window(AW_root *awr, TREE_canvas *ntw)
TREE_canvas * NT_get_canvas_by_index(int idx)
Definition: NT_extern.cxx:943
#define NO_SCROLL_SYNC
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
static void refill_syncWithList_cb(AW_root *, AW_selection_list *sellst, TREE_canvas *ntw)
#define DOWNCAST(totype, expr)
Definition: downcast.h:141
AW_awar * add_callback(const RootCallback &cb)
Definition: AW_awar.cxx:234
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
static void sync_changed_cb(AW_root *awr, int slave_idx)
#define MAX_NT_WINDOWS
Definition: NT_local.h:31
#define AWAR_NTREE_MAIN_WINDOW_COUNT
Definition: NT_local.h:29
static void error(const char *msg)
Definition: mkptypes.cxx:96
void at_screen_update_call(screen_update_callback cb, AW_CL cd)
#define MAX_AWARNAME_LENGTH
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
int get_index() const
GB_ERROR update_explicit(int slave_idx)
#define nt_assert(cond)
Definition: NT_local.h:27
void update_implicit(int slave_idx)
char * awar_name
Definition: aw_awar.hxx:103
GB_ERROR define_dependency(int slave_idx, int master_idx, bool auto_sync)
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
long AW_CL
Definition: cb.h:21
void aw_message(const char *msg)
Definition: AW_status.cxx:932
static void canvas_updated_cb(AWT_canvas *ntw, AW_CL)
void NT_fill_canvas_selection_list(class AW_selection_list *sellst, TREE_canvas *to_skip)
Definition: NT_extern.cxx:964
#define AWAR_TEMPL_SYNCED_WITH_WINDOW
#define AWAR_TEMPL_AUTO_SYNCED
#define AW_ROOT_DEFAULT
Definition: aw_base.hxx:106
GB_ERROR write_int(long aw_int)
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
char * GBS_global_string_copy(const char *templat,...)
Definition: arb_msg.cxx:195