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.

TXLabel.h 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. // TXLabel.h
  20. //
  21. // An TXLabel allows you to put up multiline text in a window with various
  22. // alignments. The label must be big enough to contain the text - if not then
  23. // it will be resized appropriately.
  24. //
  25. #ifndef __TXLABEL_H__
  26. #define __TXLABEL_H__
  27. #include <stdlib.h>
  28. #include "TXWindow.h"
  29. #include <rfb/util.h>
  30. class TXLabel : public TXWindow, public TXEventHandler {
  31. public:
  32. enum HAlign { left, centre, right };
  33. enum VAlign { top, middle, bottom };
  34. TXLabel(Display* dpy_, const char* text_, TXWindow* parent_=0,
  35. int w=1, int h=1, HAlign ha=centre, VAlign va=middle)
  36. : TXWindow(dpy_, w, h, parent_), lineSpacing(2), lines(0),
  37. halign(ha), valign(va)
  38. {
  39. setEventHandler(this);
  40. setText(text_);
  41. addEventMask(ExposureMask);
  42. }
  43. // setText() changes the text in the label.
  44. void setText(const char* text_) {
  45. text = text_;
  46. lines = 0;
  47. size_t lineStart = 0;
  48. int textWidth = 0;
  49. size_t i = -1;
  50. do {
  51. i++;
  52. if (i >= text.size() || text[i] == '\n') {
  53. int tw = XTextWidth(defaultFS, &text[lineStart], i-lineStart);
  54. if (tw > textWidth) textWidth = tw;
  55. lineStart = i+1;
  56. lines++;
  57. }
  58. } while (i < text.size());
  59. int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
  60. * lines);
  61. int newWidth = __rfbmax(width(), textWidth + xPad*2);
  62. int newHeight = __rfbmax(height(), textHeight + yPad*2);
  63. if (width() < newWidth || height() < newHeight) {
  64. resize(newWidth, newHeight);
  65. }
  66. invalidate();
  67. }
  68. private:
  69. int xOffset(int textWidth) {
  70. switch (halign) {
  71. case left: return xPad;
  72. case right: return width() - xPad - textWidth;
  73. default: return (width() - textWidth) / 2;
  74. }
  75. }
  76. int yOffset(int lineNum) {
  77. int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
  78. * lines);
  79. int lineOffset = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
  80. * lineNum + defaultFS->ascent);
  81. switch (valign) {
  82. case top: return yPad + lineOffset;
  83. case bottom: return height() - yPad - textHeight + lineOffset;
  84. default: return (height() - textHeight) / 2 + lineOffset;
  85. }
  86. }
  87. void paint() {
  88. size_t lineNum = 0;
  89. size_t lineStart = 0;
  90. size_t i = -1;
  91. do {
  92. i++;
  93. if (i >= text.size() || text[i] == '\n') {
  94. int tw = XTextWidth(defaultFS, &text[lineStart], i-lineStart);
  95. XDrawString(dpy, win(), defaultGC, xOffset(tw), yOffset(lineNum),
  96. &text[lineStart], i-lineStart);
  97. lineStart = i+1;
  98. lineNum++;
  99. }
  100. } while (i < text.size());
  101. }
  102. virtual void handleEvent(TXWindow* /*w*/, XEvent* ev) {
  103. switch (ev->type) {
  104. case Expose:
  105. paint();
  106. break;
  107. }
  108. }
  109. int lineSpacing;
  110. std::string text;
  111. int lines;
  112. HAlign halign;
  113. VAlign valign;
  114. };
  115. #endif