You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TXCheckbox.h 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This software is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. //
  19. // TXCheckbox.h
  20. //
  21. // A TXCheckbox has a box which may be "checked" with some text next to it.
  22. // The checkbox window must be big enough to contain the text - if not then it
  23. // will be resized appropriately.
  24. //
  25. // There are two styles of checkbox: the normal style which uses a tick in a
  26. // square box, and the radio style which uses a dot inside a circle. The
  27. // default behaviour when clicking on the checkbox is to toggle it on or off,
  28. // but this behaviour can be changed by the callback object. In particular to
  29. // get radiobutton behaviour, the callback must ensure that only one of a set
  30. // of radiobuttons is selected.
  31. //
  32. #ifndef __TXCHECKBOX_H__
  33. #define __TXCHECKBOX_H__
  34. #include "TXWindow.h"
  35. #include <rfb/util.h>
  36. // TXCheckboxCallback's checkboxSelect() method is called when the state of a
  37. // checkbox changes.
  38. class TXCheckbox;
  39. class TXCheckboxCallback {
  40. public:
  41. virtual void checkboxSelect(TXCheckbox* checkbox)=0;
  42. };
  43. class TXCheckbox : public TXWindow, public TXEventHandler {
  44. public:
  45. TXCheckbox(Display* dpy_, const char* text_, TXCheckboxCallback* cb_,
  46. bool radio_=false, TXWindow* parent_=0, int w=1, int h=1)
  47. : TXWindow(dpy_, w, h, parent_), cb(cb_), text(0),
  48. boxSize(radio_ ? 12 : 13), boxPad(4),
  49. checked_(false), disabled_(false), radio(radio_)
  50. {
  51. setEventHandler(this);
  52. setText(text_);
  53. gc = XCreateGC(dpy, win(), 0, 0);
  54. XSetFont(dpy, gc, defaultFont);
  55. addEventMask(ExposureMask| ButtonPressMask | ButtonReleaseMask);
  56. }
  57. virtual ~TXCheckbox() {
  58. XFreeGC(dpy, gc);
  59. if (text) free(text);
  60. }
  61. // setText() changes the text in the checkbox.
  62. void setText(const char* text_) {
  63. if (text) free(text);
  64. text = strdup((char*)text_);
  65. int textWidth = XTextWidth(defaultFS, text, strlen(text));
  66. int textHeight = (defaultFS->ascent + defaultFS->descent);
  67. int newWidth = __rfbmax(width(), textWidth + xPad*2 + boxPad*2 + boxSize);
  68. int newHeight = __rfbmax(height(), textHeight + yPad*2);
  69. if (width() < newWidth || height() < newHeight) {
  70. resize(newWidth, newHeight);
  71. }
  72. }
  73. // checked() sets or queries the state of the checkbox
  74. void checked(bool b) { checked_ = b; paint(); }
  75. bool checked() { return checked_; }
  76. // disabled() sets or queries the disabled state of the checkbox. A disabled
  77. // checkbox cannot be changed via the user interface.
  78. void disabled(bool b) { disabled_ = b; paint(); }
  79. bool disabled() { return disabled_; }
  80. private:
  81. void paint() {
  82. if (disabled_)
  83. drawBevel(gc, xPad + boxPad, (height() - boxSize) / 2, boxSize, boxSize,
  84. bevel, disabledBg, darkBg, lightBg, radio);
  85. else
  86. drawBevel(gc, xPad + boxPad, (height() - boxSize) / 2, boxSize, boxSize,
  87. bevel, enabledBg, darkBg, lightBg, radio);
  88. XSetBackground(dpy, gc, disabled_ ? disabledBg : enabledBg);
  89. XSetForeground(dpy, gc, disabled_ ? disabledFg : defaultFg);
  90. if (checked_) {
  91. Pixmap icon = radio ? dot : tick;
  92. int iconSize = radio ? dotSize : tickSize;
  93. XCopyPlane(dpy, icon, win(), gc, 0, 0, iconSize, iconSize,
  94. xPad + boxPad + (boxSize - iconSize) / 2,
  95. (height() - iconSize) / 2, 1);
  96. }
  97. XDrawString(dpy, win(), gc, xPad + boxSize + boxPad*2,
  98. (height() + defaultFS->ascent - defaultFS->descent) / 2,
  99. text, strlen(text));
  100. }
  101. virtual void handleEvent(TXWindow* /*w*/, XEvent* ev) {
  102. switch (ev->type) {
  103. case Expose:
  104. paint();
  105. break;
  106. case ButtonPress:
  107. break;
  108. case ButtonRelease:
  109. if (ev->xbutton.x >= 0 && ev->xbutton.x < width() &&
  110. ev->xbutton.y >= 0 && ev->xbutton.y < height()) {
  111. if (!disabled_) {
  112. checked_ = !checked_;
  113. if (cb) cb->checkboxSelect(this);
  114. paint();
  115. }
  116. }
  117. break;
  118. }
  119. }
  120. TXCheckboxCallback* cb;
  121. GC gc;
  122. char* text;
  123. int boxSize;
  124. int boxPad;
  125. bool checked_;
  126. bool disabled_;
  127. bool radio;
  128. };
  129. #endif