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 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) { 64 65 _initColors(); 66 _initFont(); 67 } 68 69 // -------------------------------------------------------- // 70 // *** operations 71 // -------------------------------------------------------- // 72 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() 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 123 void TipView::FrameResized( 124 float width, 125 float height) { 126 127 _inherited::FrameResized(width, height); 128 _updateLayout(width, height); 129 Invalidate(); 130 } 131 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); 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 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 173 void TipView::_initFont() { 174 175 SetFont(&m_font); 176 m_font.GetHeight(&m_fontHeight); 177 } 178 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 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 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 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