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