diff options
Diffstat (limited to 'tesseract/src/viewer/svpaint.cpp')
-rw-r--r-- | tesseract/src/viewer/svpaint.cpp | 241 |
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 |