blob: 3d5200d6748c6894490838ba100df33182b0c8c0 [file] [log] [blame]
Constantin Kaplinskyb30ae7f2006-05-25 05:04:46 +00001/* 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
26#ifndef __TXLABEL_H__
27#define __TXLABEL_H__
28
29#include <stdlib.h>
30#include "TXWindow.h"
31#include <rfb/util.h>
32
33class TXLabel : public TXWindow, public TXEventHandler {
34public:
35 enum HAlign { left, centre, right };
36 enum VAlign { top, middle, bottom };
37
38 TXLabel(Display* dpy_, const char* text_, TXWindow* parent_=0,
39 int w=1, int h=1, HAlign ha=centre, VAlign va=middle)
40 : TXWindow(dpy_, w, h, parent_), lineSpacing(2), lines(0),
41 halign(ha), valign(va)
42 {
43 setEventHandler(this);
44 setText(text_);
45 addEventMask(ExposureMask);
46 }
47
48 // setText() changes the text in the label.
49 void setText(const char* text_) {
Adam Tkacd36b6262009-09-04 10:57:20 +000050 text.buf = rfb::strDup(text_);
Constantin Kaplinskyb30ae7f2006-05-25 05:04:46 +000051 lines = 0;
52 int lineStart = 0;
53 int textWidth = 0;
54 int i = -1;
55 do {
56 i++;
57 if (text.buf[i] == '\n' || text.buf[i] == 0) {
58 int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart);
59 if (tw > textWidth) textWidth = tw;
60 lineStart = i+1;
61 lines++;
62 }
63 } while (text.buf[i] != 0);
64 int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
65 * lines);
66 int newWidth = __rfbmax(width(), textWidth + xPad*2);
67 int newHeight = __rfbmax(height(), textHeight + yPad*2);
68 if (width() < newWidth || height() < newHeight) {
69 resize(newWidth, newHeight);
70 }
71 invalidate();
72 }
73
74private:
75 int xOffset(int textWidth) {
76 switch (halign) {
77 case left: return xPad;
78 case right: return width() - xPad - textWidth;
79 default: return (width() - textWidth) / 2;
80 }
81 }
82
83 int yOffset(int lineNum) {
84 int textHeight = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
85 * lines);
86 int lineOffset = ((defaultFS->ascent + defaultFS->descent + lineSpacing)
87 * lineNum + defaultFS->ascent);
88 switch (valign) {
89 case top: return yPad + lineOffset;
90 case bottom: return height() - yPad - textHeight + lineOffset;
91 default: return (height() - textHeight) / 2 + lineOffset;
92 }
93 }
94
95 void paint() {
96 int lineNum = 0;
97 int lineStart = 0;
98 int i = -1;
99 do {
100 i++;
101 if (text.buf[i] == '\n' || text.buf[i] == 0) {
102 int tw = XTextWidth(defaultFS, &text.buf[lineStart], i-lineStart);
103 XDrawString(dpy, win(), defaultGC, xOffset(tw), yOffset(lineNum),
104 &text.buf[lineStart], i-lineStart);
105 lineStart = i+1;
106 lineNum++;
107 }
108 } while (text.buf[i] != 0);
109 }
110
111 virtual void handleEvent(TXWindow* w, XEvent* ev) {
112 switch (ev->type) {
113 case Expose:
114 paint();
115 break;
116 }
117 }
118
119 int lineSpacing;
120 rfb::CharArray text;
121 int lines;
122 HAlign halign;
123 VAlign valign;
124};
125
126#endif