source: projects/visualisator/gtkpapertapezoom.cc @ 20

Last change on this file since 20 was 20, checked in by sven, 16 years ago

Cleaned up (No object and output binaries in the SVN). Furthermore it compiles
now ("make all"). There are still bugs. See /TODO.txt (coming soon)

-- Sven @ workstation

File size: 10.2 KB
Line 
1#include "gtkpapertapezoom.h"
2#include <gtkmm/actiongroup.h>
3#include <gtkmm/table.h>
4#include <gtkmm/label.h>
5#include <gtkmm/frame.h>
6#include <gtkmm/checkbutton.h>
7#include <gtkmm/box.h>
8#include <gtk/gtk.h>
9#include <cairo.h>
10#include <gtkmm/stock.h>
11#include <iostream>
12#include <cstdio>
13
14using namespace Gtk;
15
16
17/* { name, stock_id, label, acclerator, tooltip, callback } */
18GtkActionEntry PaperTapeZoom::ui_action_entries[] = {
19        { "ZoomIn", GTK_STOCK_ZOOM_IN },
20        { "ZoomOut", GTK_STOCK_ZOOM_OUT },
21        { "Zoom100", GTK_STOCK_ZOOM_100 },
22        { "Zoom50", NULL, "Zoom to 50%" },
23        { "Zoom200", NULL, "Zoom to 200%" },
24        { "ZoomWidth", GTK_STOCK_ZOOM_FIT, "Fit to screen", NULL, "Zoom that the papertape width fills the screen" },
25        { "ZoomLength", GTK_STOCK_ZOOM_FIT, "Fit all to screen ", NULL, "Zoom that the complete papertape fills in the screen" },
26        { "ZoomDialog", GTK_STOCK_PROPERTIES, "Show dialog...", "<ctrl>z", "Set Zoom level and input own Affine Translation Matrix" },
27
28        { "Rotate90CW", GTK_STOCK_ORIENTATION_LANDSCAPE, "Rotate clockwise" },
29        { "Rotate90CCW", GTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE, "Rotate anticlockwise" },
30        { "FlipHoriz", GTK_STOCK_ORIENTATION_PORTRAIT, "Flip horizontally" },
31        { "FlipVert", GTK_STOCK_ORIENTATION_REVERSE_PORTRAIT, "Flip verticall" }
32};
33
34PaperTapeZoom::PaperTapeZoom(double default_rotation, double default_zoom_factor, PaperTapeFlip default_flip) {
35        // init values
36        this->rotation = default_rotation;
37        this->flip = default_flip;
38        this->zoom_factor = default_zoom_factor;
39        this->manually = false;
40        set_default(default_rotation, default_zoom_factor, default_flip);
41}
42
43void PaperTapeZoom::show_dialog() {
44        if(!matrix_dialog) {
45                // set up the matrix_dialog.
46                matrix_dialog = new Dialog("Set papertape view");
47                // Frame.
48                Frame* matrix_frame = manage(new Frame());
49                CheckButton* matrix_manually = manage(new CheckButton("Set Affine Translation Matrix manually"));
50                matrix_manually->set_active(this->manually);
51                // connect matrix_manually button
52                matrix_manually->signal_toggled().connect(
53                        sigc::bind(sigc::mem_fun(*this, &PaperTapeZoom::on_toggle_manually), matrix_manually)
54                );
55                matrix_frame->set_label_widget(*matrix_manually);
56               
57                Table* table = manage(new Table(2, 6));
58                Label* l;
59                l = manage(new Label("x__n = "));
60                table->attach(*l, 0, 1, 0, 1);
61                matrix_entries[&xx] = manage(new SpinButton());
62                table->attach(*matrix_entries[&xx], 1, 2, 0, 1);
63                l = manage(new Label("* x + "));
64                table->attach(*l, 2, 3, 0, 1);
65                matrix_entries[&xy] = manage(new SpinButton());
66                table->attach(*matrix_entries[&xy], 3, 4, 0, 1);
67                l = manage(new Label("* y + "));
68                table->attach(*l, 4, 5, 0, 1);
69                matrix_entries[&x0] = manage(new SpinButton());
70                table->attach(*matrix_entries[&x0], 5, 6, 0, 1);
71                l = manage(new Label("y__n = "));
72                table->attach(*l, 0, 1, 1, 2);
73                matrix_entries[&yx] = manage(new SpinButton());
74                table->attach(*matrix_entries[&yx], 1, 2, 1, 2);
75                l = manage(new Label("* x + "));
76                table->attach(*l, 2, 3, 1, 2);
77                matrix_entries[&yy] = manage(new SpinButton());
78                table->attach(*matrix_entries[&yy], 3, 4, 1, 2);
79                l = manage(new Label("* y + "));
80                table->attach(*l, 4, 5, 1, 2);
81                matrix_entries[&y0] = manage(new SpinButton());
82                table->attach(*matrix_entries[&y0], 5, 6, 1, 2);
83               
84                // connect signals
85                for(std::map<double*, SpinButton*>::iterator i = matrix_entries.begin();
86                    i != matrix_entries.end(); i++) {
87                        i->second->set_sensitive(this->manually);
88                        i->second->set_range(-G_MAXDOUBLE, G_MAXDOUBLE); // ;-)
89                        i->second->set_increments(5.0, 10.0);
90                        i->second->set_value( * (i->first) );
91                        i->second->signal_value_changed().connect(
92                                sigc::bind(
93                                        sigc::mem_fun(*this, &PaperTapeZoom::on_change_field),
94                                        i->first
95                                )
96                        );
97                } // for entries
98
99               
100                matrix_frame->add(*table);
101                matrix_dialog->get_vbox()->add(*matrix_frame);
102               
103                // add buttons
104                //matrix_dialog->add_button(GTK_STOCK_UNDO, 1);
105                Button* reset = manage(new Button(Stock::UNDO));
106                matrix_dialog->get_action_area()->add(*reset);
107                matrix_dialog->get_action_area()->set_child_secondary(*reset);
108                reset->signal_clicked().connect(sigc::mem_fun(*this, &PaperTapeZoom::reset));
109
110                //matrix_dialog->add_button(Stock::APPLY, 2);
111                // directly apply! :-)
112               
113                // we could use this, but we could not conncet own signals, so:
114                //matrix_dialog->add_button(Stock::CLOSE, 3);
115                Button *close = manage(new Button(Stock::CLOSE));
116                matrix_dialog->get_action_area()->add(*close);
117                close->signal_clicked().connect(sigc::mem_fun(*matrix_dialog, &Window::hide));
118               
119                // update the entry things whenever the zoom is changed
120                this->signal_changed().connect(sigc::mem_fun(*this, &PaperTapeZoom::update_dialog_on_zoom_changes));
121               
122                //matrix_dialog->add(*main_box);
123                matrix_dialog->set_focus(*close);
124                matrix_dialog->show_all();
125        } else {
126                // Window already created: Show it and/or bring it to front
127                matrix_dialog->show();
128                matrix_dialog->grab_focus(); // try it...
129                matrix_dialog->raise(); // bring it to front
130        }
131}
132
133void PaperTapeZoom::update_dialog_on_zoom_changes() {
134        for(std::map<double*, SpinButton*>::iterator i = matrix_entries.begin();
135            i != matrix_entries.end(); i++) {
136                i->second->set_value( * (i->first) );
137        } // for entries
138}
139
140void PaperTapeZoom::reset() {
141        if(this->is_controlled_manually()) {
142                *this = default_matrix; /*xx = default_matrix.xx; xy = default_matrix.xy; x0 = default_matrix.x0;
143                yx = default_matrix.yx; yy = default_matrix.yy; y0 = default_matrix.y0;*/
144                zoom_changed.emit();
145        } else {
146                zoom_factor = 1.0;
147                rotation = 0.0;
148                calc_matrix();
149        }
150}
151
152void PaperTapeZoom::on_toggle_manually(CheckButton* manually_toggle) {
153        this->manually = manually_toggle->get_active();
154        // turn input widgets on/off
155        for(std::map<double*, SpinButton*>::iterator i = matrix_entries.begin();
156            i != matrix_entries.end(); i++) {
157                i->second->set_sensitive(manually);
158        }
159        // + turn other widgets on/off, like action widgets
160}
161
162void PaperTapeZoom::on_change_field(double* field) {
163        // only for internal use
164        if(!field) {
165                std::cout << "Bad NUll Pointer at on_change_field.\n";
166                return;
167        }
168        if(matrix_entries[field]) {
169                std::cout << "UPDATE FIELD\n";
170                *field = matrix_entries[field]->get_value();
171                zoom_changed.emit();
172        } else
173                std::cout << "BAD: FIELD NOT SUPPORTED (PaperTapeZoom::change_field)\n";
174}
175
176void PaperTapeZoom::calc_matrix() {
177        // take the buffer things and calculate a new matrix, FROM
178        // DEFAULT MATRIX.
179        if(!this->is_controlled_manually()) {
180                *this = default_matrix;
181                cairo_matrix_scale(this, zoom_factor, zoom_factor);
182                cairo_matrix_rotate(this, rotation);
183
184                zoom_changed.emit();
185        }
186}
187
188void PaperTapeZoom::set_default(double rotation, double zoom_factor, PaperTapeFlip flip) {
189        // change default matrix.
190        cairo_matrix_init_identity(&this->default_matrix);
191        cairo_matrix_scale(&this->default_matrix, zoom_factor, zoom_factor);
192        cairo_matrix_rotate(&this->default_matrix, rotation);
193        // flip?
194}
195
196void PaperTapeZoom::set_rotate(double radians, bool relative) {
197        if(!is_controlled_manually()) {
198                this->rotation = relative ? (this->rotation + radians) : radians;
199                this->calc_matrix();
200        } else {
201                // change user matrix
202                cairo_matrix_rotate(this, radians);
203                zoom_changed.emit();
204        }
205}
206
207void PaperTapeZoom::set_zoom(double zoom_factor, bool relative) {
208        if(!is_controlled_manually()) {
209                this->zoom_factor = relative ? (this->zoom_factor * zoom_factor) : zoom_factor;
210                this->calc_matrix();
211        } else {
212                // change user matrix
213                cairo_matrix_scale(this, zoom_factor, zoom_factor);
214                zoom_changed.emit();
215        }
216}
217
218void PaperTapeZoom::set_flip(PaperTapeFlip flip, bool relative) {
219        // not implemented yet
220}
221
222Glib::RefPtr<ActionGroup> PaperTapeZoom::get_action_group() {
223        Glib::RefPtr<ActionGroup> group = ActionGroup::create("GtkPaperTapeZoom");
224       
225        gtk_action_group_add_actions(
226                        group->gobj(),
227                        ui_action_entries,
228                        G_N_ELEMENTS(ui_action_entries),
229                        NULL);
230
231        group->signal_post_activate().connect(sigc::mem_fun(*this, &PaperTapeZoom::transform_action));
232
233        return group;
234}
235
236void PaperTapeZoom::transform_action(const Glib::RefPtr<Action>& action) {
237        Glib::ustring name = action->get_name();
238       
239        if(name == "ZoomIn") {
240                set_zoom(1.1, true);
241        } else if(name == "ZoomOut") {
242                set_zoom(0.9, true);
243        } else if(name == "Zoom100") {
244                set_zoom(1.0, false);
245        } else if(name == "Zoom50") {
246                set_zoom(0.5, false);
247        } else if(name == "Zoom200") {
248                set_zoom(2.0, false);
249        } else if(name == "ZoomWidth") {
250                //signal_set_auto_zoom.emit(true);
251               
252                //set_auto_zoom(ZOOM_LOCHSTREIFEN_WIDTH);
253                // get width of lochstreifen (well, "1")
254                // get height of view Viewport
255                // calc length
256                // add signal to fetch size changements
257        } else if(name == "ZoomLength") {
258                //set_auto_zoom(ZOOM_LOCHSTREIFEN_LENGTH);
259        } else if(name == "ZoomDialog") {
260                show_dialog();
261        } else if(name == "Rotate90CW") {
262                set_rotate(G_PI, true);
263        } else if(name == "Rotate90CCW") {
264                set_rotate(-G_PI, true);
265        } else if(name == "FlipHoriz") {
266                //set_flip();
267        } else if(name == "FlipVert") {
268                // same here...
269        } else {
270                std::cout << "PaperTapeZoom: Action " << name << " not supported!\n";
271        }
272}
273
274void PaperTapeZoom::set_auto_zoom(PaperTapeView& view, PaperTapeAutoZoomType type) {
275        this->auto_zoom_enabled = true;
276
277        // connect resize signal
278        auto_zoom_resize_con = view.signal_configure_event().connect(
279                sigc::mem_fun(*this, &PaperTapeZoom::on_auto_zoom_resize)
280        );
281
282       
283       
284}
285
286void PaperTapeZoom::disable_auto_zoom() {
287        if(auto_zoom_enabled) {
288                auto_zoom_resize_con.disconnect();
289                auto_zoom_enabled = false;
290        }
291}
292
293bool PaperTapeZoom::on_auto_zoom_resize(GdkEventConfigure* event) {
294        // depending on orientation, use event->width and event->height
295       
296        // We could use LOCHSTREIFEN logic here!
297        return true;
298}
299
300
301/*
302void PaperTapeView::transform(PaperTapeTransformation how) {
303        switch(how) {
304                case ZOOM_IN:
305                case ZOOM_OUT:
306                {
307                        //current_width_scaling += 10 * ((how == ZOOM_IN) ? 1 : -1);
308                        double f((how == ZOOM_IN) ? 1.1 : (0.9));
309                       
310                        std::cout << "View: scaling up/down: " << f << "\n";
311
312                        cairo_matrix_scale(&lochstreifen->matrix, f, f);
313                        lochstreifen_check_matrix(lochstreifen);
314                        zoom_changed.emit();
315                        break;
316                }
317                case ZOOM_REAL:
318                {
319                        // get the DPI, our factor
320                        double f = Gdk::Screen::get_default().get_resolution();
321                        cairo_matrix_init_scale(&lochstreifen->matrix, f, f);
322                        lochstreifen_check_matrix(lochstreifen);
323                        zoom_changed.emit();
324                }
325                case SET_ZOOM:
326                {
327                        // display the matrix enter dialog
328                }
329        }
330}
331*/
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License