xref: /haiku/src/apps/cortex/TipManager/TipView.cpp (revision 3cb015b1ee509d69c643506e8ff573808c86dcfc)
1 // TipView.cpp
2 
3 #include "TipView.h"
4 
5 #include <Debug.h>
6 #include <Window.h>
7 #include <cmath>
8 #include <cstring>
9 
10 using namespace std;
11 
12 __USE_CORTEX_NAMESPACE
13 
14 // -------------------------------------------------------- //
15 // constants
16 // -------------------------------------------------------- //
17 
18 const float TipView::s_xPad = 5.0;
19 const float TipView::s_yPad = 2.0;
20 
21 // -------------------------------------------------------- //
22 // *** dtor/ctors
23 // -------------------------------------------------------- //
24 
25 TipView::~TipView() {}
26 TipView::TipView() :
27 	BView(
28 		BRect(0,0,0,0),
29 		"TipView",
30 		B_FOLLOW_NONE,
31 		B_WILL_DRAW|B_FRAME_EVENTS),
32 	m_font(be_plain_font) {
33 
34 	_initColors();
35 	_initFont();
36 }
37 
38 // -------------------------------------------------------- //
39 // *** operations
40 // -------------------------------------------------------- //
41 
42 void TipView::setText(
43 	const char*							text) {
44 
45 	_setText(text);
46 }
47 
48 // -------------------------------------------------------- //
49 // *** BView
50 // -------------------------------------------------------- //
51 
52 // Adapted from c.lenz' ToolTipView::Draw()
53 void TipView::Draw(
54 	BRect										updateRect) {
55 
56 	BRect r = Bounds();
57 
58 	// Draw border and fill
59 	SetDrawingMode(B_OP_ALPHA);
60 	SetHighColor(m_borderLoColor);
61 	StrokeLine(r.LeftBottom(), r.RightBottom());
62 	StrokeLine(r.RightTop(), r.RightBottom());
63 	SetHighColor(m_borderHiColor);
64 	StrokeLine(r.LeftTop(), r.RightTop());
65 	StrokeLine(r.LeftTop(), r.LeftBottom());
66 	SetHighColor(m_viewColor);
67 	SetDrawingMode(B_OP_ALPHA);
68 	r.InsetBy(1.0, 1.0);
69 	FillRect(r);
70 
71 	// Draw text
72 	SetDrawingMode(B_OP_OVER);
73 	SetHighColor(m_textColor);
74 
75 	BPoint p = m_offset;
76 	for(uint32 n = 0; n < m_lineSet.size(); ++n) {
77 
78 		uint32 from = m_lineSet[n];
79 		uint32 to = (n < m_lineSet.size()-1) ? m_lineSet[n+1]-1 :
80 			m_text.Length();
81 
82 		if(to > from)
83 			DrawString(
84 				m_text.String() + from,
85 				to - from,
86 				p);
87 
88 		p.y += (m_fontHeight.ascent + m_fontHeight.descent + m_fontHeight.leading);
89 	}
90 }
91 
92 void TipView::FrameResized(
93 	float										width,
94 	float										height) {
95 
96 	_inherited::FrameResized(width, height);
97 	_updateLayout(width, height);
98 	Invalidate();
99 }
100 
101 void TipView::GetPreferredSize(
102 	float*									outWidth,
103 	float*									outHeight) {
104 
105 //	*outWidth = ceil(m_font.StringWidth(m_text.String()) + s_xPad*2);
106 	*outWidth = ceil(_maxTextWidth() + s_xPad*2);
107 	*outHeight = ceil(_textHeight() + s_yPad*2);
108 }
109 
110 // -------------------------------------------------------- //
111 // implementation
112 // -------------------------------------------------------- //
113 
114 void _make_color(
115 	rgb_color*							outColor,
116 	uint8										red,
117 	uint8										green,
118 	uint8										blue,
119 	uint8										alpha=255);
120 void _make_color(
121 	rgb_color*							outColor,
122 	uint8										red,
123 	uint8										green,
124 	uint8										blue,
125 	uint8										alpha) {
126 	outColor->red = red;
127 	outColor->green = green;
128 	outColor->blue = blue;
129 	outColor->alpha = alpha;
130 }
131 
132 void TipView::_initColors() {
133 
134 	SetViewColor(B_TRANSPARENT_COLOR);
135 
136 	_make_color(&m_textColor, 0, 0, 0, 255);
137 	_make_color(&m_borderHiColor, 0, 0, 0, 255 /*196*/);
138 	_make_color(&m_borderLoColor, 0, 0, 0, 255 /*196*/);
139 	_make_color(&m_viewColor, 255, 255, 240, 255 /*216*/);
140 }
141 
142 void TipView::_initFont() {
143 
144 	SetFont(&m_font);
145 	m_font.GetHeight(&m_fontHeight);
146 }
147 
148 void TipView::_updateLayout(
149 	float										width,
150 	float										height) {
151 
152 	// center text
153 	m_offset.x = (width - _maxTextWidth()) / 2;
154 
155 	m_offset.y = (height - _textHeight()) / 2;
156 	m_offset.y += m_fontHeight.ascent;
157 }
158 
159 void TipView::_setText(
160 	const char*							text) {
161 
162 	ASSERT(text);
163 
164 	m_lineSet.clear();
165 	m_text = text;
166 
167 	// skip leading newlines
168 	int32 n = 0;
169 	while(n < m_text.Length() && m_text[n] == '\n')
170 		++n;
171 
172 	// mark first line
173 	m_lineSet.push_back(n);
174 
175 	// break following lines
176 	while(n < m_text.Length()) {
177 		int32 nextBreak = m_text.FindFirst('\n', n);
178 		// no more line breaks?
179 		if(nextBreak < n)
180 			break;
181 		n = nextBreak + 1;
182 		m_lineSet.push_back(n);
183 	}
184 }
185 
186 float TipView::_maxTextWidth() {
187 	float max = 0.0;
188 	for(uint32 n = 0; n < m_lineSet.size(); ++n) {
189 		uint32 from = m_lineSet[n];
190 		uint32 to = (n < m_lineSet.size()-1) ? m_lineSet[n+1]-1 :
191 			m_text.Length();
192 		float lineWidth = m_font.StringWidth(
193 			m_text.String() + from,
194 			to - from);
195 		if(lineWidth > max)
196 			max = lineWidth;
197 	}
198 	return max;
199 }
200 
201 float TipView::_textHeight() {
202 	float height = m_fontHeight.ascent + m_fontHeight.descent;
203 	if(m_lineSet.size() > 1)
204 		height += (m_lineSet.size()-1) *
205 			(m_fontHeight.ascent + m_fontHeight.descent + m_fontHeight.leading);
206 
207 	return height;
208 }
209 
210 // END -- TipView.cpp --
211