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