summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'tesseract/src/viewer/svpaint.cpp')
-rw-r--r--tesseract/src/viewer/svpaint.cpp241
1 files changed, 241 insertions, 0 deletions
diff --git a/tesseract/src/viewer/svpaint.cpp b/tesseract/src/viewer/svpaint.cpp
new file mode 100644
index 00000000..2f981fcc
--- /dev/null
+++ b/tesseract/src/viewer/svpaint.cpp
@@ -0,0 +1,241 @@
+// Copyright 2007 Google Inc. All Rights Reserved.
+//
+// Author: Joern Wanke
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+// Simple drawing program to illustrate ScrollView capabilities.
+//
+// Functionality:
+// - The menubar is used to select from different sample styles of input.
+// - With the RMB it is possible to change the RGB values in different
+// popup menus.
+// - A LMB click either draws point-to-point, point or text.
+// - A LMB dragging either draws a line, a rectangle or ellipse.
+
+// Include automatically generated configuration file if running autoconf.
+#ifdef HAVE_CONFIG_H
+#include "config_auto.h"
+#endif
+
+#ifndef GRAPHICS_DISABLED
+#include "scrollview.h"
+#include "svmnode.h"
+
+#include <cstdlib>
+#include <iostream>
+
+namespace tesseract {
+
+// The current color values we use, initially white (== ScrollView::WHITE).
+static int rgb[3] = { 255, 255, 255 };
+
+class SVPaint : public SVEventHandler {
+ public:
+ explicit SVPaint(const char* server_name);
+// This is the main event handling function that we need to overwrite, defined
+// in SVEventHandler.
+ void Notify(const SVEvent* sv_event) override;
+ private:
+// The Handler take care of the SVET_POPUP, SVET_MENU, SVET_CLICK and
+// SVET_SELECTION events.
+ void PopupHandler(const SVEvent* sv_event);
+ void MenuBarHandler(const SVEvent* sv_event);
+ void ClickHandler(const SVEvent* sv_event);
+ void SelectionHandler(const SVEvent* sv_event);
+
+// Convenience functions to build little menus.
+ SVMenuNode* BuildPopupMenu();
+ SVMenuNode* BuildMenuBar();
+
+// Our window.
+ ScrollView* window_;
+
+// The mode we are in when an SVET_CLICK or an SVET_SELECTION event occurs.
+ int click_mode_;
+ int drag_mode_;
+
+// In the point-to-point drawing mode, we need to set a start-point the first
+// time we call it (e.g. call SetCursor).
+ bool has_start_point_;
+};
+
+// Build a sample popup menu.
+SVMenuNode* SVPaint::BuildPopupMenu() {
+ auto* root = new SVMenuNode(); // Empty root node
+ // Initial color is white, so we all values to 255.
+ root->AddChild("R", // Shown caption.
+ 1, // assoc. command_id.
+ "255", // initial value.
+ "Red Color Value?"); // Shown description.
+ root->AddChild("G", 2, "255", "Green Color Value?");
+ root->AddChild("B", 3, "255", "Blue Color Value?");
+ return root;
+}
+
+// Build a sample menu bar.
+SVMenuNode* SVPaint::BuildMenuBar() {
+ auto* root = new SVMenuNode(); // Empty root node
+
+ // Create some submenus and add them to the root.
+ SVMenuNode* click = root->AddChild("Clicking");
+ SVMenuNode* drag = root->AddChild("Dragging");
+
+ // Put some nodes into the submenus.
+ click->AddChild("Point to Point Drawing", // Caption.
+ 1); // command_id.
+ click->AddChild("Point Drawing", 2);
+ click->AddChild("Text Drawing", 3);
+ drag->AddChild("Line Drawing", 4);
+ drag->AddChild("Rectangle Drawing", 5);
+ drag->AddChild("Ellipse Drawing", 6);
+ return root;
+}
+
+// Takes care of the SVET_POPUP events.
+// In our case, SVET_POPUP is used to set RGB values.
+void SVPaint::PopupHandler(const SVEvent* sv_event) {
+ // Since we only have the RGB values as popup items,
+ // we take a shortcut to not bloat up code:
+ rgb[sv_event->command_id - 1] = atoi(sv_event->parameter);
+ window_->Pen(rgb[0], rgb[1], rgb[2]);
+}
+
+// Takes care of the SVET_MENU events.
+// In our case, we change either the click_mode_ (commands 1-3)
+// or the drag_mode_ (commands 4-6).
+void SVPaint::MenuBarHandler(const SVEvent* sv_event) {
+ if ((sv_event->command_id > 0) && (sv_event->command_id < 4)) {
+ click_mode_ = sv_event->command_id;
+ has_start_point_ = false;
+ } else { drag_mode_ = sv_event->command_id; }
+}
+
+// Takes care of the SVET_CLICK events.
+// Depending on the click_mode_ we are in, either do Point-to-Point drawing,
+// point drawing, or draw text.
+void SVPaint::ClickHandler(const SVEvent* sv_event) {
+ switch (click_mode_) {
+ case 1: //Point to Point
+ if (has_start_point_) { window_->DrawTo(sv_event->x, sv_event->y);
+ } else {
+ has_start_point_ = true;
+ window_->SetCursor(sv_event->x, sv_event->y);
+ }
+ break;
+ case 2: //Point Drawing..simulated by drawing a 1 pixel line.
+ window_->Line(sv_event->x, sv_event->y, sv_event->x, sv_event->y);
+ break;
+ case 3: //Text
+ // We show a modal input dialog on our window, then draw the input and
+ // finally delete the input pointer.
+ char* p = window_->ShowInputDialog("Text:");
+ window_->Text(sv_event->x, sv_event->y, p);
+ delete [] p;
+ break;
+ }
+}
+
+// Takes care of the SVET_SELECTION events.
+// Depending on the drag_mode_ we are in, either draw a line, a rectangle or
+// an ellipse.
+void SVPaint::SelectionHandler(const SVEvent* sv_event) {
+ switch (drag_mode_) {
+ //FIXME inversed x_size, y_size
+ case 4: //Line
+ window_->Line(sv_event->x, sv_event->y,
+ sv_event->x - sv_event->x_size,
+ sv_event->y - sv_event->y_size);
+ break;
+ case 5: //Rectangle
+ window_->Rectangle(sv_event->x, sv_event->y,
+ sv_event->x - sv_event->x_size,
+ sv_event->y - sv_event->y_size);
+ break;
+ case 6: //Ellipse
+ window_->Ellipse(sv_event->x - sv_event->x_size,
+ sv_event->y - sv_event->y_size,
+ sv_event->x_size, sv_event->y_size);
+ break;
+ }
+}
+
+// The event handling function from ScrollView which we have to overwrite.
+// We handle CLICK, SELECTION, MENU and POPUP and throw away all other events.
+void SVPaint::Notify(const SVEvent* sv_event) {
+ if (sv_event->type == SVET_CLICK) { ClickHandler(sv_event); }
+ else if (sv_event->type == SVET_SELECTION) { SelectionHandler(sv_event); }
+ else if (sv_event->type == SVET_MENU) { MenuBarHandler(sv_event); }
+ else if (sv_event->type == SVET_POPUP) { PopupHandler(sv_event); }
+ //throw other events away
+}
+
+// Builds a new window, initializes the variables and event handler and builds
+// the menu.
+SVPaint::SVPaint(const char *server_name) {
+ window_ = new ScrollView("ScrollView Paint Example", // window caption
+ 0, 0, // x,y window position
+ 500, 500, // window size
+ 500, 500, // canvas size
+ false, // whether the Y axis is inversed.
+ // this is included due to legacy
+ // reasons for tesseract and enables
+ // us to have (0,0) as the LOWER left
+ // of the coordinate system.
+ server_name); // the server address.
+
+ // Set the start modes to point-to-point and line drawing.
+ click_mode_ = 1;
+ drag_mode_ = 4;
+ has_start_point_ = false;
+
+ // Bild our menus and add them to the window. The flag illustrates whether
+ // this is a menu bar.
+ SVMenuNode* popup_menu = BuildPopupMenu();
+ popup_menu->BuildMenu(window_,false);
+
+ SVMenuNode* bar_menu = BuildMenuBar();
+ bar_menu->BuildMenu(window_,true);
+
+ // Set the initial color values to White (could also be done by
+ // passing (rgb[0], rgb[1], rgb[2]).
+ window_->Pen(ScrollView::WHITE);
+ window_->Brush(ScrollView::WHITE);
+
+ // Adds the event handler to the window. This actually ensures that Notify
+ // gets called when events occur.
+ window_->AddEventHandler(this);
+
+ // Set the window visible (calling this is important to actually render
+ // everything. Without this call, the window would also be drawn, but the
+ // menu bars would be missing.
+ window_->SetVisible(true);
+
+ // Rest this thread until its window is destroyed.
+ // Note that a special eventhandling thread was created when constructing
+ // the window. Due to this, the application will not deadlock here.
+ window_->AwaitEvent(SVET_DESTROY);
+ // We now have 3 Threads running:
+ // (1) The MessageReceiver thread which fetches messages and distributes them
+ // (2) The EventHandler thread which handles all events for window_
+ // (3) The main thread which waits on window_ for a DESTROY event (blocked)
+}
+
+} // namespace tesseract
+
+// If a parameter is given, we try to connect to the given server.
+// This enables us to test the remote capabilities of ScrollView.
+int main(int argc, char** argv) {
+ const char* server_name;
+ if (argc > 1) { server_name = argv[1]; } else { server_name = "localhost"; }
+ tesseract::SVPaint svp(server_name);
+}
+
+#endif // !GRAPHICS_DISABLED