1 /////////////////////////////////////////////////////////////////////// 2 // File: scrollview.h 3 // Description: ScrollView 4 // Author: Joern Wanke 5 // Created: Thu Nov 29 2007 6 // 7 // (C) Copyright 2007, Google Inc. 8 // Licensed under the Apache License, Version 2.0 (the "License"); 9 // you may not use this file except in compliance with the License. 10 // You may obtain a copy of the License at 11 // http://www.apache.org/licenses/LICENSE-2.0 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 // 18 /////////////////////////////////////////////////////////////////////// 19 // 20 // ScrollView is designed as an UI which can be run remotely. This is the 21 // client code for it, the server part is written in java. The client consists 22 // mainly of 2 parts: 23 // The "core" ScrollView which sets up the remote connection, 24 // takes care of event handling etc. 25 // The other part of ScrollView consists of predefined API calls through LUA, 26 // which can basically be used to get a zoomable canvas in which it is possible 27 // to draw lines, text etc. 28 // Technically, thanks to LUA, its even possible to bypass the here defined LUA 29 // API calls at all and generate a java user interface from scratch (or 30 // basically generate any kind of java program, possibly even dangerous ones). 31 32 #ifndef TESSERACT_VIEWER_SCROLLVIEW_H__ 33 #define TESSERACT_VIEWER_SCROLLVIEW_H__ 34 35 #include <stdio.h> 36 37 class ScrollView; 38 class SVNetwork; 39 class SVMutex; 40 class SVSemaphore; 41 struct SVPolyLineBuffer; 42 43 enum SVEventType { 44 SVET_DESTROY, // Window has been destroyed by user. 45 SVET_EXIT, // User has destroyed the last window by clicking on the 'X'. 46 SVET_CLICK, // Left button pressed. 47 SVET_SELECTION, // Left button selection. 48 SVET_INPUT, // There is some input (single key or a whole string). 49 SVET_MOUSE, // The mouse has moved with a button pressed. 50 SVET_MOTION, // The mouse has moved with no button pressed. 51 SVET_HOVER, // The mouse has stayed still for a second. 52 SVET_POPUP, // A command selected through a popup menu. 53 SVET_MENU, // A command selected through the menubar. 54 SVET_ANY, // Any of the above. 55 56 SVET_COUNT // Array sizing. 57 }; 58 59 struct SVEvent { ~SVEventSVEvent60 ~SVEvent() { delete [] parameter; } 61 SVEvent* copy(); 62 SVEventType type; // What kind of event. 63 ScrollView* window; // Window event relates to. 64 int x; // Coords of click or selection. 65 int y; 66 int x_size; // Size of selection. 67 int y_size; 68 int command_id; // The ID of the possibly associated event (e.g. MENU) 69 char* parameter; // Any string that might have been passed as argument. 70 int counter; // Used to detect which kind of event to process next. 71 SVEventSVEvent72 SVEvent() { 73 window = NULL; 74 parameter = NULL; 75 } 76 77 SVEvent(const SVEvent&); 78 SVEvent& operator=(const SVEvent&); 79 }; 80 81 // The SVEventHandler class is used for Event handling: If you register your 82 // class as SVEventHandler to a ScrollView Window, the SVEventHandler will be 83 // called whenever an appropriate event occurs. 84 class SVEventHandler { 85 public: ~SVEventHandler()86 virtual ~SVEventHandler() {} 87 88 // Gets called by the SV Window. Does nothing on default, overwrite this 89 // to implement the desired behaviour Notify(const SVEvent * sve)90 virtual void Notify(const SVEvent* sve) { } 91 }; 92 93 // The ScrollView class provides the expernal API to the scrollviewer process. 94 // The scrollviewer process manages windows and displays images, graphics and 95 // text while allowing the user to zoom and scroll the windows arbitrarily. 96 // Each ScrollView class instance represents one window, and stuff is drawn in 97 // the window through method calls on the class. The constructor is used to 98 // create the class instance (and the window). 99 100 class ScrollView { 101 public: 102 // Color enum for pens and brushes. 103 enum Color { 104 NONE, 105 BLACK, 106 WHITE, 107 RED, 108 YELLOW, 109 GREEN, 110 CYAN, 111 BLUE, 112 MAGENTA, 113 AQUAMARINE, 114 DARK_SLATE_BLUE, 115 LIGHT_BLUE, 116 MEDIUM_BLUE, 117 MIDNIGHT_BLUE, 118 NAVY_BLUE, 119 SKY_BLUE, 120 SLATE_BLUE, 121 STEEL_BLUE, 122 CORAL, 123 BROWN, 124 SANDY_BROWN, 125 GOLD, 126 GOLDENROD, 127 DARK_GREEN, 128 DARK_OLIVE_GREEN, 129 FOREST_GREEN, 130 LIME_GREEN, 131 PALE_GREEN, 132 YELLOW_GREEN, 133 LIGHT_GREY, 134 DARK_SLATE_GREY, 135 DIM_GREY, 136 GREY, 137 KHAKI, 138 MAROON, 139 ORANGE, 140 ORCHID, 141 PINK, 142 PLUM, 143 INDIAN_RED, 144 ORANGE_RED, 145 VIOLET_RED, 146 SALMON, 147 TAN, 148 TURQUOISE, 149 DARK_TURQUOISE, 150 VIOLET, 151 WHEAT, 152 GREEN_YELLOW // Make sure this one is last. 153 }; 154 155 #ifndef GRAPHICS_DISABLED 156 157 // Create a window. The pixel size of the window may be 0,0, in which case 158 // a default size is selected based on the size of your canvas. 159 // The canvas may not be 0,0 in size! 160 ScrollView(const char* name, int x_pos, int y_pos, int x_size, int y_size, 161 int x_canvas_size, int y_canvas_size); 162 // With a flag whether the x axis is reversed. 163 ScrollView(const char* name, int x_pos, int y_pos, int x_size, int y_size, 164 int x_canvas_size, int y_canvas_size, bool y_axis_reversed); 165 // Connect to a server other than localhost. 166 ScrollView(const char* name, int x_pos, int y_pos, int x_size, int y_size, 167 int x_canvas_size, int y_canvas_size, bool y_axis_reversed, 168 const char* server_name); 169 ~ScrollView(); 170 171 /******************************************************************************* 172 * Event handling 173 * To register as listener, the class has to derive from the SVEventHandler 174 * class, which consists of a notifyMe(SVEvent*) function that should be 175 * overwritten to process the event the way you want. 176 *******************************************************************************/ 177 178 // Add an Event Listener to this ScrollView Window. 179 void AddEventHandler(SVEventHandler* listener); 180 181 // Block until an event of the given type is received. 182 SVEvent* AwaitEvent(SVEventType type); 183 184 // Block until any event on any window is received. 185 SVEvent* AwaitEventAnyWindow(); 186 187 /******************************************************************************* 188 * Getters and Setters 189 *******************************************************************************/ 190 191 // Returns the title of the window. GetName()192 const char* GetName() { return window_name_; } 193 194 // Returns the unique ID of the window. GetId()195 int GetId() { return window_id_; } 196 197 /******************************************************************************* 198 * API functions for LUA calls 199 * the implementations for these can be found in svapi.cc 200 * (keep in mind that the window is actually created through the ScrollView 201 * constructor, so this is not listed here) 202 *******************************************************************************/ 203 204 // Draw a Pix on (x,y). 205 void Image(struct Pix* image, int x_pos, int y_pos); 206 207 // Flush buffers and update display. 208 static void Update(); 209 210 // Exit the program. 211 static void Exit(); 212 213 // Update the contents of a specific window. 214 void UpdateWindow(); 215 216 // Erase all content from the window, but do not destroy it. 217 void Clear(); 218 219 // Set pen color with an enum. 220 void Pen(Color color); 221 222 // Set pen color to RGB (0-255). 223 void Pen(int red, int green, int blue); 224 225 // Set pen color to RGBA (0-255). 226 void Pen(int red, int green, int blue, int alpha); 227 228 // Set brush color with an enum. 229 void Brush(Color color); 230 231 // Set brush color to RGB (0-255). 232 void Brush(int red, int green, int blue); 233 234 // Set brush color to RGBA (0-255). 235 void Brush(int red, int green, int blue, int alpha); 236 237 // Set attributes for future text, like font name (e.g. 238 // "Times New Roman"), font size etc.. 239 // Note: The underlined flag is currently not supported 240 void TextAttributes(const char* font, int pixel_size, 241 bool bold, bool italic, bool underlined); 242 243 // Draw line from (x1,y1) to (x2,y2) with the current pencolor. 244 void Line(int x1, int y1, int x2, int y2); 245 246 // Set the stroke width of the pen. 247 void Stroke(float width); 248 249 // Draw a rectangle given upper left corner and lower right corner. 250 // The current pencolor is used as outline, the brushcolor to fill the shape. 251 void Rectangle(int x1, int y1, int x2, int y2); 252 253 // Draw an ellipse centered on (x,y). 254 // The current pencolor is used as outline, the brushcolor to fill the shape. 255 void Ellipse(int x, int y, int width, int height); 256 257 // Draw text with the current pencolor 258 void Text(int x, int y, const char* mystring); 259 260 // Draw an image from a local filename. This should be faster than createImage. 261 // WARNING: This only works on a local machine. This also only works image 262 // types supported by java (like bmp,jpeg,gif,png) since the image is opened by 263 // the server. 264 void Image(const char* image, int x_pos, int y_pos); 265 266 // Set the current position to draw from (x,y). In conjunction with... 267 void SetCursor(int x, int y); 268 269 // ...this function, which draws a line from the current to (x,y) and then 270 // sets the new position to the new (x,y), this can be used to easily draw 271 // polygons using vertices 272 void DrawTo(int x, int y); 273 274 // Set the SVWindow visible/invisible. 275 void SetVisible(bool visible); 276 277 // Set the SVWindow always on top or not always on top. 278 void AlwaysOnTop(bool b); 279 280 // Shows a modal dialog with "msg" as question and returns 'y' or 'n'. 281 int ShowYesNoDialog(const char* msg); 282 283 // Shows a modal dialog with "msg" as question and returns a char* string. 284 // Constraint: As return, only words (e.g. no whitespaces etc.) are allowed. 285 char* ShowInputDialog(const char* msg); 286 287 // Adds a messagebox to the SVWindow. This way, it can show the messages... 288 void AddMessageBox(); 289 290 // ...which can be added by this command. 291 // This is intended as an "debug" output window. 292 void AddMessage(const char* format, ...); 293 294 // Zoom the window to the rectangle given upper left corner and 295 // lower right corner. 296 void ZoomToRectangle(int x1, int y1, int x2, int y2); 297 298 // Custom messages (manipulating java code directly) can be send through this. 299 // Send a message to the server and attach the Id of the corresponding window. 300 // Note: This should only be called if you are know what you are doing, since 301 // you are fiddling with the Java objects on the server directly. Calling 302 // this just for fun will likely break your application! 303 // It is public so you can actually take use of the LUA functionalities, but 304 // be careful! 305 void SendMsg(const char* msg, ...); 306 307 // Custom messages (manipulating java code directly) can be send through this. 308 // Send a message to the server without adding the 309 // window id. Used for global events like Exit(). 310 // Note: This should only be called if you are know what you are doing, since 311 // you are fiddling with the Java objects on the server directly. Calling 312 // this just for fun will likely break your application! 313 // It is public so you can actually take use of the LUA functionalities, but 314 // be careful! 315 static void SendRawMessage(const char* msg); 316 317 /******************************************************************************* 318 * Add new menu entries to parent. If parent is "", the entry gets added to the 319 * main menubar (toplevel). 320 *******************************************************************************/ 321 // This adds a new submenu to the menubar. 322 void MenuItem(const char* parent, const char* name); 323 324 // This adds a new (normal) menu entry with an associated eventID, which should 325 // be unique among menubar eventIDs. 326 void MenuItem(const char* parent, const char* name, int cmdEvent); 327 328 // This adds a new checkbox entry, which might initally be flagged. 329 void MenuItem(const char* parent, const char* name, 330 int cmdEvent, bool flagged); 331 332 // This adds a new popup submenu to the popup menu. If parent is "", the entry 333 // gets added at "toplevel" popupmenu. 334 void PopupItem(const char* parent, const char* name); 335 336 // This adds a new popup entry with the associated eventID, which should be 337 // unique among popup eventIDs. 338 // If value and desc are given, on a click the server will ask you to modify 339 // the value and return the new value. 340 void PopupItem(const char* parent, const char* name, 341 int cmdEvent, const char* value, const char* desc); 342 343 // Returns the correct Y coordinate for a window, depending on whether it might 344 // have to be flipped (by ySize). 345 int TranslateYCoordinate(int y); 346 347 private: 348 // Transfers a binary Image. 349 void TransferBinaryImage(struct Pix* image); 350 // Transfers a gray scale Image. 351 void TransferGrayImage(struct Pix* image); 352 // Transfers a 32-Bit Image. 353 void Transfer32bppImage(struct Pix* image); 354 355 // Sets up ScrollView, depending on the variables from the constructor. 356 void Initialize(const char* name, int x_pos, int y_pos, int x_size, 357 int y_size, int x_canvas_size, int y_canvas_size, 358 bool y_axis_reversed, const char* server_name); 359 360 // Send the current buffered polygon (if any) and clear it. 361 void SendPolygon(); 362 363 // Start the message receiving thread. 364 static void* MessageReceiver(void* a); 365 366 // Place an event into the event_table (synchronized). 367 void SetEvent(SVEvent* svevent); 368 369 // Wake up the semaphore. 370 void Signal(); 371 372 // Returns the unique, shared network stream. GetStream()373 static SVNetwork* GetStream() { return stream_; } 374 375 // Starts a new event handler. Called whenever a new window is created. 376 static void* StartEventHandler(void* sv); 377 378 // Escapes the ' character with a \, so it can be processed by LUA. 379 char* AddEscapeChars(const char* input); 380 381 // The event handler for this window. 382 SVEventHandler* event_handler_; 383 // The name of the window. 384 const char* window_name_; 385 // The id of the window. 386 int window_id_; 387 // The points of the currently under-construction polyline. 388 SVPolyLineBuffer* points_; 389 // Whether the axis is reversed. 390 bool y_axis_is_reversed_; 391 // If the y axis is reversed, flip all y values by ySize. 392 int y_size_; 393 // # of created windows (used to assign an id to each ScrollView* for svmap). 394 static int nr_created_windows_; 395 396 // The stream through which the c++ client is connected to the server. 397 static SVNetwork* stream_; 398 399 // Table of all the currently queued events. 400 SVEvent* event_table_[SVET_COUNT]; 401 402 // Mutex to access the event_table_ in a synchronized fashion. 403 SVMutex* mutex_; 404 405 // Semaphore to the thread belonging to this window. 406 SVSemaphore* semaphore_; 407 #endif // GRAPHICS_DISABLED 408 }; 409 410 #endif // TESSERACT_VIEWER_SCROLLVIEW_H__ 411