source: projects/paper-tape-project/trunk/visualisator/gtkpapertapeview.cc @ 76

Last change on this file since 76 was 76, checked in by sven, 11 years ago

Reverted Visualisator to SVN Revision 21, with patches that make the
code compile with current Linuxes. See Ticket #45 and #44 for these issues.

This codebase will form the basis for the PaperTapeViewer in the
Paper Tape Project NG 2013.

File size: 10.0 KB
Line 
1#include <cairomm/context.h>
2#include <iostream>
3#include <cstdio>
4#include <gtkmm/colorbutton.h>
5
6#include "gtkpapertapeview.h"
7#include "gtkpapertapeexporter.h"
8
9#include <cairo/cairo-xlib.h>
10using namespace Gtk;
11
12PaperTapeView::PaperTapeView(PaperTape* controller)
13:
14        just_hovered_row(LOCHSTREIFEN_NO_ROW),
15        just_hovered_track(LOCHSTREIFEN_NO_TRACK),
16        controller(controller)
17{
18        this->lochstreifen = lochstreifen_new();
19        make_colors();
20       
21        current_width_scaling = 200;
22        lochstreifen_set_scaling_by_width(lochstreifen, 200);
23       
24        // catch events for callback functions
25        add_events(Gdk::POINTER_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
26       
27        // the controller connects the on_data_change for us.
28        controller->model->data_changed.connect(sigc::mem_fun(*this, &PaperTapeView::on_data_change));
29       
30        // init zoom (don't forget to delete)
31        zoom = new PaperTapeZoom(0.0, Gdk::Screen::get_default()->get_resolution());
32        zoom->signal_changed().connect(sigc::mem_fun(*this, &PaperTapeView::on_zoom_change));
33       
34        //set_double_buffered(false);
35        //get_window()->set_debug_updates(true);
36}
37
38void PaperTapeView::on_data_change(byte_t* new_data, int new_data_len) {
39        // daten haben sich geaendert. Neue Daten als Parameter
40        // Die Daten verblieben bei dem Model, welches das hier aufruft.
41       
42        std::cout << "data change signal called, newl len " << new_data_len << "\n";
43
44        lochstreifen_set_data(lochstreifen, new_data_len, new_data);
45       
46        set_size_request(
47                lochstreifen_get_target_width(lochstreifen),
48                lochstreifen_get_target_height(lochstreifen)
49        );
50}
51
52void PaperTapeView::on_zoom_change() {
53        // yeah, zoom has changed.
54        // erhm, this is a bit stupid:
55        cairo_matrix_init(&lochstreifen->matrix,
56                zoom->xx, zoom->xy, zoom->yx, zoom->yy, zoom->x0, zoom->y0
57        );
58        lochstreifen_check_matrix(lochstreifen);       
59        set_size_request(
60                lochstreifen_get_target_width(lochstreifen),
61                lochstreifen_get_target_height(lochstreifen)
62        );
63        queue_draw();
64}
65
66bool PaperTapeView::on_expose_event(GdkEventExpose *event) {
67        // besser: Erst das tatsaechliche cairo_t* objekt kriegen beim drawen!
68        Cairo::RefPtr<Cairo::Context> cr = this->get_window()->create_cairo_context();
69        cr->save(); // this is said to be good style
70       
71        // --gtk-debug=updates
72        // for debugging!
73       
74        std::cout << "expose("<< event->count <<"): " << event->area.x << "|" << event->area.y << " " <<
75                event->area.width << "x" << event->area.height << "\n";
76
77        //get_window()->clear_area(event->area.x, event->area.y, event->area.width, event->area.height);
78        //gdk_window_clear_area(event->window, event->area.x, event->area.y, event->area.width, event->area.height);
79        //gdk_window_clear(event->window);
80       
81        int x, y, width, height;
82       
83        gdk_window_get_position(gdk_window_get_parent(event->window), &x, &y);
84        gdk_drawable_get_size(GDK_DRAWABLE(event->window), &width, &height);
85        std::cout << "GdkWin: " << x << "|" << y << " " << width << "x" << height << "\n";
86        //gdk_window_get_geometry(gdk_window_get_parent(event->window), &x, &y, &width, &height, NULL);
87        //std::cout << x << "|" << y << " " << width << "x" << height << "\n";
88       
89        // Get the CAIRO WIDTH/HEIGHT
90        width = cairo_xlib_surface_get_width( cairo_get_target(cr->cobj()) );
91        height = cairo_xlib_surface_get_height( cairo_get_target(cr->cobj()) );
92        std::cout << "csurface: " << width << "x" << height << "\n";
93       
94        // clipping! :-)
95        lochstreifen_set_clip(lochstreifen,
96                event->area.x, event->area.y,
97                event->area.width, event->area.height);
98       
99        lochstreifen_draw(lochstreifen, cr->cobj());
100        cr->restore();
101       
102//      cr->set_source_rgba(0.337, 0.612, 0.117, 0.9);   // green
103//      cr->paint();
104       
105       
106        return true;
107}
108
109bool PaperTapeView::on_scroll_event(GdkEventScroll* event) {
110        std::cout << "Mouse Scrolling.\n";
111
112        return true;
113}
114
115void PaperTapeView::queue_draw_bit(row_t& row, track_t& track) {
116        cairo_rectangle_t repaint;
117        // paint only in valid range:
118        if(row != LOCHSTREIFEN_NO_ROW && track != LOCHSTREIFEN_NO_TRACK) {
119                if(lochstreifen_get_target_rect_from_bit(lochstreifen, row, track, &repaint)
120                   == LOCHSTREIFEN_SUCCESS) {
121                        std::cout << "Redrawing! row " << row << " track " << track << ": ";
122                        std::cout << repaint.x << "|" << repaint.y << " " << repaint.width << "x" << repaint.height << "\n";
123                        queue_draw_rect(repaint);
124                }
125                else
126                        std::cout << "ERROR Repainting the bit " << row << "," << track << " failed!\n";
127        }
128}
129
130void PaperTapeView::queue_draw_row(row_t& row) {
131        cairo_rectangle_t repaint;
132        // paint only in valid range
133        if(row != LOCHSTREIFEN_NO_ROW) {
134                if(lochstreifen_get_target_rect_from_row(lochstreifen, row, &repaint)
135                   == LOCHSTREIFEN_SUCCESS)
136                        queue_draw_rect(repaint);
137                else   
138                        std::cout << "ERROR Repainting row " << row << " failed!\n";
139        }
140}
141
142bool PaperTapeView::on_motion_notify_event(GdkEventMotion* event) {
143        row_t new_row;
144        track_t new_track;
145        lochstreifen_get_target_bit_from_point(lochstreifen, &new_row, &new_track, event->x, event->y);
146
147        // repaint bits, if neccessary
148        if(new_track != just_hovered_track) {
149                // we have changed the track, queue a redraw for the old one
150                queue_draw_bit(just_hovered_row, just_hovered_track);
151       
152                // set the new one. If NO_TRACK or NO_ROW, this is the "no highlight"
153                // state, internally
154                lochstreifen_set_highlight_bit(lochstreifen, new_row, new_track);
155                std::cout << "Queue new draw row " << new_row << " bit " << new_track << "\n";
156                // redraw the new one. If NO_TRACK or NO_ROW, it won't be paint.
157                queue_draw_bit(new_row, new_track);
158               
159                // buffer hovered track for next mouse event
160                just_hovered_track = new_track;
161        } // bit
162       
163        // repaint the old row, if neccessary
164        if(new_row != just_hovered_row) {
165                // we have changed the row, repaint the old one (remove the highlight)
166                queue_draw_row(just_hovered_row);
167       
168                // if new_row is NO_ROW, this will simply remove the highlight
169                lochstreifen_set_highlight_row(lochstreifen, new_row);
170                // this will only repaint if it's a vaild row
171                queue_draw_row(new_row);
172
173                // buffer hovered row for next mouse event
174                just_hovered_row = new_row;
175        } // row
176
177        return true;
178}
179
180bool PaperTapeView::on_button_press_event(GdkEventButton* event) {
181        // mouse button pressed. (we could make another color ;-)
182        if(just_hovered_track != LOCHSTREIFEN_NO_TRACK) {
183                // we are on a bit, and the mouse button was pressed.
184                std::cout << "You are about to change byte " << just_hovered_row << ", bit " << just_hovered_track << "\n";
185               
186                // make a cool surface:
187                cairo_pattern_destroy(lochstreifen->highlight_bit_color);
188                lochstreifen->highlight_bit_color = cairo_pattern_create_rgb(0., 1., 0.);
189               
190                queue_draw_bit(just_hovered_row, just_hovered_track);
191        } else if(just_hovered_row != LOCHSTREIFEN_NO_ROW) {
192                // mouse pressed on a row, but not on Button
193                std::cout << "Begin selection\n";
194        }
195
196        return true;
197}
198
199bool PaperTapeView::on_button_release_event(GdkEventButton* event) {
200        // mouse button released.
201        if(just_hovered_track != LOCHSTREIFEN_NO_TRACK) {
202                // that's it. CHANGE THE DATA!
203                std::cout << "Triggered. Have toggled byte " << just_hovered_row << ", bit " << just_hovered_track << "\n";
204                controller->model->toggle_bit(just_hovered_row, just_hovered_track);
205        }
206
207        // reset pattern
208        cairo_pattern_destroy(lochstreifen->highlight_bit_color);
209        lochstreifen->highlight_bit_color = LOCHSTREIFEN_DEFAULT_HIGHLIGHT_BIT_COLOR;
210       
211        queue_draw_bit(just_hovered_row, just_hovered_track);
212
213        return true;
214}
215
216
217void PaperTapeView::export_image() {
218        std::cout << "Creating object:\n";
219        PaperTapeExporter program(*controller->parent_window, lochstreifen);
220        std::cout << "STARTING EXPORT\n";
221        if(program.run_export()) {
222                std::cout << "Export handled nicely\n";
223        }
224}
225
226Glib::RefPtr<ActionGroup> PaperTapeView::get_color_action_group() {
227        Glib::RefPtr<ActionGroup> group = ActionGroup::create("GtkPaperTapeViewColors");
228        // iterate the Colors
229        for(std::map<std::string,  Glib::RefPtr<PaperTapeColor> >::iterator i = colors.begin();
230            i != colors.end(); i++) {
231                std::cout << "Adding actions for " << i->first << "\n";
232                group->add(i->second);
233                if(i->second->is_switchable())
234                        group->add(i->second->get_toggle_action());
235        }
236
237/*
238        for(unsigned int i = 0; i < colors.size(); i++) {
239                group->add(colors[i]->get_color_action());
240                if(colors[i]->is_switchable())
241                        group->add(colors[i]->get_toggle_action());
242        }
243*/
244        return group;
245}
246
247void PaperTapeView::make_colors() {
248        // Make the color vector thing, for faster iteration
249        add_color("outer_background",
250                &lochstreifen->outer_background_color,
251                "Select background color",
252                "Color of the <b>background</b>",
253                "Display background"
254        );
255        add_color("papertape_background",
256                &lochstreifen->papertape_background_color,
257                "Select color of papertape",
258                "Color of the <b>papertape</b>",
259                "Display papertape sheet"
260        );
261        add_color("one_code_hole",
262                &lochstreifen->one_code_hole_color,
263                "Select color of punched holes (logical 1)",
264                "Color of <b>punched holes</b>\n(logical 1)",
265                "Display punched code holes"
266        );
267        add_color("zero_code_hole",
268                &lochstreifen->zero_code_hole_color,
269                "Select color of zero holes (logical 0)",
270                "Color of <b>zero holes</b>\n(logical 0)",
271                "Display zero code holes"
272        );
273        add_color("feed_hole",
274                &lochstreifen->feed_hole_color,
275                "Select color of feed holes",
276                "Color of <b>feed holes</b>",
277                "Display feed holes"
278        );
279        add_color("highlight_region",
280                &lochstreifen->highlight_region_color,
281                "Select color of highlighted regions (selections)",
282                "Color of <b>selections</b>"
283        );
284        add_color("highlight_row",
285                &lochstreifen->highlight_row_color,
286                "Select color of highlighted byte (hovered byte)",
287                "Color of <b>hovered bytes</b>"
288        );
289        add_color("highlight_bit",
290                &lochstreifen->highlight_bit_color,
291                "Select color of highlighted bit (hovered bit)",
292                "Color of <b>hovered bit</b>"
293        );
294}
295
296void PaperTapeView::add_color(const Glib::ustring& name, cairo_pattern_t** target, const Glib::ustring& dialog_title,
297   const Glib::ustring& menu_label, const Glib::ustring& toggle_label) {
298        colors[name] = PaperTapeColor::create(this, target,
299                name, dialog_title, menu_label, toggle_label);
300        colors[name]->signal_color_changed().connect(sigc::mem_fun(*this, &PaperTapeView::on_color_change));
301}
302
303void PaperTapeView::on_color_change(PaperTapeColor* name) {
304        std::cout << "PaperTapeView: Got a changed color!\n";
305        queue_draw();
306}
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