1 /* 2 * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "StringView.h" 8 9 10 StringView::StringView(BRect frame, const char* name, const char* label, 11 const char* text, uint32 resizeMask, uint32 flags) 12 : BView(frame, name, resizeMask, flags), 13 fLabel(label), 14 fText(text), 15 fLabelAlignment(B_ALIGN_RIGHT), 16 fTextAlignment(B_ALIGN_LEFT), 17 fEnabled(true) 18 { 19 fDivider = StringWidth(label) + 4.0f; 20 } 21 22 23 StringView::~StringView() 24 { 25 } 26 27 28 void 29 StringView::SetAlignment(alignment labelAlignment, alignment textAlignment) 30 { 31 if (labelAlignment == fLabelAlignment && textAlignment == fTextAlignment) 32 return; 33 34 fLabelAlignment = labelAlignment; 35 fTextAlignment = textAlignment; 36 37 Invalidate(); 38 } 39 40 41 void 42 StringView::GetAlignment(alignment* _label, alignment* _text) const 43 { 44 if (_label) 45 *_label = fLabelAlignment; 46 if (_text) 47 *_text = fTextAlignment; 48 } 49 50 51 void 52 StringView::SetDivider(float divider) 53 { 54 fDivider = divider; 55 _UpdateText(); 56 57 Invalidate(); 58 } 59 60 61 void 62 StringView::AttachedToWindow() 63 { 64 if (Parent() != NULL) 65 SetViewColor(Parent()->ViewColor()); 66 else 67 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 68 69 SetLowColor(ViewColor()); 70 _UpdateText(); 71 } 72 73 74 void 75 StringView::Draw(BRect updateRect) 76 { 77 BRect rect = Bounds(); 78 79 font_height fontHeight; 80 GetFontHeight(&fontHeight); 81 82 float y = ceilf(fontHeight.ascent) + 1.0f; 83 float x; 84 85 #if defined(HAIKU_TARGET_PLATFORM_BEOS) || defined(HAIKU_TARGET_PLATFORM_BONE) 86 rgb_color textColor = {0, 0, 0, 255}; 87 #else 88 rgb_color textColor = ui_color(B_CONTROL_TEXT_COLOR); 89 #endif 90 91 SetHighColor(IsEnabled() ? textColor 92 : tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT)); 93 94 if (Label()) { 95 switch (fLabelAlignment) { 96 case B_ALIGN_RIGHT: 97 x = Divider() - StringWidth(Label()) - 3.0f; 98 break; 99 100 case B_ALIGN_CENTER: 101 x = Divider() - StringWidth(Label()) / 2.0f; 102 break; 103 104 default: 105 x = 1.0f; 106 break; 107 } 108 109 DrawString(Label(), BPoint(x, y)); 110 } 111 112 if (fTruncatedText.String() != NULL) { 113 switch (fTextAlignment) { 114 case B_ALIGN_RIGHT: 115 x = rect.Width() - StringWidth(fTruncatedText.String()); 116 break; 117 118 case B_ALIGN_CENTER: 119 x = Divider() + (rect.Width() - Divider() - StringWidth(Label())) / 2.0f; 120 break; 121 122 default: 123 x = Divider() + 3.0f; 124 break; 125 } 126 127 DrawString(fTruncatedText.String(), BPoint(x, y)); 128 } 129 } 130 131 132 void 133 StringView::FrameResized(float width, float height) 134 { 135 BString oldTruncated = fTruncatedText; 136 _UpdateText(); 137 138 if (oldTruncated != fTruncatedText) { 139 // invalidate text portion only 140 BRect rect = Bounds(); 141 rect.left = Divider(); 142 Invalidate(rect); 143 } 144 } 145 146 147 void 148 StringView::ResizeToPreferred() 149 { 150 float width, height; 151 GetPreferredSize(&width, &height); 152 153 // Resize the width only for B_ALIGN_LEFT (if its large enough already, that is) 154 if (Bounds().Width() > width 155 && (fLabelAlignment != B_ALIGN_LEFT || fTextAlignment != B_ALIGN_LEFT)) 156 width = Bounds().Width(); 157 158 BView::ResizeTo(width, height); 159 } 160 161 162 void 163 StringView::GetPreferredSize(float* _width, float* _height) 164 { 165 if (!Text() && !Label()) { 166 BView::GetPreferredSize(_width, _height); 167 return; 168 } 169 170 if (_width) 171 *_width = 7.0f + ceilf(StringWidth(Label()) + StringWidth(Text())); 172 173 if (_height) { 174 font_height fontHeight; 175 GetFontHeight(&fontHeight); 176 *_height = ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading) + 2.0f; 177 } 178 } 179 180 181 void 182 StringView::SetEnabled(bool enabled) 183 { 184 if (IsEnabled() == enabled) 185 return; 186 187 fEnabled = enabled; 188 Invalidate(); 189 } 190 191 192 void 193 StringView::SetLabel(const char* label) 194 { 195 fLabel = label; 196 197 // invalidate label portion only 198 BRect rect = Bounds(); 199 rect.right = Divider(); 200 Invalidate(rect); 201 } 202 203 204 void 205 StringView::SetText(const char* text) 206 { 207 fText = text; 208 209 _UpdateText(); 210 211 // invalidate text portion only 212 BRect rect = Bounds(); 213 rect.left = Divider(); 214 Invalidate(rect); 215 } 216 217 218 void 219 StringView::_UpdateText() 220 { 221 fTruncatedText = fText; 222 TruncateString(&fTruncatedText, B_TRUNCATE_MIDDLE, Bounds().Width() - Divider()); 223 } 224