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