| 1 | #ifndef AWT_CANVAS_HXX |
|---|
| 2 | #define AWT_CANVAS_HXX |
|---|
| 3 | |
|---|
| 4 | #ifndef AW_WINDOW_HXX |
|---|
| 5 | #include <aw_window.hxx> |
|---|
| 6 | #endif |
|---|
| 7 | #ifndef AW_DEVICE_HXX |
|---|
| 8 | #include <aw_device.hxx> |
|---|
| 9 | #endif |
|---|
| 10 | #ifndef ATTRIBUTES_H |
|---|
| 11 | #include <attributes.h> |
|---|
| 12 | #endif |
|---|
| 13 | |
|---|
| 14 | class AWT_canvas; |
|---|
| 15 | class AW_device; |
|---|
| 16 | class AW_clicked_line; |
|---|
| 17 | class AW_clicked_text; |
|---|
| 18 | |
|---|
| 19 | enum AWT_COMMAND_MODE { |
|---|
| 20 | AWT_MODE_NONE, |
|---|
| 21 | AWT_MODE_SELECT, |
|---|
| 22 | AWT_MODE_MARK, |
|---|
| 23 | AWT_MODE_GROUP, |
|---|
| 24 | AWT_MODE_ZOOM, // no command |
|---|
| 25 | AWT_MODE_LZOOM, |
|---|
| 26 | AWT_MODE_EDIT, // species info |
|---|
| 27 | AWT_MODE_WWW, |
|---|
| 28 | AWT_MODE_LINE, |
|---|
| 29 | AWT_MODE_ROT, |
|---|
| 30 | AWT_MODE_SPREAD, |
|---|
| 31 | AWT_MODE_SWAP, |
|---|
| 32 | AWT_MODE_LENGTH, |
|---|
| 33 | AWT_MODE_SWAP2, |
|---|
| 34 | AWT_MODE_MOVE, |
|---|
| 35 | AWT_MODE_SETROOT, |
|---|
| 36 | AWT_MODE_RESET, |
|---|
| 37 | |
|---|
| 38 | AWT_MODE_KERNINGHAN, |
|---|
| 39 | AWT_MODE_NNI, |
|---|
| 40 | AWT_MODE_OPTIMIZE, |
|---|
| 41 | AWT_MODE_PROINFO, |
|---|
| 42 | AWT_MODE_STRETCH |
|---|
| 43 | }; |
|---|
| 44 | |
|---|
| 45 | #define STANDARD_PADDING 10 |
|---|
| 46 | |
|---|
| 47 | // -------------------------------------------------------------------------------- |
|---|
| 48 | // AWT_zoom_mode + AWT_fit_mode are correlated, but not strictly coupled |
|---|
| 49 | |
|---|
| 50 | enum AWT_zoom_mode { // bit values! |
|---|
| 51 | AWT_ZOOM_NEVER = 0, |
|---|
| 52 | AWT_ZOOM_X = 1, |
|---|
| 53 | AWT_ZOOM_Y = 2, |
|---|
| 54 | AWT_ZOOM_BOTH = 3, |
|---|
| 55 | }; |
|---|
| 56 | |
|---|
| 57 | enum AWT_fit_mode { |
|---|
| 58 | AWT_FIT_NEVER, |
|---|
| 59 | AWT_FIT_LARGER, |
|---|
| 60 | AWT_FIT_SMALLER, |
|---|
| 61 | AWT_FIT_X, |
|---|
| 62 | AWT_FIT_Y, |
|---|
| 63 | }; |
|---|
| 64 | |
|---|
| 65 | // used combinations are: |
|---|
| 66 | // AWT_ZOOM_NEVER + AWT_FIT_NEVER (NDS list, others) |
|---|
| 67 | // AWT_ZOOM_X + AWT_FIT_X (dendrogram tree) |
|---|
| 68 | // AWT_ZOOM_Y + AWT_FIT_Y |
|---|
| 69 | // AWT_ZOOM_BOTH + AWT_FIT_LARGER (radial tree/gene-map; secedit) |
|---|
| 70 | // AWT_ZOOM_BOTH + AWT_FIT_SMALLER (book-style gene-map) |
|---|
| 71 | // |
|---|
| 72 | // other combinations may work as well. some combinations make no sense. |
|---|
| 73 | // -------------------------------------------------------------------------------- |
|---|
| 74 | |
|---|
| 75 | |
|---|
| 76 | class AWT_graphic_exports { |
|---|
| 77 | AW_borders default_padding; |
|---|
| 78 | AW_borders padding; |
|---|
| 79 | |
|---|
| 80 | public: |
|---|
| 81 | unsigned int zoom_reset : 1; |
|---|
| 82 | unsigned int resize : 1; |
|---|
| 83 | unsigned int refresh : 1; |
|---|
| 84 | unsigned int save : 1; |
|---|
| 85 | unsigned int structure_change : 1; // maybe useless |
|---|
| 86 | |
|---|
| 87 | AWT_zoom_mode zoom_mode; |
|---|
| 88 | AWT_fit_mode fit_mode; |
|---|
| 89 | |
|---|
| 90 | unsigned int dont_scroll : 1; // normally 0 (1 for IRS tree) |
|---|
| 91 | |
|---|
| 92 | void init(); // like clear, but resets fit, scroll state and padding |
|---|
| 93 | void clear(); |
|---|
| 94 | |
|---|
| 95 | void set_default_padding(int t, int b, int l, int r) { |
|---|
| 96 | default_padding.t = t; |
|---|
| 97 | default_padding.b = b; |
|---|
| 98 | default_padding.l = l; |
|---|
| 99 | default_padding.r = r; |
|---|
| 100 | |
|---|
| 101 | padding = default_padding; |
|---|
| 102 | } |
|---|
| 103 | |
|---|
| 104 | void set_equilateral_default_padding(int pad) { set_default_padding(pad, pad, pad, pad); } |
|---|
| 105 | void set_standard_default_padding() { set_equilateral_default_padding(STANDARD_PADDING); } |
|---|
| 106 | |
|---|
| 107 | void set_extra_text_padding(const AW_borders& text_padding) { |
|---|
| 108 | padding.t = default_padding.t + text_padding.t; |
|---|
| 109 | padding.b = default_padding.b + text_padding.b; |
|---|
| 110 | padding.l = default_padding.l + text_padding.l; |
|---|
| 111 | padding.r = default_padding.r + text_padding.r; |
|---|
| 112 | } |
|---|
| 113 | |
|---|
| 114 | int get_x_padding() const { return padding.l+padding.r; } |
|---|
| 115 | int get_y_padding() const { return padding.t+padding.b; } |
|---|
| 116 | int get_top_padding() const { return padding.t; } |
|---|
| 117 | int get_left_padding() const { return padding.l; } |
|---|
| 118 | |
|---|
| 119 | AW::Vector zoomVector(double transToFit) const { |
|---|
| 120 | return AW::Vector(zoom_mode&AWT_ZOOM_X ? transToFit : 1.0, |
|---|
| 121 | zoom_mode&AWT_ZOOM_Y ? transToFit : 1.0); |
|---|
| 122 | } |
|---|
| 123 | }; |
|---|
| 124 | |
|---|
| 125 | class AWT_graphic { |
|---|
| 126 | friend class AWT_canvas; |
|---|
| 127 | |
|---|
| 128 | void refresh_by_exports(AWT_canvas *scr); |
|---|
| 129 | |
|---|
| 130 | protected: |
|---|
| 131 | int drag_gc; |
|---|
| 132 | |
|---|
| 133 | public: |
|---|
| 134 | AWT_graphic_exports exports; |
|---|
| 135 | |
|---|
| 136 | AWT_graphic() { exports.init(); } |
|---|
| 137 | virtual ~AWT_graphic() {} |
|---|
| 138 | |
|---|
| 139 | // pure virtual interface (methods implemented by AWT_nonDB_graphic) |
|---|
| 140 | |
|---|
| 141 | virtual GB_ERROR load(GBDATA *gb_main, const char *name, AW_CL cd1, AW_CL cd2) = 0; |
|---|
| 142 | virtual GB_ERROR save(GBDATA *gb_main, const char *name, AW_CL cd1, AW_CL cd2) = 0; |
|---|
| 143 | virtual int check_update(GBDATA *gb_main) = 0; // check whether anything changed |
|---|
| 144 | virtual void update(GBDATA *gb_main) = 0; // mark the database |
|---|
| 145 | |
|---|
| 146 | // pure virtual interface (rest) |
|---|
| 147 | |
|---|
| 148 | virtual void show(AW_device *device) = 0; |
|---|
| 149 | |
|---|
| 150 | virtual void info(AW_device *device, AW_pos x, AW_pos y, AW_clicked_line *cl, AW_clicked_text *ct) = 0; // double click |
|---|
| 151 | virtual AW_gc_manager init_devices(AW_window *, AW_device *, AWT_canvas *scr, AW_CL cd2) = 0; |
|---|
| 152 | /* init gcs, if any gc is changed you may call |
|---|
| 153 | AWT_expose_cb(aw_window, scr, cd2); |
|---|
| 154 | or AWT_resize_cb(aw_window, scr, cd2); |
|---|
| 155 | The function may return a pointer to a preset window */ |
|---|
| 156 | |
|---|
| 157 | // implemented interface (most are dummies doing nothing): |
|---|
| 158 | virtual void command(AW_device *device, AWT_COMMAND_MODE cmd, |
|---|
| 159 | int button, AW_key_mod key_modifier, AW_key_code key_code, char key_char, |
|---|
| 160 | AW_event_type type, AW_pos x, AW_pos y, |
|---|
| 161 | AW_clicked_line *cl, AW_clicked_text *ct); |
|---|
| 162 | virtual void text(AW_device *device, char *text); |
|---|
| 163 | |
|---|
| 164 | }; |
|---|
| 165 | |
|---|
| 166 | class AWT_nonDB_graphic : public AWT_graphic { // @@@ check AWT_nonDB_graphic |
|---|
| 167 | // a partly implementation of AWT_graphic |
|---|
| 168 | public: |
|---|
| 169 | AWT_nonDB_graphic() {} |
|---|
| 170 | virtual ~AWT_nonDB_graphic() {} |
|---|
| 171 | |
|---|
| 172 | // dummy functions, only spittings out warnings: |
|---|
| 173 | GB_ERROR load(GBDATA *gb_main, const char *name, AW_CL cd1, AW_CL cd2) __ATTR__USERESULT; |
|---|
| 174 | GB_ERROR save(GBDATA *gb_main, const char *name, AW_CL cd1, AW_CL cd2) __ATTR__USERESULT; |
|---|
| 175 | int check_update(GBDATA *gb_main); |
|---|
| 176 | void update(GBDATA *gb_main); |
|---|
| 177 | }; |
|---|
| 178 | |
|---|
| 179 | |
|---|
| 180 | #define EPS 0.0001 // div zero check |
|---|
| 181 | #define CLIP_OVERLAP 15 |
|---|
| 182 | #define AWT_CATCH_LINE 50 // pixel |
|---|
| 183 | #define AWT_CATCH_TEXT 5 // pixel |
|---|
| 184 | #define AWT_ZOOM_OUT_STEP 40 // (pixel) rand um screen |
|---|
| 185 | #define AWT_MIN_WIDTH 100 // Minimum center screen (= screen-offset) |
|---|
| 186 | |
|---|
| 187 | enum { |
|---|
| 188 | AWT_d_screen = 1 |
|---|
| 189 | }; |
|---|
| 190 | |
|---|
| 191 | class AWT_canvas : virtual Noncopyable { |
|---|
| 192 | bool consider_text_for_size; |
|---|
| 193 | |
|---|
| 194 | public: |
|---|
| 195 | // too many callbacks -> public |
|---|
| 196 | // in fact: private |
|---|
| 197 | // (in real fact: needs rewrite) |
|---|
| 198 | |
|---|
| 199 | char *user_awar; |
|---|
| 200 | void init_device(AW_device *device); |
|---|
| 201 | AW_pos trans_to_fit; |
|---|
| 202 | AW_pos shift_x_to_fit; |
|---|
| 203 | AW_pos shift_y_to_fit; |
|---|
| 204 | |
|---|
| 205 | int old_hor_scroll_pos; |
|---|
| 206 | int old_vert_scroll_pos; |
|---|
| 207 | AW_screen_area rect; // screen coordinates |
|---|
| 208 | AW_world worldinfo; // real coordinates without transform. |
|---|
| 209 | AW_world worldsize; |
|---|
| 210 | int zoom_drag_sx; |
|---|
| 211 | int zoom_drag_sy; |
|---|
| 212 | int zoom_drag_ex; |
|---|
| 213 | int zoom_drag_ey; |
|---|
| 214 | int drag; |
|---|
| 215 | AW_clicked_line clicked_line; |
|---|
| 216 | AW_clicked_text clicked_text; |
|---|
| 217 | |
|---|
| 218 | void set_scrollbars(); |
|---|
| 219 | void set_dragEndpoint(int x, int y); |
|---|
| 220 | |
|---|
| 221 | void set_horizontal_scrollbar_position(AW_window *aww, int pos); |
|---|
| 222 | void set_vertical_scrollbar_position(AW_window *aww, int pos); |
|---|
| 223 | |
|---|
| 224 | |
|---|
| 225 | // public (read only) |
|---|
| 226 | |
|---|
| 227 | GBDATA *gb_main; |
|---|
| 228 | AW_window *aww; |
|---|
| 229 | AW_root *awr; |
|---|
| 230 | AWT_graphic *gfx; |
|---|
| 231 | |
|---|
| 232 | AW_gc_manager gc_manager; |
|---|
| 233 | int drag_gc; |
|---|
| 234 | |
|---|
| 235 | AWT_COMMAND_MODE mode; |
|---|
| 236 | |
|---|
| 237 | // real public |
|---|
| 238 | |
|---|
| 239 | AWT_canvas(GBDATA *gb_main, AW_window *aww, AWT_graphic *awd, AW_gc_manager &gc_manager, const char *user_awar); |
|---|
| 240 | |
|---|
| 241 | inline void push_transaction() const; |
|---|
| 242 | inline void pop_transaction() const; |
|---|
| 243 | |
|---|
| 244 | void refresh(); |
|---|
| 245 | |
|---|
| 246 | void recalc_size(bool adjust_scrollbars = true); |
|---|
| 247 | void recalc_size_and_refresh() { recalc_size(true); refresh(); } |
|---|
| 248 | |
|---|
| 249 | void zoom_reset(); |
|---|
| 250 | void zoom_reset_and_refresh() { zoom_reset(); refresh(); } |
|---|
| 251 | |
|---|
| 252 | void set_consider_text_for_zoom_reset(bool consider) { consider_text_for_size = consider; } |
|---|
| 253 | |
|---|
| 254 | void refresh_by_exports() { gfx->refresh_by_exports(this); } |
|---|
| 255 | |
|---|
| 256 | void zoom(AW_device *device, bool zoomIn, const AW::Rectangle& wanted_part, const AW::Rectangle& current_part, int percent); |
|---|
| 257 | |
|---|
| 258 | void set_mode(AWT_COMMAND_MODE mo) { mode = mo; } |
|---|
| 259 | |
|---|
| 260 | void scroll(int delta_x, int delta_y, bool dont_update_scrollbars = false); |
|---|
| 261 | void scroll(const AW::Vector& delta, bool dont_update_scrollbars = false) { |
|---|
| 262 | scroll(int(delta.x()), int(delta.y()), dont_update_scrollbars); |
|---|
| 263 | } |
|---|
| 264 | |
|---|
| 265 | bool handleWheelEvent(AW_device *device, const AW_event& event); |
|---|
| 266 | }; |
|---|
| 267 | |
|---|
| 268 | inline void AWT_graphic::refresh_by_exports(AWT_canvas *scr) { |
|---|
| 269 | if (exports.zoom_reset) scr->zoom_reset_and_refresh(); |
|---|
| 270 | else if (exports.resize) scr->recalc_size_and_refresh(); |
|---|
| 271 | else if (exports.refresh) scr->refresh(); |
|---|
| 272 | } |
|---|
| 273 | |
|---|
| 274 | |
|---|
| 275 | void AWT_expose_cb(AW_window *dummy, AWT_canvas *scr, AW_CL cl2); |
|---|
| 276 | void AWT_resize_cb(AW_window *dummy, AWT_canvas *scr, AW_CL cl2); |
|---|
| 277 | |
|---|
| 278 | void AWT_popup_tree_export_window(AW_window *parent_win, AW_CL cl_canvas, AW_CL); |
|---|
| 279 | void AWT_popup_sec_export_window (AW_window *parent_win, AW_CL cl_canvas, AW_CL); |
|---|
| 280 | void AWT_popup_print_window (AW_window *parent_win, AW_CL cl_canvas, AW_CL); |
|---|
| 281 | |
|---|
| 282 | |
|---|
| 283 | #endif |
|---|