All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
svpaint.cpp
Go to the documentation of this file.
1 // Copyright 2007 Google Inc. All Rights Reserved.
2 //
3 // Author: Joern Wanke
4 //
5 // Simple drawing program to illustrate ScrollView capabilities.
6 //
7 // Functionality:
8 // - The menubar is used to select from different sample styles of input.
9 // - With the RMB it is possible to change the RGB values in different
10 // popup menus.
11 // - A LMB click either draws point-to-point, point or text.
12 // - A LMB dragging either draws a line, a rectangle or ellipse.
13 
14 // Include automatically generated configuration file if running autoconf.
15 #ifdef HAVE_CONFIG_H
16 #include "config_auto.h"
17 #endif
18 
19 #ifndef GRAPHICS_DISABLED
20 #include "scrollview.h"
21 #include "svmnode.h"
22 #include <stdlib.h>
23 #include <iostream>
24 
25 // The current color values we use, initially white (== ScrollView::WHITE).
26 int rgb[3] = { 255, 255, 255 };
27 
28 class SVPaint : public SVEventHandler {
29  public:
30  explicit SVPaint(const char* server_name);
31 // This is the main event handling function that we need to overwrite, defined
32 // in SVEventHandler.
33  void Notify(const SVEvent* sv_event);
34  private:
35 // The Handler take care of the SVET_POPUP, SVET_MENU, SVET_CLICK and
36 // SVET_SELECTION events.
37  void PopupHandler(const SVEvent* sv_event);
38  void MenuBarHandler(const SVEvent* sv_event);
39  void ClickHandler(const SVEvent* sv_event);
40  void SelectionHandler(const SVEvent* sv_event);
41 
42 // Convenience functions to build little menus.
43  SVMenuNode* BuildPopupMenu();
44  SVMenuNode* BuildMenuBar();
45 
46 // Our window.
47  ScrollView* window_;
48 
49 // The mode we are in when an SVET_CLICK or an SVET_SELECTION event occurs.
50  int click_mode_;
51  int drag_mode_;
52 
53 // In the point-to-point drawing mode, we need to set a start-point the first
54 // time we call it (e.g. call SetCursor).
55  bool has_start_point_;
56 };
57 
58 // Build a sample popup menu.
59 SVMenuNode* SVPaint::BuildPopupMenu() {
60  SVMenuNode* root = new SVMenuNode(); // Empty root node
61  // Initial color is white, so we all values to 255.
62  root->AddChild("R", // Shown caption.
63  1, // assoc. command_id.
64  "255", // initial value.
65  "Red Color Value?"); // Shown description.
66  root->AddChild("G", 2, "255", "Green Color Value?");
67  root->AddChild("B", 3, "255", "Blue Color Value?");
68  return root;
69 }
70 
71 // Build a sample menu bar.
72 SVMenuNode* SVPaint::BuildMenuBar() {
73  SVMenuNode* root = new SVMenuNode(); // Empty root node
74 
75  // Create some submenus and add them to the root.
76  SVMenuNode* click = root->AddChild("Clicking");
77  SVMenuNode* drag = root->AddChild("Dragging");
78 
79  // Put some nodes into the submenus.
80  click->AddChild("Point to Point Drawing", // Caption.
81  1); // command_id.
82  click->AddChild("Point Drawing", 2);
83  click->AddChild("Text Drawing", 3);
84  drag->AddChild("Line Drawing", 4);
85  drag->AddChild("Rectangle Drawing", 5);
86  drag->AddChild("Ellipse Drawing", 6);
87  return root;
88 }
89 
90 // Takes care of the SVET_POPUP events.
91 // In our case, SVET_POPUP is used to set RGB values.
92 void SVPaint::PopupHandler(const SVEvent* sv_event) {
93  // Since we only have the RGB values as popup items,
94  // we take a shortcut to not bloat up code:
95  rgb[sv_event->command_id - 1] = atoi(sv_event->parameter);
96  window_->Pen(rgb[0], rgb[1], rgb[2]);
97 }
98 
99 // Takes care of the SVET_MENU events.
100 // In our case, we change either the click_mode_ (commands 1-3)
101 // or the drag_mode_ (commands 4-6).
102 void SVPaint::MenuBarHandler(const SVEvent* sv_event) {
103  if ((sv_event->command_id > 0) && (sv_event->command_id < 4)) {
104  click_mode_ = sv_event->command_id;
105  has_start_point_ = false;
106  } else { drag_mode_ = sv_event->command_id; }
107 }
108 
109 // Takes care of the SVET_CLICK events.
110 // Depending on the click_mode_ we are in, either do Point-to-Point drawing,
111 // point drawing, or draw text.
112 void SVPaint::ClickHandler(const SVEvent* sv_event) {
113  switch (click_mode_) {
114  case 1: //Point to Point
115  if (has_start_point_) { window_->DrawTo(sv_event->x, sv_event->y);
116  } else {
117  has_start_point_ = true;
118  window_->SetCursor(sv_event->x, sv_event->y);
119  }
120  break;
121  case 2: //Point Drawing..simulated by drawing a 1 pixel line.
122  window_->Line(sv_event->x, sv_event->y, sv_event->x, sv_event->y);
123  break;
124  case 3: //Text
125  // We show a modal input dialog on our window, then draw the input and
126  // finally delete the input pointer.
127  char* p = window_->ShowInputDialog("Text:");
128  window_->Text(sv_event->x, sv_event->y, p);
129  delete [] p;
130  break;
131  }
132 }
133 
134 // Takes care of the SVET_SELECTION events.
135 // Depending on the drag_mode_ we are in, either draw a line, a rectangle or
136 // an ellipse.
137 void SVPaint::SelectionHandler(const SVEvent* sv_event) {
138  switch (drag_mode_) {
139  //FIXME inversed x_size, y_size
140  case 4: //Line
141  window_->Line(sv_event->x, sv_event->y,
142  sv_event->x - sv_event->x_size,
143  sv_event->y - sv_event->y_size);
144  break;
145  case 5: //Rectangle
146  window_->Rectangle(sv_event->x, sv_event->y,
147  sv_event->x - sv_event->x_size,
148  sv_event->y - sv_event->y_size);
149  break;
150  case 6: //Ellipse
151  window_->Ellipse(sv_event->x - sv_event->x_size,
152  sv_event->y - sv_event->y_size,
153  sv_event->x_size, sv_event->y_size);
154  break;
155  }
156 }
157 
158 // The event handling function from ScrollView which we have to overwrite.
159 // We handle CLICK, SELECTION, MENU and POPUP and throw away all other events.
160 void SVPaint::Notify(const SVEvent* sv_event) {
161  if (sv_event->type == SVET_CLICK) { ClickHandler(sv_event); }
162  else if (sv_event->type == SVET_SELECTION) { SelectionHandler(sv_event); }
163  else if (sv_event->type == SVET_MENU) { MenuBarHandler(sv_event); }
164  else if (sv_event->type == SVET_POPUP) { PopupHandler(sv_event); }
165  else {} //throw other events away
166 }
167 
168 // Builds a new window, initializes the variables and event handler and builds
169 // the menu.
170 SVPaint::SVPaint(const char *server_name) {
171  window_ = new ScrollView("ScrollView Paint Example", // window caption
172  0, 0, // x,y window position
173  500, 500, // window size
174  500, 500, // canvas size
175  false, // whether the Y axis is inversed.
176  // this is included due to legacy
177  // reasons for tesseract and enables
178  // us to have (0,0) as the LOWER left
179  // of the coordinate system.
180  server_name); // the server address.
181 
182  // Set the start modes to point-to-point and line drawing.
183  click_mode_ = 1;
184  drag_mode_ = 4;
185  has_start_point_ = false;
186 
187  // Bild our menus and add them to the window. The flag illustrates whether
188  // this is a menu bar.
189  SVMenuNode* popup_menu = BuildPopupMenu();
190  popup_menu->BuildMenu(window_,false);
191 
192  SVMenuNode* bar_menu = BuildMenuBar();
193  bar_menu->BuildMenu(window_,true);
194 
195  // Set the initial color values to White (could also be done by
196  // passing (rgb[0], rgb[1], rgb[2]).
197  window_->Pen(ScrollView::WHITE);
198  window_->Brush(ScrollView::WHITE);
199 
200  // Adds the event handler to the window. This actually ensures that Notify
201  // gets called when events occur.
202  window_->AddEventHandler(this);
203 
204  // Set the window visible (calling this is important to actually render
205  // everything. Without this call, the window would also be drawn, but the
206  // menu bars would be missing.
207  window_->SetVisible(true);
208 
209  // Rest this thread until its window is destroyed.
210  // Note that a special eventhandling thread was created when constructing
211  // the window. Due to this, the application will not deadlock here.
212  window_->AwaitEvent(SVET_DESTROY);
213  // We now have 3 Threads running:
214  // (1) The MessageReceiver thread which fetches messages and distributes them
215  // (2) The EventHandler thread which handles all events for window_
216  // (3) The main thread which waits on window_ for a DESTROY event (blocked)
217 }
218 
219 // If a parameter is given, we try to connect to the given server.
220 // This enables us to test the remote capabilites of ScrollView.
221 int main(int argc, char** argv) {
222  const char* server_name;
223  if (argc > 1) { server_name = argv[1]; } else { server_name = "localhost"; }
224  SVPaint svp(server_name);
225 }
226 #endif // GRAPHICS_DISABLED
void Pen(Color color)
Definition: scrollview.cpp:726
int main(int argc, char **argv)
Definition: svpaint.cpp:221
void Notify(const SVEvent *sv_event)
Definition: svpaint.cpp:160
void Text(int x, int y, const char *mystring)
Definition: scrollview.cpp:658
void DrawTo(int x, int y)
Definition: scrollview.cpp:531
int y
Definition: scrollview.h:67
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:121
int command_id
Definition: scrollview.h:70
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
Definition: scrollview.cpp:418
void SetCursor(int x, int y)
Definition: scrollview.cpp:525
void Brush(Color color)
Definition: scrollview.cpp:732
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:449
int x_size
Definition: scrollview.h:68
void Ellipse(int x, int y, int width, int height)
Definition: scrollview.cpp:615
char * parameter
Definition: scrollview.h:71
char * ShowInputDialog(const char *msg)
Definition: scrollview.cpp:740
SVPaint(const char *server_name)
Definition: svpaint.cpp:170
int rgb[3]
Definition: svpaint.cpp:26
SVEventType type
Definition: scrollview.h:64
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
int y_size
Definition: scrollview.h:69
void Line(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:538
void SetVisible(bool visible)
Definition: scrollview.cpp:555
int x
Definition: scrollview.h:66