tesseract
3.03
|
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