1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31
32 // TipView.cpp
33
34 #include "TipView.h"
35
36 #include <Debug.h>
37 #include <Window.h>
38 #include <cmath>
39 #include <cstring>
40
41 using namespace std;
42
43 __USE_CORTEX_NAMESPACE
44
45 // -------------------------------------------------------- //
46 // constants
47 // -------------------------------------------------------- //
48
49 const float TipView::s_xPad = 5.0;
50 const float TipView::s_yPad = 2.0;
51
52 // -------------------------------------------------------- //
53 // *** dtor/ctors
54 // -------------------------------------------------------- //
55
~TipView()56 TipView::~TipView() {}
TipView()57 TipView::TipView() :
58 BView(
59 BRect(0,0,0,0),
60 "TipView",
61 B_FOLLOW_NONE,
62 B_WILL_DRAW|B_FRAME_EVENTS),
63 m_font(be_plain_font) {
64
65 _initColors();
66 _initFont();
67 }
68
69 // -------------------------------------------------------- //
70 // *** operations
71 // -------------------------------------------------------- //
72
setText(const char * text)73 void TipView::setText(
74 const char* text) {
75
76 _setText(text);
77 }
78
79 // -------------------------------------------------------- //
80 // *** BView
81 // -------------------------------------------------------- //
82
83 // Adapted from c.lenz' ToolTipView::Draw()
Draw(BRect updateRect)84 void TipView::Draw(
85 BRect updateRect) {
86
87 BRect r = Bounds();
88
89 // Draw border and fill
90 SetDrawingMode(B_OP_ALPHA);
91 SetHighColor(m_borderLoColor);
92 StrokeLine(r.LeftBottom(), r.RightBottom());
93 StrokeLine(r.RightTop(), r.RightBottom());
94 SetHighColor(m_borderHiColor);
95 StrokeLine(r.LeftTop(), r.RightTop());
96 StrokeLine(r.LeftTop(), r.LeftBottom());
97 SetHighColor(m_viewColor);
98 SetDrawingMode(B_OP_ALPHA);
99 r.InsetBy(1.0, 1.0);
100 FillRect(r);
101
102 // Draw text
103 SetDrawingMode(B_OP_OVER);
104 SetHighColor(m_textColor);
105
106 BPoint p = m_offset;
107 for(uint32 n = 0; n < m_lineSet.size(); ++n) {
108
109 uint32 from = m_lineSet[n];
110 uint32 to = (n < m_lineSet.size()-1) ? m_lineSet[n+1]-1 :
111 m_text.Length();
112
113 if(to > from)
114 DrawString(
115 m_text.String() + from,
116 to - from,
117 p);
118
119 p.y += (m_fontHeight.ascent + m_fontHeight.descent + m_fontHeight.leading);
120 }
121 }
122
FrameResized(float width,float height)123 void TipView::FrameResized(
124 float width,
125 float height) {
126
127 _inherited::FrameResized(width, height);
128 _updateLayout(width, height);
129 Invalidate();
130 }
131
GetPreferredSize(float * outWidth,float * outHeight)132 void TipView::GetPreferredSize(
133 float* outWidth,
134 float* outHeight) {
135
136 // *outWidth = ceil(m_font.StringWidth(m_text.String()) + s_xPad*2);
137 *outWidth = ceil(_maxTextWidth() + s_xPad*2);
138 *outHeight = ceil(_textHeight() + s_yPad*2);
139 }
140
141 // -------------------------------------------------------- //
142 // implementation
143 // -------------------------------------------------------- //
144
145 void _make_color(
146 rgb_color* outColor,
147 uint8 red,
148 uint8 green,
149 uint8 blue,
150 uint8 alpha=255);
_make_color(rgb_color * outColor,uint8 red,uint8 green,uint8 blue,uint8 alpha)151 void _make_color(
152 rgb_color* outColor,
153 uint8 red,
154 uint8 green,
155 uint8 blue,
156 uint8 alpha) {
157 outColor->red = red;
158 outColor->green = green;
159 outColor->blue = blue;
160 outColor->alpha = alpha;
161 }
162
_initColors()163 void TipView::_initColors() {
164
165 SetViewColor(B_TRANSPARENT_COLOR);
166
167 _make_color(&m_textColor, 0, 0, 0, 255);
168 _make_color(&m_borderHiColor, 0, 0, 0, 255 /*196*/);
169 _make_color(&m_borderLoColor, 0, 0, 0, 255 /*196*/);
170 _make_color(&m_viewColor, 255, 255, 240, 255 /*216*/);
171 }
172
_initFont()173 void TipView::_initFont() {
174
175 SetFont(&m_font);
176 m_font.GetHeight(&m_fontHeight);
177 }
178
_updateLayout(float width,float height)179 void TipView::_updateLayout(
180 float width,
181 float height) {
182
183 // center text
184 m_offset.x = (width - _maxTextWidth()) / 2;
185
186 m_offset.y = (height - _textHeight()) / 2;
187 m_offset.y += m_fontHeight.ascent;
188 }
189
_setText(const char * text)190 void TipView::_setText(
191 const char* text) {
192
193 ASSERT(text);
194
195 m_lineSet.clear();
196 m_text = text;
197
198 // skip leading newlines
199 int32 n = 0;
200 while(n < m_text.Length() && m_text[n] == '\n')
201 ++n;
202
203 // mark first line
204 m_lineSet.push_back(n);
205
206 // break following lines
207 while(n < m_text.Length()) {
208 int32 nextBreak = m_text.FindFirst('\n', n);
209 // no more line breaks?
210 if(nextBreak < n)
211 break;
212 n = nextBreak + 1;
213 m_lineSet.push_back(n);
214 }
215 }
216
_maxTextWidth()217 float TipView::_maxTextWidth() {
218 float max = 0.0;
219 for(uint32 n = 0; n < m_lineSet.size(); ++n) {
220 uint32 from = m_lineSet[n];
221 uint32 to = (n < m_lineSet.size()-1) ? m_lineSet[n+1]-1 :
222 m_text.Length();
223 float lineWidth = m_font.StringWidth(
224 m_text.String() + from,
225 to - from);
226 if(lineWidth > max)
227 max = lineWidth;
228 }
229 return max;
230 }
231
_textHeight()232 float TipView::_textHeight() {
233 float height = m_fontHeight.ascent + m_fontHeight.descent;
234 if(m_lineSet.size() > 1)
235 height += (m_lineSet.size()-1) *
236 (m_fontHeight.ascent + m_fontHeight.descent + m_fontHeight.leading);
237
238 return height;
239 }
240
241 // END -- TipView.cpp --
242