xref: /haiku/src/apps/cortex/TipManager/TipView.cpp (revision 19ae20e67e91fc09cc9fc5c0e60e21e24e7a53eb)
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