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