tesseract v5.3.3.20231005
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
35namespace tesseract {
36
37// The current color values we use, initially white (== ScrollView::WHITE).
38static int rgb[3] = {255, 255, 255};
39
40class SVPaint : public SVEventHandler {
41public:
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
47private:
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.
72SVMenuNode *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.
85SVMenuNode *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.
105void 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).
115void 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.
127void 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.
153void 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.
173void 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.
188SVPaint::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.
241int 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
const char * p
@ SVET_SELECTION
Definition: scrollview.h:57
@ SVET_DESTROY
Definition: scrollview.h:54
@ SVET_POPUP
Definition: scrollview.h:62
@ SVET_CLICK
Definition: scrollview.h:56
SVPaint(const char *server_name)
Definition: svpaint.cpp:188
void Notify(const SVEvent *sv_event) override
Definition: svpaint.cpp:173
SVEventType type
Definition: scrollview.h:74
void Line(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:498
char * ShowInputDialog(const char *msg)
Definition: scrollview.cpp:722
std::unique_ptr< SVEvent > AwaitEvent(SVEventType type)
Definition: scrollview.cpp:432
void Text(int x, int y, const char *mystring)
Definition: scrollview.cpp:635
void SetVisible(bool visible)
Definition: scrollview.cpp:515
void Pen(Color color)
Definition: scrollview.cpp:710
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
Definition: scrollview.cpp:408
void Brush(Color color)
Definition: scrollview.cpp:716
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:576
void SetCursor(int x, int y)
Definition: scrollview.cpp:485
void Ellipse(int x, int y, int width, int height)
Definition: scrollview.cpp:585
void DrawTo(int x, int y)
Definition: scrollview.cpp:491
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:120