appkit  1.5.1
RoadNarrows Robotics Application Kit
WinGtk.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Roboitics Windowing Package
4 //
5 // Library: librnr_wingtk
6 //
7 // File: WinGtk.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2013-07-15 11:45:50 -0600 (Mon, 15 Jul 2013) $
12  * $Rev: 3131 $
13  *
14  * \brief RoadNarrows GTK derived window class implementation.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  * \author Daniel Packard (daniel@roadnarrows.com)
18  *
19  * \par Copyright
20  * \h_copy 2011-2017. RoadNarrows LLC.\n
21  * http://www.roadnarrows.com\n
22  * All Rights Reserved
23  */
24 /*
25  * @EulaBegin@
26  *
27  * Permission is hereby granted, without written agreement and without
28  * license or royalty fees, to use, copy, modify, and distribute this
29  * software and its documentation for any purpose, provided that
30  * (1) The above copyright notice and the following two paragraphs
31  * appear in all copies of the source code and (2) redistributions
32  * including binaries reproduces these notices in the supporting
33  * documentation. Substantial modifications to this software may be
34  * copyrighted by their authors and need not follow the licensing terms
35  * described here, provided that the new terms are clearly indicated in
36  * all files where they apply.
37  *
38  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
39  * OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
40  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
41  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
42  * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
43  * THE POSSIBILITY OF SUCH DAMAGE.
44  *
45  * THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
46  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
47  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
48  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
49  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
50  *
51  * @EulaEnd@
52  */
53 ////////////////////////////////////////////////////////////////////////////////
54 
55 #include <sys/types.h>
56 #include <stdarg.h>
57 #include <libgen.h>
58 #include <unistd.h>
59 
60 #include <string>
61 #include <map>
62 
63 #include "rnr/rnrconfig.h"
64 #include "rnr/log.h"
65 
66 #include "rnr/appkit/WinLookFeel.h"
67 #include "rnr/appkit/Win.h"
68 #include "rnr/appkit/WinGtk.h"
69 
70 #include "opencv2/core/core.hpp"
71 #include "opencv2/highgui/highgui.hpp"
72 
73 #include <gtk/gtk.h>
74 #include <gdk/gdk.h>
75 #include <gdk/gdkkeysyms.h>
76 #include <gdk/gdkx.h>
77 
78 using namespace std;
79 using namespace cv;
80 using namespace rnr;
81 
82 //
83 // OpenCv public but unpublizied functions and types
84 //
85 typedef struct _CvImageWidget CvImageWidget;
86 extern GtkWidget *cvImageWidgetNew(int flags);
87 extern void cvImageWidgetSetImage(CvImageWidget *widget, const CvArr *arr);
88 
89 
90 //------------------------------------------------------------------------------
91 // Class WinGtk
92 //------------------------------------------------------------------------------
93 
94 WinGtk::WinGtk(const string &strWinName,
95  int nWidth,
96  int nHeight,
97  bool bDecorate) :
98  Win(strWinName, nWidth, nHeight, bDecorate)
99 
100 {
101  const int nHBoxBorder = 6; // hbox outside border width
102  const int nMenuWidth = 48; // button menu width
103  const int nStatusBarHeight = 20; // status bar height
104  const int nWorkspaceBorder = 4; // workspace outside border width
105 
106  int nWorkspaceWidth;
107  int nWorkspaceHeight = nHeight - nStatusBarHeight;
108  GtkWidget *wHBox;
109  GtkWidget *wVBox;
110  GtkWidget *w;
111  int i;
112 
113  nWorkspaceWidth = nWidth - (nHBoxBorder + nMenuWidth + nWorkspaceBorder) * 2;
114  nWorkspaceHeight = nHeight - nHBoxBorder - nStatusBarHeight
115  - nWorkspaceBorder;
116 
117  // default colors & fonts
119 
120  // required
121  gtk_init(0, NULL);
122 
123  // create a new gtk window
124  m_wMain = gtk_window_new(GTK_WINDOW_TOPLEVEL);
125  m_wWindowMain = GTK_WINDOW(m_wMain);
126 
127  //
128  // Configure window's look and feel
129  //
130  gtk_window_set_title(m_wWindowMain, m_strWinName.c_str());
131  gtk_window_resize(m_wWindowMain, m_nWinWidth, m_nWinHeight);
132  gtk_window_set_decorated(m_wWindowMain, bDecorate);
133  gtk_widget_modify_bg(m_wMain, GTK_STATE_NORMAL, &m_mapColors["color_win_bg"]);
134  //gtk_widget_modify_base(m_wMain, GTK_STATE_NORMAL,
135  // &m_mapColors["color_win_bg"]);
136 
137  //
138  // Top-Level Container.
139  //
140  // Each window can only have one direct descendent widget. This is it: a
141  // vertical box that will contaion all child widgets.
142  //
143  m_wContainer = gtk_vbox_new(FALSE, 0);
144  gtk_container_add(GTK_CONTAINER(m_wMain), m_wContainer);
145 
146  //
147  // The left-menu, workspace, right-menu horizontal box container
148  //
149  wHBox = gtk_hbox_new(FALSE, 0);
150  gtk_container_set_border_width(GTK_CONTAINER(wHBox), nHBoxBorder);
151  gtk_box_pack_start(GTK_BOX(m_wContainer), wHBox, FALSE, FALSE, 0);
152 
153  //
154  // Left menu vertical button box container
155  //
156  w = gtk_vbutton_box_new();
157  gtk_button_box_set_layout(GTK_BUTTON_BOX(w), GTK_BUTTONBOX_START);
158  g_object_set(G_OBJECT(w),
159  "width-request", nMenuWidth,
160  "height-request", nWorkspaceHeight,
161  NULL);
162  gtk_container_set_border_width(GTK_CONTAINER(w), 2);
163  gtk_button_box_set_child_size(GTK_BUTTON_BOX(w), nMenuWidth, nMenuWidth);
164  gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX(w), 0, 0);
165  gtk_box_set_spacing(GTK_BOX(w), 1);
166  gtk_box_pack_start(GTK_BOX(wHBox), w, TRUE, TRUE, 0);
168 
169  //
170  // Middle workspace vertical box container
171  //
172  m_wWorkspace = gtk_vbox_new(FALSE, 0);
173  g_object_set(G_OBJECT(m_wWorkspace),
174  "width-request", nWorkspaceWidth,
175  "height-request", nWorkspaceHeight,
176  NULL);
177  gtk_widget_modify_bg(m_wWorkspace, GTK_STATE_NORMAL,
178  &m_mapColors["color_win_bg"]);
179  gtk_container_set_border_width(GTK_CONTAINER(m_wWorkspace), nWorkspaceBorder);
180  gtk_box_pack_start(GTK_BOX(wHBox), m_wWorkspace, FALSE, FALSE, 0);
181  m_rectWorkspace = cvRect(nMenuWidth, 0, nWorkspaceWidth, nWorkspaceHeight);
182  for(i=0; i<MaxCvImages; ++i)
183  {
184  m_wCvImage[i] = NULL;
185  m_wCvImageBox[i] = NULL;
186  }
187  m_wGstWin = NULL;
188 
189  //
190  // Right menu vertical button box container
191  //
192  w = gtk_vbutton_box_new();
193  gtk_button_box_set_layout(GTK_BUTTON_BOX(w), GTK_BUTTONBOX_START);
194  g_object_set(G_OBJECT(w),
195  "width-request", nMenuWidth,
196  "height-request", nWorkspaceHeight,
197  NULL);
198  gtk_button_box_set_child_size(GTK_BUTTON_BOX(w), nMenuWidth, nMenuWidth);
199  gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX(w), 0, 0);
200  gtk_box_set_spacing(GTK_BOX(w), 1);
201  gtk_box_pack_start(GTK_BOX(wHBox), w, TRUE, TRUE, 0);
203 
204  //
205  // Extra widgets vbox
206  //
207  m_wExtraVBox = gtk_vbox_new(FALSE, 0);
208  g_object_set(G_OBJECT(m_wExtraVBox),
209  "width-request", nWorkspaceWidth,
210  NULL);
211  gtk_box_pack_start(GTK_BOX(m_wContainer), m_wExtraVBox, FALSE, FALSE, 0);
212 
213  //
214  // Bottom status.
215  //
216  m_wStatusFrame = gtk_frame_new(NULL);
217  gtk_box_pack_start(GTK_BOX(m_wContainer), m_wStatusFrame, FALSE, FALSE, 0);
218  gtk_widget_modify_bg(m_wStatusFrame, GTK_STATE_NORMAL,
219  &m_mapColors["color_status_border"]);
220  gtk_container_set_border_width(GTK_CONTAINER(m_wStatusFrame), 3);
221 
222  wHBox = gtk_hbox_new(FALSE, 0);
223  gtk_container_add(GTK_CONTAINER(m_wStatusFrame), wHBox);
224 
225  // page reference
226  m_wPageRef = gtk_label_new("");
227  gtk_widget_modify_fg(m_wPageRef, GTK_STATE_NORMAL,
228  &m_mapColors["color_status_fg"]);
229  gtk_widget_modify_bg(m_wPageRef, GTK_STATE_NORMAL,
230  &m_mapColors["color_status_bg"]);
231  g_object_set(G_OBJECT(m_wPageRef),
232  "width-request", nMenuWidth,
233  "height-request", nStatusBarHeight,
234  NULL);
235  gtk_label_set_justify(GTK_LABEL(m_wPageRef), GTK_JUSTIFY_LEFT);
236  gtk_box_pack_start(GTK_BOX(wHBox), m_wPageRef, FALSE, FALSE, 4);
237 
238  // status bar
239  m_wStatusBar = gtk_label_new("");
240  gtk_widget_modify_fg(m_wStatusBar, GTK_STATE_NORMAL,
241  &m_mapColors["color_status_fg"]);
242  gtk_widget_modify_bg(m_wStatusBar, GTK_STATE_NORMAL,
243  &m_mapColors["color_status_bg"]);
244  g_object_set(G_OBJECT(m_wStatusBar),
245  "width-request", nWorkspaceWidth-nMenuWidth,
246  "height-request", nStatusBarHeight,
247  NULL);
248  gtk_label_set_justify(GTK_LABEL(m_wStatusBar), GTK_JUSTIFY_LEFT);
249  gtk_misc_set_alignment(GTK_MISC(m_wStatusBar), 0, 0.5);
250  gtk_box_pack_start(GTK_BOX(wHBox), m_wStatusBar, FALSE, FALSE, 4);
251 
252  //
253  // Install event handlers
254  //
255  gtk_signal_connect(GTK_OBJECT(m_wMain), "key-press-event",
256  GTK_SIGNAL_FUNC(WinGtk::onKeyPress), this);
257 
258 
259  // show window
260  gtk_widget_show_all(m_wMain);
261 }
262 
264 {
265  MapPangoFont_T::iterator iter;
266 
267  gtk_widget_destroy(m_wMain);
268 
269  // delete all font decsriptors
270  for(iter=m_mapFonts.begin(); iter!=m_mapFonts.end(); ++iter)
271  {
272  pango_font_description_free(iter->second);
273  }
274 }
275 
276 void WinGtk::setLookAndFeel(const std::string &strKey,
277  const std::string &strVal)
278 {
279  GdkColor color;
280  PangoFontDescription *pFont;
281 
282  Win::setLookAndFeel(strKey, strVal);
283 
284  if( strKey.find("color") == 0 )
285  {
286  gdk_color_parse(strVal.c_str(), &color);
287  m_mapColors[strKey] = color;
288 
289  if( strKey == "color_win_bg" )
290  {
291  gtk_widget_modify_bg(m_wMain, GTK_STATE_NORMAL, &color);
292  gtk_widget_modify_base(m_wMain, GTK_STATE_NORMAL, &color);
293  gtk_widget_modify_bg(m_wWorkspace, GTK_STATE_NORMAL, &color);
294  }
295  else if( strKey == "color_status_fg" )
296  {
297  gtk_widget_modify_fg(m_wPageRef, GTK_STATE_NORMAL, &color);
298  gtk_widget_modify_fg(m_wStatusBar, GTK_STATE_NORMAL, &color);
299  }
300  else if( strKey == "color_status_bg" )
301  {
302  }
303  else if( strKey == "color_status_border" )
304  {
305  gtk_widget_modify_bg(m_wStatusFrame, GTK_STATE_NORMAL, &color);
306  }
307  else if( strKey == "color_button_bg" )
308  {
309  for(size_t i=0; i<NumOfButtonMenus; ++i)
310  {
311  for(size_t j=0; j<m_mapBttns[i].size(); ++i)
312  {
313  gtk_widget_modify_bg(m_mapBttns[i][j].m_wBttn, GTK_STATE_NORMAL,
314  &color);
315  gtk_widget_modify_bg(m_mapBttns[i][j].m_wBttn, GTK_STATE_INSENSITIVE,
316  &color);
317  }
318  }
319  }
320  }
321 
322  else if( strKey.find("font") == 0 )
323  {
324  pFont = pango_font_description_from_string(strVal.c_str());
325  m_mapFonts[strKey] = pFont;
326  }
327 
328  showWorkspace();
329 }
330 
331 void WinGtk::showCvImage(Mat &img, uint_t uImgIndex)
332 {
333  if( (uImgIndex < MaxCvImages) && (m_wCvImage[uImgIndex] != NULL) )
334  {
335  uint_t i = uImgIndex;
336 
337  cvImageWidgetSetImage((CvImageWidget *)m_wCvImage[i], &img);
338  m_sizeCvImage[i] = Size(img.cols, img.rows);
339  m_ptCvImageOrig[i].x = (m_rectWorkspace.width - m_sizeCvImage[i].width) / 2;
340  m_ptCvImageOrig[i].y = (m_rectWorkspace.height - m_sizeCvImage[i].height)/2;
341  if( m_ptCvImageOrig[i].x < 0 )
342  {
343  m_ptCvImageOrig[i].x = 0;
344  }
345  if( m_ptCvImageOrig[i].y < 0 )
346  {
347  m_ptCvImageOrig[i].y = 0;
348  }
349  gtk_widget_show(m_wCvImage[i]);
350  }
351  else
352  {
353  LOGERROR("Workspace has no CvImage[%u] widget.", uImgIndex);
354  }
355 }
356 
357 void WinGtk::showPageRef(int nPageRef)
358 {
359  char buf[16];
360 
361  // format status text
362  snprintf(buf, sizeof(buf), "%d", nPageRef);
363  buf[sizeof(buf)-1] = 0;
364 
365  gtk_label_set_text(GTK_LABEL(m_wPageRef), buf);
366  gtk_widget_show(m_wPageRef);
367 }
368 
369 void WinGtk::showPageRef(const string &strPageRef)
370 {
371  if( !strPageRef.empty() )
372  {
373  gtk_label_set_text(GTK_LABEL(m_wPageRef), strPageRef.c_str());
374  gtk_widget_show(m_wPageRef);
375  }
376 }
377 
378 void WinGtk::showStatus(const char *sFmt, ...)
379 {
380  char buf[256];
381  va_list ap;
382 
383  // format status text
384  va_start(ap, sFmt);
385  vsnprintf(buf, sizeof(buf), sFmt, ap);
386  buf[sizeof(buf)-1] = 0;
387  va_end(ap);
388 
389  gtk_label_set_text(GTK_LABEL(m_wStatusBar), buf);
390  gtk_widget_show(m_wStatusBar);
391 }
392 
393 /*!
394  * \brief Clear status message.
395  */
397 {
398  gtk_label_set_text(GTK_LABEL(m_wStatusBar), "");
399  gtk_widget_show(m_wStatusBar);
400 }
401 
402 int WinGtk::waitKey(int delay)
403 {
404  int expired = 0;
405  guint timer = 0;
406  int key;
407 
408  // set alarm timer
409  if( delay > 0 )
410  {
411  timer = g_timeout_add(delay, WinGtk::onAlarm, &expired);
412  }
413 
414  // wait for keyboard press
415  while( gtk_main_iteration_do(FALSE) &&
416  (m_uLastKey == 0) &&
417  !expired );
418 
419  // got a keyboard press
420  if( !expired )
421  {
422  // cancel timer
423  if( delay > 0 )
424  {
425  g_source_remove(timer);
426  }
427  key = (int)m_uLastKey;
428  m_uLastKey = 0;
429  }
430 
431  // expired without keyboard event
432  else
433  {
434  key = -1;
435  }
436 
437  return key;
438 }
439 
440 void WinGtk::waitMouse(int delay)
441 {
442  int expired = 0;
443  guint timer = 0;
444 
445  // causes an infinite block
446  if( delay <= 0 )
447  {
448  return;
449  }
450 
451  timer = g_timeout_add(delay, WinGtk::onAlarm, &expired);
452 
453  m_bMouseEvent = false;
454 
455  while( gtk_main_iteration_do(FALSE) && !expired && !m_bMouseEvent );
456 
457  if( !expired )
458  {
459  m_bMouseEvent = false;
460  g_source_remove(timer);
461  }
462 }
463 
464 void WinGtk::wait(int delay)
465 {
466  int expired = 0;
467  guint timer = 0;
468 
469  // causes an infinite block
470  if( delay <= 0 )
471  {
472  return;
473  }
474 
475  timer = g_timeout_add(delay, WinGtk::onAlarm, &expired);
476 
477  while( gtk_main_iteration_do(FALSE) && !expired );
478 }
479 
480 bool WinGtk::addImageButton(int nBttnId,
481  AlignOp eAlign,
482  const string &strIconPath,
483  const string &strAltText,
484  const string &strToolTip)
485 {
486  GtkWidget *wBttnImg = NULL;
487  GtkWidget *wBttn;
488 
489  if( !strIconPath.empty() && (access(strIconPath.c_str(), F_OK|R_OK) == 0) )
490  {
491  wBttnImg = gtk_image_new_from_file(strIconPath.c_str());
492  }
493 
494  if( wBttnImg == NULL )
495  {
496  return addLabelButton(nBttnId, eAlign, strAltText, strToolTip);
497  }
498 
499  wBttn = gtk_button_new();
500 
501  gtk_widget_modify_bg(wBttn, GTK_STATE_NORMAL,
502  &m_mapColors["color_button_bg"]);
503  gtk_widget_modify_bg(wBttn, GTK_STATE_INSENSITIVE,
504  &m_mapColors["color_button_bg"]);
505  gtk_button_set_image(GTK_BUTTON(wBttn), wBttnImg);
506  gtk_widget_set_tooltip_text(wBttn,
507  strToolTip.empty()? NULL: strToolTip.c_str());
508 
509  return addButton(nBttnId, eAlign, wBttn);
510 }
511 
512 bool WinGtk::addImageButton(int nBttnId,
513  AlignOp eAlign,
514  void *wBttnImg,
515  const string &strAltText,
516  const string &strToolTip)
517 {
518  GtkWidget *wBttn;
519 
520  if( wBttnImg != NULL )
521  {
522  wBttn = gtk_button_new();
523  gtk_widget_modify_bg(wBttn, GTK_STATE_NORMAL,
524  &m_mapColors["color_button_bg"]);
525  gtk_widget_modify_bg(wBttn, GTK_STATE_INSENSITIVE,
526  &m_mapColors["color_button_bg"]);
527  gtk_button_set_image(GTK_BUTTON(wBttn), (GtkWidget *)wBttnImg);
528  gtk_widget_set_tooltip_text(wBttn,
529  strToolTip.empty()? NULL: strToolTip.c_str());
530 
531  return addButton(nBttnId, eAlign, wBttn);
532  }
533  else
534  {
535  return addLabelButton(nBttnId, eAlign, strAltText, strToolTip);
536  }
537 }
538 
539 bool WinGtk::addLabelButton(int nBttnId,
540  AlignOp eAlign,
541  const string &strLabel,
542  const string &strToolTip)
543 {
544  GtkWidget *wBttn;
545 
546  if( !strLabel.empty() )
547  {
548  wBttn = gtk_button_new_with_label(strLabel.c_str());
549  }
550  else
551  {
552  char buf[16];
553  snprintf(buf, sizeof(buf), "Bttn %d", nBttnId);
554  buf[sizeof(buf)-1] = 0;
555  wBttn = gtk_button_new_with_label(buf);
556  }
557 
558  gtk_widget_modify_bg(wBttn, GTK_STATE_NORMAL,
559  &m_mapColors["color_button_bg"]);
560  gtk_widget_modify_bg(wBttn, GTK_STATE_INSENSITIVE,
561  &m_mapColors["color_button_bg"]);
562  gtk_widget_set_tooltip_text(wBttn,
563  strToolTip.empty()? NULL: strToolTip.c_str());
564 
565  return addButton(nBttnId, eAlign, wBttn);
566 }
567 
568 bool WinGtk::addButton(int nBttnId, AlignOp eAlign, GtkWidget *wBttn)
569 {
570  BttnInfo_T info;
571  int n = getBttnMenuIdx(eAlign);
572 
573  info.m_nBttnId = nBttnId;
574  info.m_wBttn = wBttn;
575  info.m_pWin = this;
576 
577  // add to button map
578  m_mapBttns[n][nBttnId] = info;
579 
580  // bind button press event
581  gtk_signal_connect(GTK_OBJECT(wBttn), "clicked",
582  GTK_SIGNAL_FUNC(onButtonClick),
583  &m_mapBttns[n][nBttnId]);
584 
585  gtk_box_pack_start(GTK_BOX(m_wBttnMenu[n]), wBttn, TRUE, TRUE, 0);
586 
587  // RDK TODO Need to center image with 1 px border to fit 5 buttons/side
588  //GtkBorder bttnborder = {1,1,1,1};
589  //gfloat x, y;
590  //gtk_button_set_image_position(GTK_BUTTON(wBttn), GTK_POS_RIGHT);
591  gtk_button_set_alignment(GTK_BUTTON(wBttn), 0.5, 0.5);
592  //g_object_set(G_OBJECT(wBttn),
593  // image-position", GTK_POS_RIGHT,
594  // "inner-border", &bttnborder,
595  // "image-spacing", 0,
596  // NULL);
597  //gtk_widget_set_size_request(wBttn, 50, 50);
598 
599  // show
600  gtk_widget_show(wBttn);
601  gtk_widget_show(m_wMain);
602  gtk_widget_queue_draw( GTK_WIDGET(wBttn) );
603 
604  return true;
605 }
606 
607 bool WinGtk::replaceButtonImage(int nBttnId,
608  const string &strIconPath,
609  const string &strToolTip)
610 {
611  MapBttns_T::iterator pos;
612  GtkWidget *wBttnImg = NULL;
613  GtkWidget *wBttn;
614 
615  if( !findBttn(nBttnId, pos) )
616  {
617  return false;
618  }
619 
620  if( !strIconPath.empty() && (access(strIconPath.c_str(), F_OK|R_OK) == 0) )
621  {
622  wBttnImg = gtk_image_new_from_file(strIconPath.c_str());
623  }
624 
625  if( wBttnImg == NULL )
626  {
627  return false;
628  }
629 
630  wBttn = pos->second.m_wBttn;
631 
632  gtk_button_set_image(GTK_BUTTON(wBttn), wBttnImg);
633 
634  gtk_widget_set_tooltip_text(wBttn,
635  strToolTip.empty()? NULL: strToolTip.c_str());
636 
637  // redraw
638  gtk_widget_show(wBttn);
639  gtk_widget_show(m_wMain);
640 
641  return true;
642 }
643 
644 bool WinGtk::replaceButtonImage(int nBttnId,
645  void *wBttnImg,
646  const string &strToolTip)
647 {
648  MapBttns_T::iterator pos;
649  GtkWidget *wBttn;
650 
651  if( !findBttn(nBttnId, pos) )
652  {
653  return false;
654  }
655 
656  wBttn = pos->second.m_wBttn;
657 
658  gtk_button_set_image(GTK_BUTTON(wBttn), (GtkWidget *)wBttnImg);
659 
660  gtk_widget_set_tooltip_text(wBttn,
661  strToolTip.empty()? NULL: strToolTip.c_str());
662 
663  // redraw
664  gtk_widget_show(wBttn);
665  gtk_widget_show(m_wMain);
666 
667  return true;
668 }
669 
670 bool WinGtk::replaceButtonLabel(int nBttnId,
671  const std::string &strLabel,
672  const std::string &strToolTip)
673 {
674  MapBttns_T::iterator pos;
675  GtkWidget *wBttn;
676 
677  if( !findBttn(nBttnId, pos) )
678  {
679  return false;
680  }
681 
682  wBttn = pos->second.m_wBttn;
683 
684  gtk_button_set_label(GTK_BUTTON(wBttn), strLabel.c_str());
685 
686  gtk_widget_set_tooltip_text(wBttn,
687  strToolTip.empty()? NULL: strToolTip.c_str());
688 
689  // redraw
690  gtk_widget_show(wBttn);
691  gtk_widget_show(m_wMain);
692 
693  return true;
694 }
695 
696 bool WinGtk::removeButton(int nBttnId)
697 {
698  MapBttns_T::iterator pos;
699  int n;
700  GtkWidget *wBttn;
701 
702  if( (pos = m_mapBttns[0].find(nBttnId)) != m_mapBttns[0].end() )
703  {
704  n = 0;
705  }
706  else if( (pos = m_mapBttns[1].find(nBttnId)) != m_mapBttns[1].end() )
707  {
708  n = 1;
709  }
710  else
711  {
712  return false;
713  }
714 
715  wBttn = pos->second.m_wBttn;
716 
717  //
718  // Replace any exiting button image with NULL or the image widget is hosed
719  // for reuse.
720  //
721  gtk_button_set_image(GTK_BUTTON(wBttn), NULL);
722 
723  // remove widget from gui
724  gtk_container_remove(GTK_CONTAINER(m_wBttnMenu[n]), wBttn);
725 
726  // remove widget from map
727  m_mapBttns[n].erase(pos);
728 
729  // redraw
730  gtk_widget_show(m_wMain);
731 
732  return true;
733 }
734 
736 {
737  MapBttns_T::iterator iter;
738  int n;
739  GtkWidget *wBttn;
740 
741  for(n=0; n<2; ++n)
742  {
743  for(iter=m_mapBttns[n].begin(); iter != m_mapBttns[n].end(); ++iter)
744  {
745  wBttn = iter->second.m_wBttn;
746 
747  //
748  // Replace any exiting button image with NULL or the image widget is hosed
749  // for reuse.
750  //
751  gtk_button_set_image(GTK_BUTTON(wBttn), NULL);
752 
753  // remove widget from gui
754  gtk_container_remove(GTK_CONTAINER(m_wBttnMenu[n]), wBttn);
755  }
756  m_mapBttns[n].clear();
757  }
758 
759  // redraw
760  gtk_widget_show(m_wMain);
761 }
762 
763 bool WinGtk::showButtonState(int nBttnId, WidgetState eBttnState)
764 {
765  MapBttns_T::iterator pos;
766 
767  if( !findBttn(nBttnId, pos) )
768  {
769  return false;
770  }
771 
772  switch( eBttnState )
773  {
774  case WidgetStateNormal:
775  gtk_widget_set_sensitive(pos->second.m_wBttn, TRUE);
776  gtk_widget_set_state(pos->second.m_wBttn, GTK_STATE_NORMAL);
777  break;
778  case WidgetStateActive:
779  gtk_widget_set_sensitive(pos->second.m_wBttn, TRUE);
780  gtk_widget_set_state(pos->second.m_wBttn, GTK_STATE_ACTIVE);
781  break;
782  case WidgetStateDisabled:
783  gtk_widget_set_sensitive(pos->second.m_wBttn, FALSE);
784  break;
785  default:
786  return false;
787  }
788 
789  gtk_widget_show_all(pos->second.m_wBttn);
790 
791  return true;
792 }
793 
795 {
796  // remove all workspace widgets - nothing else required
797  eraseWorkspace();
798 }
799 
801 {
802  GtkWidget *wAlign;
803 
804  // remove any old workspace widgets
805  eraseWorkspace();
806 
807  // new CvImage widget
808  m_wCvImage[0] = cvImageWidgetNew(CV_WINDOW_AUTOSIZE);
809 
810  // CvImage container box widget
812 
813  // center-top alignment
814  wAlign = gtk_alignment_new(0.5, 0.0, 0, 0);
815  gtk_box_pack_start(GTK_BOX(m_wWorkspace), wAlign, TRUE, TRUE, 0);
816 
817  // CvImage container box widget
818  m_wCvImageBox[0] = gtk_hbox_new(FALSE, 0);
819  gtk_container_add(GTK_CONTAINER(wAlign), m_wCvImageBox[0]);
820 
821  // initial size of widget is the size of the workspace
822  m_sizeCvImage[0] = cvSize(m_rectWorkspace.width, m_rectWorkspace.height);
823 
824  // initial origin
825  m_ptCvImageOrig[0] = cvPoint(0, 0);
826 
827  // pack at the start of the container widget
828  gtk_box_pack_start(GTK_BOX(m_wCvImageBox[0]), m_wCvImage[0], TRUE, TRUE, 0);
829 
830  // configure the CvImage widget
831  configureCvImage(0);
832 
833  // force show
834  gtk_widget_show_all(m_wWorkspace);
835 
836  return 0;
837 }
838 
839 void WinGtk::initWorkspaceAsGstWin(const Size &sizeVidWin)
840 {
841  // remove any old workspace widgets
842  eraseWorkspace();
843 
844  //---
845  // Video window
846  //---
847  m_wGstWin = gtk_drawing_area_new();
848  g_object_set(G_OBJECT(m_wGstWin),
849  "width-request", sizeVidWin.width,
850  "height-request", sizeVidWin.height,
851  NULL);
852  gtk_widget_modify_bg(m_wGstWin, GTK_STATE_NORMAL,
853  &m_mapColors["color_win_bg"]);
854  gtk_widget_modify_bg(m_wGstWin, GTK_STATE_ACTIVE,
855  &m_mapColors["color_win_bg"]);
856  gtk_widget_modify_bg(m_wGstWin, GTK_STATE_SELECTED,
857  &m_mapColors["color_win_bg"]);
858  g_signal_connect(m_wGstWin, "realize", G_CALLBACK(onRealizeGstWin), this);
859  gtk_widget_set_double_buffered(m_wGstWin, FALSE);
860  gtk_box_pack_start(GTK_BOX(m_wWorkspace), m_wGstWin, FALSE, FALSE, 0);
861 
862  //---
863  // Show
864  //---
865  showWorkspace();
866 
867  //
868  // Realize the window now so that the video window gets created and we can
869  // obtain its XID before the pipeline is started up and the videosink
870  // asks for the XID of the window to render onto.
871  //
872  gtk_widget_realize(m_wGstWin);
873 
874  if( m_uGstWinXid == 0 )
875  {
876  LOGERROR("Cannot determine xid.");
877  }
878 }
879 
880 uint_t WinGtk::addWorkspaceCvImageDisplay(void *wContainer)
881 {
882  GtkWidget *wBox = (GtkWidget *)wContainer;
883  uint_t i;
884 
885  for(i=0; i<MaxCvImages; ++i)
886  {
887  if( m_wCvImage[i] == NULL )
888  {
889  break;
890  }
891  }
892 
893  if( i >= MaxCvImages )
894  {
895  LOGERROR("No more CvImage displays available.");
896  return -1;
897  }
898 
899  // new CvImage widget
900  m_wCvImage[i] = cvImageWidgetNew(CV_WINDOW_AUTOSIZE);
901 
902  // CvImage container box widget
903  m_wCvImageBox[i] = wBox;
904 
905  // initial size of widget is unknown
906  m_sizeCvImage[i] = cvSize(0, 0);
907  m_ptCvImageOrig[i] = cvPoint(0, 0);
908 
909  // pack at the start of the container widget
910  gtk_box_pack_start(GTK_BOX(m_wCvImageBox[i]), m_wCvImage[i], TRUE, TRUE, 0);
911 
912  // configure the CvImage widget
913  configureCvImage(i);
914 
915  return i;
916 }
917 
919 {
920  // remove (and destroy) old CvImage widget
921  if( (uImgIndex < MaxCvImages) && (m_wCvImage[uImgIndex] != NULL) )
922  {
923  gtk_container_remove(GTK_CONTAINER(m_wCvImageBox[uImgIndex]),
924  m_wCvImage[uImgIndex]);
925  m_wCvImage[uImgIndex] = NULL;
926  m_wCvImageBox[uImgIndex] = NULL;
927  }
928 }
929 
931 {
932  int i;
933 
934  gtk_container_foreach(GTK_CONTAINER(m_wWorkspace),
936  m_wWorkspace);
937 
938  for(i=0; i<MaxCvImages; ++i)
939  {
940  m_wCvImage[i] = NULL;
941  m_wCvImageBox[i] = NULL;
942  }
943 }
944 
945 
946 //..............................................................................
947 // Protected Implementation
948 //..............................................................................
949 
951 {
952  GdkColor color;
953  PangoFontDescription *pFont;
954  MapLookFeel_T::iterator iter;
955 
956  for(iter=m_mapLookFeel.begin(); iter!=m_mapLookFeel.end(); ++iter)
957  {
958  if( iter->first.find("color") == 0 )
959  {
960  gdk_color_parse(iter->second.c_str(), &color);
961  m_mapColors[iter->first] = color;
962  }
963  else if( iter->first.find("font") == 0 )
964  {
965  pFont = pango_font_description_from_string(iter->second.c_str());
966  m_mapFonts[iter->first] = pFont;
967  }
968  }
969 }
970 
971 void WinGtk::configureCvImage(uint_t uImgIndex)
972 {
973  uint_t i = uImgIndex;
974 
975  gtk_widget_modify_bg(m_wCvImage[i], GTK_STATE_NORMAL,
976  &m_mapColors["color_image_bg"]);
977 
978  gtk_signal_connect(GTK_OBJECT(m_wCvImage[i]), "button-press-event",
979  GTK_SIGNAL_FUNC(WinGtk::onMouseCvImage), this);
980  gtk_signal_connect(GTK_OBJECT(m_wCvImage[i]), "button-release-event",
981  GTK_SIGNAL_FUNC(WinGtk::onMouseCvImage), this);
982  gtk_signal_connect(GTK_OBJECT(m_wCvImage[i]), "motion-notify-event",
983  GTK_SIGNAL_FUNC(WinGtk::onMouseCvImage), this);
984 
985  gtk_widget_show(m_wCvImage[i]);
986  gtk_widget_show(m_wMain);
987  gtk_widget_queue_draw(GTK_WIDGET(m_wCvImage[i]));
988 }
989 
990 void WinGtk::onRemoveWidget(GtkWidget *w, gpointer user_data)
991 {
992  GtkWidget *wContainer = (GtkWidget *)user_data;
993  gtk_container_remove(GTK_CONTAINER(wContainer), w);
994 }
995 
996 gboolean WinGtk::onAlarm(gpointer user_data)
997 {
998  *(int *)user_data = 1;
999  return FALSE;
1000 }
1001 
1002 gboolean WinGtk::onKeyPress(GtkWidget *w,
1003  GdkEventKey *event,
1004  gpointer *user_data)
1005 {
1006  WinGtk *pWin = (WinGtk *)user_data;
1007 
1008  int code = 0;
1009 
1010  switch( event->keyval )
1011  {
1012  case GDK_Escape:
1013  code = 27;
1014  break;
1015  case GDK_Return:
1016  case GDK_Linefeed:
1017  code = '\n';
1018  break;
1019  case GDK_Tab:
1020  code = '\t';
1021  break;
1022  default:
1023  code = event->keyval;
1024  break;
1025  }
1026 
1027  pWin->m_uLastKey = (code & 0xffff) | (event->state << 16);
1028 
1029  if( pWin->m_funcKeyCb )
1030  {
1031  pWin->m_funcKeyCb(code, event->state, pWin->m_dataKeyCb);
1032  }
1033 
1034  return FALSE;
1035 }
1036 
1037 gboolean WinGtk::onMouseCvImage(GtkWidget *w,
1038  GdkEventKey *event,
1039  gpointer *user_data)
1040 {
1041  WinGtk *pWin = (WinGtk *)user_data;
1042 
1043  CvPoint2D32f pt32f = {-1., -1.};
1044  CvPoint pt = {-1,-1};
1045  int cv_event = -1;
1046  int state = 0;
1047  uint_t i;
1048 
1049  if( event->type == GDK_MOTION_NOTIFY )
1050  {
1051  GdkEventMotion* event_motion = (GdkEventMotion*)event;
1052 
1053  cv_event = CV_EVENT_MOUSEMOVE;
1054  pt32f.x = cvRound(event_motion->x);
1055  pt32f.y = cvRound(event_motion->y);
1056  state = event_motion->state;
1057  }
1058 
1059  else if( event->type == GDK_BUTTON_PRESS ||
1060  event->type == GDK_BUTTON_RELEASE ||
1061  event->type == GDK_2BUTTON_PRESS )
1062  {
1063  GdkEventButton* event_button = (GdkEventButton*)event;
1064 
1065  pt32f.x = cvRound(event_button->x);
1066  pt32f.y = cvRound(event_button->y);
1067 
1068  if( event_button->type == GDK_BUTTON_PRESS )
1069  {
1070  cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONDOWN :
1071  event_button->button == 2 ? CV_EVENT_MBUTTONDOWN :
1072  event_button->button == 3 ? CV_EVENT_RBUTTONDOWN : 0;
1073  }
1074  else if( event_button->type == GDK_BUTTON_RELEASE )
1075  {
1076  cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONUP :
1077  event_button->button == 2 ? CV_EVENT_MBUTTONUP :
1078  event_button->button == 3 ? CV_EVENT_RBUTTONUP : 0;
1079  }
1080  else if( event_button->type == GDK_2BUTTON_PRESS )
1081  {
1082  cv_event = event_button->button == 1 ? CV_EVENT_LBUTTONDBLCLK :
1083  event_button->button == 2 ? CV_EVENT_MBUTTONDBLCLK :
1084  event_button->button == 3 ? CV_EVENT_RBUTTONDBLCLK : 0;
1085  }
1086 
1087  state = event_button->state;
1088  }
1089 
1090  if( cv_event >= 0 )
1091  {
1092  pt = cvPointFrom32f(pt32f);
1093 
1094  //dbgpoint("mouse", pt);
1095 
1096  int flags = (state & GDK_SHIFT_MASK ? CV_EVENT_FLAG_SHIFTKEY : 0) |
1097  (state & GDK_CONTROL_MASK ? CV_EVENT_FLAG_CTRLKEY : 0) |
1098  (state & (GDK_MOD1_MASK|GDK_MOD2_MASK) ? CV_EVENT_FLAG_ALTKEY : 0) |
1099  (state & GDK_BUTTON1_MASK ? CV_EVENT_FLAG_LBUTTON : 0) |
1100  (state & GDK_BUTTON2_MASK ? CV_EVENT_FLAG_MBUTTON : 0) |
1101  (state & GDK_BUTTON3_MASK ? CV_EVENT_FLAG_RBUTTON : 0);
1102 
1103  for(i=0; i<MaxCvImages; ++i)
1104  {
1105  if( (pWin->m_wCvImage[i] == NULL) || (pWin->m_funcMouseCb[i] == NULL) )
1106  {
1107  continue;
1108  }
1109 
1110  //pt.x -= pWin->m_ptCvImageOrig[i].x;
1111  //pt.y -= pWin->m_ptCvImageOrig[i].y;
1112 
1113  if( (pt.x >= 0) && (pt.x < pWin->m_sizeCvImage[i].width) ||
1114  (pt.y >= 0) && (pt.y < pWin->m_sizeCvImage[i].height) )
1115  {
1116  pWin->m_bMouseEvent = true;
1117  pWin->m_funcMouseCb[i](cv_event, pt.x, pt.y, flags,
1118  pWin->m_dataMouseCb[i]);
1119  break;
1120  }
1121  }
1122  }
1123 
1124  return FALSE;
1125 }
1126 
1127 void WinGtk::onButtonClick(GtkWidget *w, gpointer *user_data)
1128 {
1129  WinGtk::BttnInfo_T *pInfo = (WinGtk::BttnInfo_T *)user_data;
1130 
1131  if( pInfo->m_pWin->m_funcBttnCb != NULL )
1132  {
1133  pInfo->m_pWin->m_bMouseEvent = true;
1134  pInfo->m_pWin->m_funcBttnCb(pInfo->m_nBttnId, pInfo->m_pWin->m_dataBttnCb);
1135  }
1136 }
1137 
1138 void WinGtk::onRealizeGstWin(GtkWidget *w, gpointer user_data)
1139 {
1140  WinGtk *pWin = (WinGtk *)user_data;
1141 
1142 #if GTK_CHECK_VERSION(2,18,0)
1143  //
1144  // I copied this code. Kept it for meta-pedagogical reasons.
1145  //
1146  // This is here just for pedagogical purposes, GDK_WINDOW_XID will call
1147  // it as well in newer Gtk versions.
1148  //
1149  if( !gdk_window_ensure_native(w->window) )
1150  {
1151  LOGERROR("Couldn't create native window needed for GstXOverlay!");
1152  }
1153 #endif
1154 
1155 #ifdef GDK_WINDOWING_X11
1156  pWin->m_uGstWinXid = GDK_WINDOW_XID(gtk_widget_get_window(pWin->m_wGstWin));
1157 #endif
1158 }
1159 
1160 
1161 //.............................................................................
1162 // Simple Functions
1163 //.............................................................................
1164 
1165 #if 0 // TODO
1166 
1167 /*!
1168  * Create GTK window with minumum decorations.
1169  *
1170  * \param sWinName Window name (and id).
1171  * \param width Window width in pixels.
1172  * \param height Window height in pixels.
1173  */
1174 void rnr::WinCreate(const char *sWinName, int width, int height)
1175 {
1176  // use openCV to create and size window
1177  cvNamedWindow(sWinName, 0);
1178  cvResizeWindow(sWinName, width, height);
1179 
1180  // now go to the native gtk space for fine tuning and operatiion
1181 
1182  GtkWidget *widgetCv = (GtkWidget *)cvGetWindowHandle(sWinName);
1183  GtkWindow *windowCv = GTK_WINDOW(gtk_widget_get_toplevel(widgetCv));
1184 
1185  // kill title bar, resize controls, exit control, menus, etc.
1186  gtk_window_set_decorated(windowCv, false);
1187 }
1188 #endif // TODO
static gboolean onKeyPress(GtkWidget *w, GdkEventKey *event, gpointer *user_data)
Keyboard press event callback handler.
Definition: WinGtk.cxx:1002
GtkWidget * m_wBttn
button widget
Definition: WinGtk.h:522
WidgetState
Definition: Win.h:129
static const int MaxCvImages
max workspace images/video
Definition: Win.h:214
GtkWidget * m_wCvImage[MaxCvImages]
CvImage widgets.
Definition: WinGtk.h:544
GtkWidget * m_wGstWin
GstWin container widget.
Definition: WinGtk.h:546
GtkWidget * m_wBttnMenu[NumOfButtonMenus]
left menu container widget
Definition: WinGtk.h:534
virtual void initWorkspaceAsGtk()
Initialize window&#39;s workspace to hold a GTK widget tree.
Definition: WinGtk.cxx:794
GtkWindow * m_wWindowMain
main widnow widget
Definition: WinGtk.h:532
virtual bool removeButton(int nBttnId)
Remove a button from a menu.
Definition: WinGtk.cxx:696
virtual void initWorkspaceAsGstWin(const cv::Size &sizeVidWin)
Initialize the workspace as a window display to show GStreamer video/images.
Definition: WinGtk.cxx:839
virtual void setLookAndFeel(const std::string &strKey, const std::string &strVal)
Set GUI look and feel value.
Definition: Win.h:278
rigth alignment
Definition: Win.h:86
virtual void showPageRef(int nPageId)
Show page reference number.
Definition: WinGtk.cxx:357
MouseCbFunc_T m_funcMouseCb[MaxCvImages]
registered mouse cb func
Definition: Win.h:662
virtual void showCvImage(cv::Mat &img, uint_t uImgIndex=0)
Show a OpenCV image on the workspace.
Definition: WinGtk.cxx:331
CvSize m_sizeCvImage[MaxCvImages]
size of shown CvImage
Definition: WinGtk.h:547
int m_nBttnId
unique button id
Definition: WinGtk.h:521
RoadNarrows Robotics GTK derived WinGtk window class interface.
virtual void removeAllButtons()
Remove all buttons from all menus.
Definition: WinGtk.cxx:735
virtual bool replaceButtonLabel(int nBttnId, const std::string &strLabel, const std::string &strToolTip="")
Replace existing button label with new label.
Definition: WinGtk.cxx:670
RoadNarrows Robotics Win abstract base class interface.
bool findBttn(int nBttnId, MapBttns_T::iterator &pos)
Find button.
Definition: WinGtk.h:578
virtual void waitMouse(int delay)
Wait for timeout or registered mouse event.
Definition: WinGtk.cxx:440
void * m_dataMouseCb[MaxCvImages]
registered mouse cb data
Definition: Win.h:663
std::string m_strWinName
window name (and title)
Definition: Win.h:654
virtual void showWorkspace()
Show/refresh all gui widgets in workspace.
Definition: WinGtk.h:447
static gboolean onAlarm(gpointer user_data)
Timeout expiry callback handler.
Definition: WinGtk.cxx:996
virtual bool replaceButtonImage(int nBttnId, const std::string &strIconPath, const std::string &strToolTip="")
Replace existing button image with new image.
uint_t m_uLastKey
last pressed keyboard code
Definition: Win.h:660
virtual uint_t addWorkspaceCvImageDisplay(void *wContainer)
Add an OpenCV display widget to the container widget.
Definition: WinGtk.cxx:880
left alignment
Definition: Win.h:84
MapPangoFont_T m_mapFonts
look and feel font map
Definition: WinGtk.h:556
virtual uint_t initWorkspaceAsCvImage()
Initialize the workspace as a display to show OpenCV images.
Definition: WinGtk.cxx:800
virtual bool addButton(int nBttnId, AlignOp eAlign, GtkWidget *wBttn)
Add a GTK button widget to window button menu.
Definition: WinGtk.cxx:568
KeyCbFunc_T m_funcKeyCb
registered keyboard callback func
Definition: Win.h:664
AlignOp
Definition: Win.h:81
WinGtk window derived class.
Definition: WinGtk.h:89
virtual ~WinGtk()
Destructor.
Definition: WinGtk.cxx:263
static gboolean onMouseCvImage(GtkWidget *w, GdkEventKey *event, gpointer *user_data)
Mouse event on OpenCV Image widget workspace callback handler.
Definition: WinGtk.cxx:1037
RoadNarrows top-level look and feel user interface declarations.
GtkWidget * m_wContainer
top container widget (hbox)
Definition: WinGtk.h:533
virtual bool showButtonState(int nBttnId, WidgetState eBttnState)
Show a button&#39;s widget state.
Definition: WinGtk.cxx:763
normal - enabled but not selected
Definition: Win.h:131
virtual void eraseWorkspace()
Remove all widgets contained in the window&#39;s workspace container.
Definition: WinGtk.cxx:930
GtkWidget * m_wMain
main widget
Definition: WinGtk.h:531
MapBttns_T m_mapBttns[NumOfButtonMenus]
left/right map of menu buttons.
Definition: WinGtk.h:551
GtkWidget * m_wStatusFrame
holds page reference and status bar
Definition: WinGtk.h:539
ulong_t m_uGstWinXid
GstWin container X window id.
Definition: Win.h:659
void * m_dataKeyCb
registered keyboard callback data
Definition: Win.h:665
int m_nWinHeight
window height
Definition: Win.h:656
static void onRealizeGstWin(GtkWidget *w, gpointer user_data)
Realize GStreamer video window callback.
Definition: WinGtk.cxx:1138
static void onButtonClick(GtkWidget *w, gpointer *user_data)
Button press event handler.
Definition: WinGtk.cxx:1127
BttnCbFunc_T m_funcBttnCb
registered menu button callback func
Definition: Win.h:666
static const int NumOfButtonMenus
left and right menus
Definition: Win.h:215
RNR Win window abstract base class.
Definition: Win.h:211
MapGdkColor_T m_mapColors
look and feel color map
Definition: WinGtk.h:555
virtual void setLookAndFeel(const std::string &strKey, const std::string &strVal)
Set GUI look and feel value.
Definition: WinGtk.cxx:276
int getBttnMenuIdx(AlignOp eAlign)
Get button menu index from alignment enum.
Definition: WinGtk.h:565
MapLookFeel_T m_mapLookFeel
look and feel map
Definition: Win.h:668
GtkWidget * m_wCvImageBox[MaxCvImages]
CvImage box containers.
Definition: WinGtk.h:545
static void onRemoveWidget(GtkWidget *w, gpointer user_data)
Remove widget callback handler.
Definition: WinGtk.cxx:990
selected
Definition: Win.h:132
WinGtk * m_pWin
this
Definition: WinGtk.h:523
virtual bool addLabelButton(int nBttnId, AlignOp eAlign, const std::string &strLabel, const std::string &strToolTip="")
Add a button with a label to window button menu.
Definition: WinGtk.cxx:539
virtual bool addImageButton(int nBttnId, AlignOp eAlign, const std::string &strIconPath, const std::string &strAltText, const std::string &strToolTip="")
Add a button with an image to window button menu.
virtual void clearStatus()
Clear status message.
Definition: WinGtk.cxx:396
virtual void wait(int delay)
Wait for timeout.
Definition: WinGtk.cxx:464
GtkWidget * m_wWorkspace
middle workspace container widget
Definition: WinGtk.h:536
void convertLookAndFeelDefaults()
Convert Look and Feel defaults to native GTK/GDK values.
Definition: WinGtk.cxx:950
GtkWidget * m_wPageRef
workflow page reference
Definition: WinGtk.h:540
bool m_bMouseEvent
was a mouse event (click, drag, etc)
Definition: Win.h:661
int m_nWinWidth
window width
Definition: Win.h:655
void * m_dataBttnCb
registered menu button callback data
Definition: Win.h:667
RoadNarrows Robotics.
Definition: Camera.h:74
virtual void configureCvImage(uint_t uImgIndex)
Configure OpenCV image widget.
Definition: WinGtk.cxx:971
CvRect m_rectWorkspace
workspace bounding rectangle
Definition: Win.h:658
virtual int waitKey(int delay)
Wait for keypress or timeout.
Definition: WinGtk.cxx:402
CvPoint m_ptCvImageOrig[MaxCvImages]
origin of shown CvImage
Definition: WinGtk.h:548
virtual void removeWorkspaceCvImageDisplay(uint_t uImgIndex)
Remove OpenCV display widget from workspace.
Definition: WinGtk.cxx:918
GtkWidget * m_wStatusBar
status message bar
Definition: WinGtk.h:541
virtual void showStatus(const char *sFmt,...)
Show status message.
Definition: WinGtk.cxx:378
GtkWidget * m_wExtraVBox
extra vertical box
Definition: WinGtk.h:537