tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/viewer/svpaint.cpp
Go to the documentation of this file.
00001 // Copyright 2007 Google Inc. All Rights Reserved.
00002 //
00003 // Author: Joern Wanke
00004 //
00005 // Simple drawing program to illustrate ScrollView capabilities.
00006 //
00007 // Functionality:
00008 // - The menubar is used to select from different sample styles of input.
00009 // - With the RMB it is possible to change the RGB values in different
00010 //   popup menus.
00011 // - A LMB click either draws point-to-point, point or text.
00012 // - A LMB dragging either draws a line, a rectangle or ellipse.
00013 
00014 // Include automatically generated configuration file if running autoconf.
00015 #ifdef HAVE_CONFIG_H
00016 #include "config_auto.h"
00017 #endif
00018 
00019 #ifndef GRAPHICS_DISABLED
00020 #include "scrollview.h"
00021 #include "svmnode.h"
00022 #include <stdlib.h>
00023 #include <iostream>
00024 
00025 // The current color values we use, initially white (== ScrollView::WHITE).
00026 int rgb[3] = { 255, 255, 255 };
00027 
00028 class SVPaint : public SVEventHandler {
00029  public:
00030    SVPaint(const char* server_name);
00031 // This is the main event handling function that we need to overwrite, defined
00032 // in SVEventHandler.
00033    void Notify(const SVEvent* sv_event);
00034  private:
00035 // The Handler take care of the SVET_POPUP, SVET_MENU, SVET_CLICK and
00036 // SVET_SELECTION events.
00037    void PopupHandler(const SVEvent* sv_event);
00038    void MenuBarHandler(const SVEvent* sv_event);
00039    void ClickHandler(const SVEvent* sv_event);
00040    void SelectionHandler(const SVEvent* sv_event);
00041 
00042 // Convenience functions to build little menus.
00043    SVMenuNode* BuildPopupMenu();
00044    SVMenuNode* BuildMenuBar();
00045 
00046 // Our window.
00047    ScrollView* window_;
00048 
00049 // The mode we are in when an SVET_CLICK or an SVET_SELECTION event occurs.
00050    int click_mode_;
00051    int drag_mode_;
00052 
00053 // In the point-to-point drawing mode, we need to set a start-point the first
00054 // time we call it (e.g. call SetCursor).
00055    bool has_start_point_;
00056 };
00057 
00058 // Build a sample popup menu.
00059 SVMenuNode* SVPaint::BuildPopupMenu() {
00060   SVMenuNode* root = new SVMenuNode();  // Empty root node
00061   // Initial color is white, so we  all values to 255.
00062   root->AddChild("R",                   // Shown caption.
00063                   1,                    // assoc. command_id.
00064                  "255",                 // initial value.
00065                  "Red Color Value?");  // Shown description.
00066   root->AddChild("G", 2, "255", "Green Color Value?");
00067   root->AddChild("B", 3, "255", "Blue Color Value?");
00068   return root;
00069 }
00070 
00071 // Build a sample menu bar.
00072 SVMenuNode* SVPaint::BuildMenuBar() {
00073   SVMenuNode* root = new SVMenuNode();  // Empty root node
00074 
00075   // Create some submenus and add them to the root.
00076   SVMenuNode* click = root->AddChild("Clicking");
00077   SVMenuNode* drag = root->AddChild("Dragging");
00078   
00079   // Put some nodes into the submenus.
00080   click->AddChild("Point to Point Drawing",  // Caption.
00081                   1);                       // command_id.
00082   click->AddChild("Point Drawing", 2);
00083   click->AddChild("Text Drawing", 3);
00084   drag->AddChild("Line Drawing", 4);
00085   drag->AddChild("Rectangle Drawing", 5);
00086   drag->AddChild("Ellipse Drawing", 6);
00087   return root;
00088 }
00089 
00090 // Takes care of the SVET_POPUP events.
00091 // In our case, SVET_POPUP is used to set RGB values.
00092 void SVPaint::PopupHandler(const SVEvent* sv_event) {
00093   // Since we only have the RGB values as popup items,
00094   // we take a shortcut to not bloat up code:
00095   rgb[sv_event->command_id - 1] = atoi(sv_event->parameter);
00096   window_->Pen(rgb[0], rgb[1], rgb[2]);
00097 }
00098 
00099 // Takes care of the SVET_MENU events.
00100 // In our case, we change either the click_mode_ (commands 1-3)
00101 // or the drag_mode_ (commands 4-6).
00102 void SVPaint::MenuBarHandler(const SVEvent* sv_event) {
00103   if ((sv_event->command_id > 0) && (sv_event->command_id < 4)) { 
00104   click_mode_ = sv_event->command_id;   
00105   has_start_point_ = false;
00106   } else { drag_mode_ = sv_event->command_id; }
00107 }
00108 
00109 // Takes care of the SVET_CLICK events.
00110 // Depending on the click_mode_ we are in, either do Point-to-Point drawing,
00111 // point drawing, or draw text.
00112 void SVPaint::ClickHandler(const SVEvent* sv_event) {
00113   switch (click_mode_) {
00114   case 1: //Point to Point
00115     if (has_start_point_) { window_->DrawTo(sv_event->x, sv_event->y);
00116     } else {
00117         has_start_point_ = true; 
00118         window_->SetCursor(sv_event->x, sv_event->y);
00119     }
00120     break;
00121   case 2: //Point Drawing..simulated by drawing a 1 pixel line.
00122     window_->Line(sv_event->x, sv_event->y, sv_event->x, sv_event->y);
00123     break;
00124   case 3: //Text
00125     // We show a modal input dialog on our window, then draw the input and
00126     // finally delete the input pointer.
00127     char* p = window_->ShowInputDialog("Text:");
00128     window_->Text(sv_event->x, sv_event->y, p);
00129     delete p;
00130     break;
00131   }
00132 }
00133 
00134 // Takes care of the SVET_SELECTION events.
00135 // Depending on the drag_mode_ we are in, either draw a line, a rectangle or
00136 // an ellipse.
00137 void SVPaint::SelectionHandler(const SVEvent* sv_event) {
00138   switch (drag_mode_) {
00139   //FIXME inversed x_size, y_size
00140     case 4: //Line
00141       window_->Line(sv_event->x, sv_event->y, 
00142                     sv_event->x - sv_event->x_size,
00143                     sv_event->y - sv_event->y_size);
00144       break;
00145     case 5: //Rectangle
00146       window_->Rectangle(sv_event->x, sv_event->y,
00147                          sv_event->x - sv_event->x_size,
00148                          sv_event->y - sv_event->y_size);
00149       break;
00150     case 6: //Ellipse
00151       window_->Ellipse(sv_event->x - sv_event->x_size,
00152                        sv_event->y - sv_event->y_size,
00153                        sv_event->x_size, sv_event->y_size);
00154       break;
00155     }
00156 }
00157 
00158 // The event handling function from ScrollView which we have to overwrite.
00159 // We handle CLICK, SELECTION, MENU and POPUP and throw away all other events.
00160 void SVPaint::Notify(const SVEvent* sv_event) {
00161   if (sv_event->type == SVET_CLICK) { ClickHandler(sv_event); }  
00162   else if (sv_event->type == SVET_SELECTION) { SelectionHandler(sv_event); }
00163   else if (sv_event->type == SVET_MENU) { MenuBarHandler(sv_event); }
00164   else if (sv_event->type == SVET_POPUP) { PopupHandler(sv_event); }
00165   else {} //throw other events away
00166 }
00167 
00168 // Builds a new window, initializes the variables and event handler and builds
00169 // the menu.
00170 SVPaint::SVPaint(const char *server_name) {
00171   window_ = new ScrollView("ScrollView Paint Example",  // window caption
00172                             0, 0,                       // x,y window position
00173                             500, 500,                   // window size
00174                                     500, 500,                   // canvas size
00175                             false,      // whether the Y axis is inversed.
00176                                         // this is included due to legacy 
00177                                         // reasons for tesseract and enables
00178                                         // us to have (0,0) as the LOWER left
00179                                         // of the coordinate system.
00180                             server_name);               // the server address.
00181 
00182   // Set the start modes to point-to-point and line drawing.
00183   click_mode_ = 1;
00184   drag_mode_ = 4;
00185   has_start_point_ = false;
00186 
00187   // Bild our menus and add them to the window. The flag illustrates whether
00188   // this is a menu bar.
00189   SVMenuNode* popup_menu = BuildPopupMenu();
00190   popup_menu->BuildMenu(window_,false);
00191         
00192   SVMenuNode* bar_menu = BuildMenuBar();
00193   bar_menu->BuildMenu(window_,true);
00194 
00195   // Set the initial color values to White (could also be done by
00196   // passing (rgb[0], rgb[1], rgb[2]).
00197   window_->Pen(ScrollView::WHITE);
00198   window_->Brush(ScrollView::WHITE);
00199 
00200   // Adds the event handler to the window. This actually ensures that Notify
00201   // gets called when events occur.
00202   window_->AddEventHandler(this);
00203 
00204   // Set the window visible (calling this is important to actually render
00205   // everything. Without this call, the window would also be drawn, but the
00206   // menu bars would be missing.
00207   window_->SetVisible(true);
00208 
00209   // Rest this thread until its window is destroyed.
00210   // Note that a special eventhandling thread was created when constructing
00211   // the window. Due to this, the application will not deadlock here.
00212   window_->AwaitEvent(SVET_DESTROY);
00213   // We now have 3 Threads running:
00214   // (1) The MessageReceiver thread which fetches messages and distributes them
00215   // (2) The EventHandler thread which handles all events for window_
00216   // (3) The main thread which waits on window_ for a DESTROY event (blocked)
00217 }
00218 
00219 // If a parameter is given, we try to connect to the given server.
00220 // This enables us to test the remote capabilites of ScrollView.
00221 int main(int argc, char** argv) {
00222         const char* server_name;
00223         if (argc > 1) { server_name = argv[1]; } else { server_name = "localhost"; }
00224         SVPaint svp(server_name);
00225 }
00226 #endif  // GRAPHICS_DISABLED
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines