source: tags/ms_r18q1/NTREE/NT_shadeTree.cxx

Last change on this file was 16763, checked in by westram, 6 years ago
File size: 5.1 KB
Line 
1// ============================================================ //
2//                                                              //
3//   File      : NT_shadeTree.cxx                               //
4//   Purpose   :                                                //
5//                                                              //
6//   Coded by Ralf Westram (coder@reallysoft.de) in June 2016   //
7//   http://www.arb-home.de/                                    //
8//                                                              //
9// ============================================================ //
10
11#include "tree_position.h"
12
13#include <TreeDisplay.hxx>
14#include <AP_TreeShader.hxx>
15
16#include <awt_canvas.hxx>
17
18#include <aw_root.hxx>
19#include <aw_awar.hxx>
20#include <aw_awar_defs.hxx>
21
22#define nt_assert(cond) arb_assert(cond)
23
24// ------------------------
25//      TopologyShader
26
27typedef SmartPtr<TreePositionLookup> TreePositionLookupPtr;
28
29class TopologyShader: public ShaderPlugin {
30    RefPtr<AWT_graphic_tree> agt;
31    mutable TreePositionLookupPtr pos;
32
33    void init_specific_awars(AW_root*) OVERRIDE {}
34
35    void update_pos_lookup() const {
36        pos = new TreePositionLookup(agt->get_logical_root());
37    }
38
39public:
40    TopologyShader(AWT_graphic_tree *agt_) :
41        ShaderPlugin("topology", "Topology shader"),
42        agt(agt_)
43    {}
44
45    ShadedValue shade(GBDATA *gb_item) const OVERRIDE {
46        if (gb_item) {
47            if (pos.isNull()) update_pos_lookup();
48
49            const char *name = GBT_read_name(gb_item);
50            if (name) {
51                TreeRelativePosition relpos = pos->relative(name);
52                if (relpos.is_known()) return ValueTuple::make(relpos.value());
53            }
54        }
55        return ValueTuple::undefined();
56    }
57
58    int get_dimension() const OVERRIDE { return 1; }
59    bool customizable() const OVERRIDE { return true; }
60    void customize(AW_root *) OVERRIDE { AW_help_popup(NULp, "topology_shader.hlp"); }
61
62    char *store_config() const OVERRIDE { return NULp; }
63    void load_or_reset_config(const char *) OVERRIDE {}
64
65    void activate(bool on) OVERRIDE;
66
67#if defined(ASSERTION_USED)
68    bool is_linked_with(AWT_graphic_tree *linkedWith) { return linkedWith == agt; }
69#endif
70
71    void tree_changed_cb() {
72        pos.setNull();
73        trigger_reshade_if_active_cb(SIMPLE_RESHADE); // forces reshade of "other" tree-canvas
74    }
75    static void tree_changed_cb(AWT_graphic_tree *IF_ASSERTION_USED(by), TopologyShader *shader) {
76        nt_assert(shader->is_linked_with(by));
77        shader->tree_changed_cb();
78    }
79};
80
81void TopologyShader::activate(bool on) {
82    // called with true when plugin gets activated, with false when it gets deactivated
83
84    if (on) {
85        pos.setNull(); // invalidate cached positions
86        GraphicTreeCallback gtcb = makeGraphicTreeCallback(TopologyShader::tree_changed_cb, this);
87        agt->install_tree_changed_callback(gtcb);
88    }
89    else {
90        agt->uninstall_tree_changed_callback();
91    }
92}
93
94// -----------------------
95//      NT_TreeShader
96
97class NT_TreeShader: public AP_TreeShader, virtual Noncopyable {
98    ItemShader *shader; // (owned by registry in ITEM_SHADER)
99
100    static void reshade() {
101#if defined(DEBUG)
102        fprintf(stderr, "[NT_TreeShader::reshade] @ %zu\n", clock());
103#endif
104        AW_root::SINGLETON->awar(AWAR_TREE_RECOMPUTE)->touch();
105    }
106
107public:
108    NT_TreeShader(TREE_canvas *ntw, GBDATA *gb_main) :
109        shader(registerItemShader(ntw->awr,
110                                  ntw->gc_manager,
111                                  BoundItemSel(gb_main, SPECIES_get_selector()),
112                                  "tree",
113                                  "Tree shading",
114                                  "tree_shading.hlp",
115                                  NT_TreeShader::reshade,
116                                  AWT_GC_NONE_MARKED))
117    {
118        AWT_graphic_tree *agt         = DOWNCAST(AWT_graphic_tree*, ntw->gfx);
119        ShaderPluginPtr   topo_shader = new TopologyShader(agt);
120        shader->register_plugin(topo_shader);
121    }
122    ~NT_TreeShader() OVERRIDE {}
123    void init() OVERRIDE { shader->init(); } // called by AP_tree::set_tree_shader when installed
124
125    void update_settings() OVERRIDE {
126        colorize_marked = shader->overlay_marked();
127        colorize_groups = shader->overlay_color_groups();
128        shade_species   = shader->active();
129    }
130
131    ShadedValue calc_shaded_leaf_GC(GBDATA *gb_node) const OVERRIDE { return shader->shade(gb_node); }
132    ShadedValue calc_shaded_inner_GC(const ShadedValue& left, float left_ratio, const ShadedValue& right) const OVERRIDE {
133        return mix(left, left_ratio, right);
134    }
135    int to_GC(const ShadedValue& val) const OVERRIDE { return shader->to_GC(val); }
136
137    void popup_config() const {
138        shader->popup_config_window(AW_root::SINGLETON);
139    }
140};
141
142// ----------------------------
143//      external interface
144
145void NT_install_treeShader(TREE_canvas *ntw, GBDATA *gb_main) {
146    AP_tree::set_tree_shader(new NT_TreeShader(ntw, gb_main));
147}
148
149void NT_configure_treeShader() {
150    const AP_TreeShader *tshader = AP_tree::get_tree_shader();
151    nt_assert(tshader);
152    if (tshader) DOWNCAST(const NT_TreeShader*, tshader)->popup_config();
153
154}
155
156
157
Note: See TracBrowser for help on using the repository browser.