vfs: check userland buffers before reading them.
[haiku.git] / src / apps / cortex / TipManager / TipView.cpp
blob7ae48627b2bd326795125746bb0cc910fc662d83
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
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.
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.
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.
32 // TipView.cpp
34 #include "TipView.h"
36 #include <Debug.h>
37 #include <Window.h>
38 #include <cmath>
39 #include <cstring>
41 using namespace std;
43 __USE_CORTEX_NAMESPACE
45 // -------------------------------------------------------- //
46 // constants
47 // -------------------------------------------------------- //
49 const float TipView::s_xPad = 5.0;
50 const float TipView::s_yPad = 2.0;
52 // -------------------------------------------------------- //
53 // *** dtor/ctors
54 // -------------------------------------------------------- //
56 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) {
65 _initColors();
66 _initFont();
69 // -------------------------------------------------------- //
70 // *** operations
71 // -------------------------------------------------------- //
73 void TipView::setText(
74 const char* text) {
76 _setText(text);
79 // -------------------------------------------------------- //
80 // *** BView
81 // -------------------------------------------------------- //
83 // Adapted from c.lenz' ToolTipView::Draw()
84 void TipView::Draw(
85 BRect updateRect) {
87 BRect r = Bounds();
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);
102 // Draw text
103 SetDrawingMode(B_OP_OVER);
104 SetHighColor(m_textColor);
106 BPoint p = m_offset;
107 for(uint32 n = 0; n < m_lineSet.size(); ++n) {
109 uint32 from = m_lineSet[n];
110 uint32 to = (n < m_lineSet.size()-1) ? m_lineSet[n+1]-1 :
111 m_text.Length();
113 if(to > from)
114 DrawString(
115 m_text.String() + from,
116 to - from,
119 p.y += (m_fontHeight.ascent + m_fontHeight.descent + m_fontHeight.leading);
123 void TipView::FrameResized(
124 float width,
125 float height) {
127 _inherited::FrameResized(width, height);
128 _updateLayout(width, height);
129 Invalidate();
132 void TipView::GetPreferredSize(
133 float* outWidth,
134 float* outHeight) {
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);
141 // -------------------------------------------------------- //
142 // implementation
143 // -------------------------------------------------------- //
145 void _make_color(
146 rgb_color* outColor,
147 uint8 red,
148 uint8 green,
149 uint8 blue,
150 uint8 alpha=255);
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;
163 void TipView::_initColors() {
165 SetViewColor(B_TRANSPARENT_COLOR);
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*/);
173 void TipView::_initFont() {
175 SetFont(&m_font);
176 m_font.GetHeight(&m_fontHeight);
179 void TipView::_updateLayout(
180 float width,
181 float height) {
183 // center text
184 m_offset.x = (width - _maxTextWidth()) / 2;
186 m_offset.y = (height - _textHeight()) / 2;
187 m_offset.y += m_fontHeight.ascent;
190 void TipView::_setText(
191 const char* text) {
193 ASSERT(text);
195 m_lineSet.clear();
196 m_text = text;
198 // skip leading newlines
199 int32 n = 0;
200 while(n < m_text.Length() && m_text[n] == '\n')
201 ++n;
203 // mark first line
204 m_lineSet.push_back(n);
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);
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;
229 return max;
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);
238 return height;
241 // END -- TipView.cpp --