1105644bfSAxel Dörfler /* 2105644bfSAxel Dörfler * Copyright 2001-2005, Haiku Inc. 3105644bfSAxel Dörfler * Distributed under the terms of the MIT License. 4105644bfSAxel Dörfler * 5105644bfSAxel Dörfler * Authors: 6105644bfSAxel Dörfler * Frans van Nispen (xlr8@tref.nl) 7105644bfSAxel Dörfler * Stephan Aßmus <superstippi@gmx.de> 8105644bfSAxel Dörfler */ 9105644bfSAxel Dörfler 10105644bfSAxel Dörfler /** BTextControl displays text that can act like a control. */ 11105644bfSAxel Dörfler 12105644bfSAxel Dörfler 1352a38012Sejakowatz #include <stdio.h> 1452a38012Sejakowatz 15058691d4SStefano Ceccherini #include <Message.h> 16*455d1c46SAxel Dörfler #include <Region.h> 1752a38012Sejakowatz #include <TextControl.h> 1852a38012Sejakowatz #include <Window.h> 1952a38012Sejakowatz 2052a38012Sejakowatz #include "TextInput.h" 2152a38012Sejakowatz 2252a38012Sejakowatz 2352a38012Sejakowatz BTextControl::BTextControl(BRect frame, const char *name, const char *label, 2452a38012Sejakowatz const char *text, BMessage *message, uint32 mask, 2552a38012Sejakowatz uint32 flags) 269cb2dbe2SMarc Flerackers : BControl(frame, name, label, message, mask, flags | B_FRAME_EVENTS) 2752a38012Sejakowatz { 289cb2dbe2SMarc Flerackers InitData(label, text); 2952a38012Sejakowatz 30105644bfSAxel Dörfler float height; 31ee001e26SAxel Dörfler BTextControl::GetPreferredSize(NULL, &height); 32105644bfSAxel Dörfler 33105644bfSAxel Dörfler ResizeTo(Bounds().Width(), height); 34105644bfSAxel Dörfler 35*455d1c46SAxel Dörfler float lineHeight = ceil(fText->LineHeight(0)); 36105644bfSAxel Dörfler fText->ResizeTo(fText->Bounds().Width(), lineHeight); 37105644bfSAxel Dörfler fText->MoveTo(fText->Frame().left, (height - lineHeight) / 2); 3852a38012Sejakowatz } 39058691d4SStefano Ceccherini 40058691d4SStefano Ceccherini 4152a38012Sejakowatz BTextControl::~BTextControl() 4252a38012Sejakowatz { 439cb2dbe2SMarc Flerackers SetModificationMessage(NULL); 4452a38012Sejakowatz } 45058691d4SStefano Ceccherini 46058691d4SStefano Ceccherini 4752a38012Sejakowatz BTextControl::BTextControl(BMessage *data) 4852a38012Sejakowatz : BControl(data) 4952a38012Sejakowatz { 509cb2dbe2SMarc Flerackers InitData(Label(), NULL, data); 5152a38012Sejakowatz 529cb2dbe2SMarc Flerackers int32 _a_label = B_ALIGN_LEFT; 539cb2dbe2SMarc Flerackers int32 _a_text = B_ALIGN_LEFT; 5452a38012Sejakowatz 559cb2dbe2SMarc Flerackers if (data->HasInt32("_a_label")) 569cb2dbe2SMarc Flerackers data->FindInt32("_a_label", &_a_label); 5752a38012Sejakowatz 589cb2dbe2SMarc Flerackers if (data->HasInt32("_a_text")) 599cb2dbe2SMarc Flerackers data->FindInt32("_a_text", &_a_text); 6052a38012Sejakowatz 619cb2dbe2SMarc Flerackers SetAlignment((alignment)_a_label, (alignment)_a_text); 629cb2dbe2SMarc Flerackers 639cb2dbe2SMarc Flerackers if (data->HasFloat("_divide")) 649cb2dbe2SMarc Flerackers data->FindFloat("_a_text", &fDivider); 659cb2dbe2SMarc Flerackers 66058691d4SStefano Ceccherini if (data->HasMessage("_mod_msg")) { 679cb2dbe2SMarc Flerackers BMessage *_mod_msg = new BMessage; 689cb2dbe2SMarc Flerackers data->FindMessage("_mod_msg", _mod_msg); 699cb2dbe2SMarc Flerackers SetModificationMessage(_mod_msg); 709cb2dbe2SMarc Flerackers } 7152a38012Sejakowatz } 72058691d4SStefano Ceccherini 73058691d4SStefano Ceccherini 74058691d4SStefano Ceccherini BArchivable * 75058691d4SStefano Ceccherini BTextControl::Instantiate(BMessage *archive) 7652a38012Sejakowatz { 779cb2dbe2SMarc Flerackers if (validate_instantiation(archive, "BTextControl")) 789cb2dbe2SMarc Flerackers return new BTextControl(archive); 799cb2dbe2SMarc Flerackers else 8052a38012Sejakowatz return NULL; 8152a38012Sejakowatz } 82058691d4SStefano Ceccherini 83058691d4SStefano Ceccherini 84058691d4SStefano Ceccherini status_t 85058691d4SStefano Ceccherini BTextControl::Archive(BMessage *data, bool deep) const 8652a38012Sejakowatz { 879cb2dbe2SMarc Flerackers BView::Archive(data, deep); 8852a38012Sejakowatz 89058691d4SStefano Ceccherini alignment labelAlignment, textAlignment; 9052a38012Sejakowatz 91058691d4SStefano Ceccherini GetAlignment(&labelAlignment, &textAlignment); 929cb2dbe2SMarc Flerackers 93058691d4SStefano Ceccherini data->AddInt32("_a_label", labelAlignment); 94058691d4SStefano Ceccherini data->AddInt32("_a_text", textAlignment); 959cb2dbe2SMarc Flerackers data->AddFloat("_divide", Divider()); 969cb2dbe2SMarc Flerackers 979cb2dbe2SMarc Flerackers if (ModificationMessage()) 989cb2dbe2SMarc Flerackers data->AddMessage("_mod_msg", ModificationMessage()); 999cb2dbe2SMarc Flerackers 1009cb2dbe2SMarc Flerackers return B_OK; 10152a38012Sejakowatz } 102058691d4SStefano Ceccherini 103058691d4SStefano Ceccherini 104058691d4SStefano Ceccherini void 105058691d4SStefano Ceccherini BTextControl::SetText(const char *text) 10652a38012Sejakowatz { 1079cb2dbe2SMarc Flerackers if (InvokeKind() != B_CONTROL_INVOKED) 1089cb2dbe2SMarc Flerackers return; 1099cb2dbe2SMarc Flerackers 11052a38012Sejakowatz fText->SetText(text); 1119cb2dbe2SMarc Flerackers 1129cb2dbe2SMarc Flerackers if (IsFocus()) 1139cb2dbe2SMarc Flerackers fText->SetInitialText(); 1149cb2dbe2SMarc Flerackers 1159cb2dbe2SMarc Flerackers fText->Invalidate(); 11652a38012Sejakowatz } 117058691d4SStefano Ceccherini 118058691d4SStefano Ceccherini 119058691d4SStefano Ceccherini const char * 120058691d4SStefano Ceccherini BTextControl::Text() const 12152a38012Sejakowatz { 12252a38012Sejakowatz return fText->Text(); 12352a38012Sejakowatz } 124058691d4SStefano Ceccherini 125058691d4SStefano Ceccherini 126058691d4SStefano Ceccherini void 127058691d4SStefano Ceccherini BTextControl::SetValue(int32 value) 12852a38012Sejakowatz { 1299cb2dbe2SMarc Flerackers BControl::SetValue(value); 13052a38012Sejakowatz } 131058691d4SStefano Ceccherini 132058691d4SStefano Ceccherini 133058691d4SStefano Ceccherini status_t 134058691d4SStefano Ceccherini BTextControl::Invoke(BMessage *message) 13552a38012Sejakowatz { 136058691d4SStefano Ceccherini return BControl::Invoke(message); 13752a38012Sejakowatz } 138058691d4SStefano Ceccherini 139058691d4SStefano Ceccherini 140058691d4SStefano Ceccherini BTextView * 141058691d4SStefano Ceccherini BTextControl::TextView() const 14252a38012Sejakowatz { 1439cb2dbe2SMarc Flerackers return fText; 14452a38012Sejakowatz } 145058691d4SStefano Ceccherini 146058691d4SStefano Ceccherini 147058691d4SStefano Ceccherini void 148058691d4SStefano Ceccherini BTextControl::SetModificationMessage(BMessage *message) 14952a38012Sejakowatz { 1509cb2dbe2SMarc Flerackers delete fModificationMessage; 15152a38012Sejakowatz fModificationMessage = message; 15252a38012Sejakowatz } 153058691d4SStefano Ceccherini 154058691d4SStefano Ceccherini 155058691d4SStefano Ceccherini BMessage * 156058691d4SStefano Ceccherini BTextControl::ModificationMessage() const 15752a38012Sejakowatz { 15852a38012Sejakowatz return fModificationMessage; 15952a38012Sejakowatz } 160058691d4SStefano Ceccherini 161058691d4SStefano Ceccherini 162058691d4SStefano Ceccherini void 163058691d4SStefano Ceccherini BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment) 16452a38012Sejakowatz { 165058691d4SStefano Ceccherini fText->SetAlignment(textAlignment); 1669cb2dbe2SMarc Flerackers fText->AlignTextRect(); 1679cb2dbe2SMarc Flerackers 168058691d4SStefano Ceccherini if (fLabelAlign != labelAlignment) { 169058691d4SStefano Ceccherini fLabelAlign = labelAlignment; 1709cb2dbe2SMarc Flerackers Invalidate(); 1719cb2dbe2SMarc Flerackers } 17252a38012Sejakowatz } 173058691d4SStefano Ceccherini 174058691d4SStefano Ceccherini 175058691d4SStefano Ceccherini void 176058691d4SStefano Ceccherini BTextControl::GetAlignment(alignment *label, alignment *text) const 17752a38012Sejakowatz { 178058691d4SStefano Ceccherini if (label) 17952a38012Sejakowatz *label = fLabelAlign; 180058691d4SStefano Ceccherini if (text) 18152a38012Sejakowatz *text = fText->Alignment(); 18252a38012Sejakowatz } 1839cb2dbe2SMarc Flerackers 184058691d4SStefano Ceccherini 185058691d4SStefano Ceccherini void 186058691d4SStefano Ceccherini BTextControl::SetDivider(float dividingLine) 187058691d4SStefano Ceccherini { 1882e6a5805SStephan Aßmus dividingLine = floorf(dividingLine + 0.5); 1892e6a5805SStephan Aßmus 190058691d4SStefano Ceccherini float dx = fDivider - dividingLine; 191058691d4SStefano Ceccherini 192058691d4SStefano Ceccherini fDivider = dividingLine; 19352a38012Sejakowatz 1949cb2dbe2SMarc Flerackers fText->MoveBy(-dx, 0.0f); 1959cb2dbe2SMarc Flerackers fText->ResizeBy(dx, 0.0f); 19652a38012Sejakowatz 197058691d4SStefano Ceccherini if (Window()) { 19852a38012Sejakowatz fText->Invalidate(); 19952a38012Sejakowatz Invalidate(); 20052a38012Sejakowatz } 2019cb2dbe2SMarc Flerackers } 202058691d4SStefano Ceccherini 203058691d4SStefano Ceccherini 204058691d4SStefano Ceccherini float 205058691d4SStefano Ceccherini BTextControl::Divider() const 20652a38012Sejakowatz { 20752a38012Sejakowatz return fDivider; 20852a38012Sejakowatz } 209058691d4SStefano Ceccherini 210058691d4SStefano Ceccherini 211058691d4SStefano Ceccherini void 212058691d4SStefano Ceccherini BTextControl::Draw(BRect updateRect) 21352a38012Sejakowatz { 214105644bfSAxel Dörfler rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR), 215105644bfSAxel Dörfler lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT), 216105644bfSAxel Dörfler lighten2 = tint_color(noTint, B_LIGHTEN_2_TINT), 217105644bfSAxel Dörfler lightenMax = tint_color(noTint, B_LIGHTEN_MAX_TINT), 218105644bfSAxel Dörfler darken1 = tint_color(noTint, B_DARKEN_1_TINT), 219105644bfSAxel Dörfler darken2 = tint_color(noTint, B_DARKEN_2_TINT), 220105644bfSAxel Dörfler darken4 = tint_color(noTint, B_DARKEN_4_TINT), 221105644bfSAxel Dörfler darkenMax = tint_color(noTint, B_DARKEN_MAX_TINT), 222105644bfSAxel Dörfler navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 2239cb2dbe2SMarc Flerackers 2249cb2dbe2SMarc Flerackers bool enabled = IsEnabled(); 2259cb2dbe2SMarc Flerackers bool active = false; 2269cb2dbe2SMarc Flerackers 2279cb2dbe2SMarc Flerackers if (fText->IsFocus() && Window()->IsActive()) 2289cb2dbe2SMarc Flerackers active = true; 2299cb2dbe2SMarc Flerackers 230*455d1c46SAxel Dörfler // outer bevel 231*455d1c46SAxel Dörfler 232*455d1c46SAxel Dörfler BRect rect = Bounds(); 233*455d1c46SAxel Dörfler rect.left = fDivider; 234*455d1c46SAxel Dörfler 235*455d1c46SAxel Dörfler if (enabled) 236*455d1c46SAxel Dörfler SetHighColor(darken1); 237*455d1c46SAxel Dörfler else 238*455d1c46SAxel Dörfler SetHighColor(noTint); 239*455d1c46SAxel Dörfler 240*455d1c46SAxel Dörfler StrokeLine(rect.LeftBottom(), rect.LeftTop()); 241*455d1c46SAxel Dörfler StrokeLine(rect.RightTop()); 242*455d1c46SAxel Dörfler 243*455d1c46SAxel Dörfler if (enabled) 244*455d1c46SAxel Dörfler SetHighColor(lighten2); 245*455d1c46SAxel Dörfler else 246*455d1c46SAxel Dörfler SetHighColor(lighten1); 247*455d1c46SAxel Dörfler 248*455d1c46SAxel Dörfler StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 249*455d1c46SAxel Dörfler StrokeLine(BPoint(rect.right, rect.top + 1.0f), rect.RightBottom()); 250*455d1c46SAxel Dörfler 251*455d1c46SAxel Dörfler // inner bevel 252*455d1c46SAxel Dörfler 253*455d1c46SAxel Dörfler rect.InsetBy(1.0f, 1.0f); 2549cb2dbe2SMarc Flerackers 255058691d4SStefano Ceccherini if (active) { 256105644bfSAxel Dörfler SetHighColor(navigationColor); 2579cb2dbe2SMarc Flerackers StrokeRect(rect); 258058691d4SStefano Ceccherini } else { 2599cb2dbe2SMarc Flerackers if (enabled) 2609cb2dbe2SMarc Flerackers SetHighColor(darken4); 2619cb2dbe2SMarc Flerackers else 2629cb2dbe2SMarc Flerackers SetHighColor(darken2); 2639cb2dbe2SMarc Flerackers 2649cb2dbe2SMarc Flerackers StrokeLine(rect.LeftTop(), rect.LeftBottom()); 2659cb2dbe2SMarc Flerackers StrokeLine(rect.LeftTop(), rect.RightTop()); 2669cb2dbe2SMarc Flerackers 267105644bfSAxel Dörfler SetHighColor(noTint); 2689cb2dbe2SMarc Flerackers StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 2699cb2dbe2SMarc Flerackers StrokeLine(BPoint(rect.right, rect.top + 1.0f)); 2709cb2dbe2SMarc Flerackers } 2719cb2dbe2SMarc Flerackers 272*455d1c46SAxel Dörfler // area around text view 2739cb2dbe2SMarc Flerackers 274*455d1c46SAxel Dörfler SetHighColor(fText->ViewColor()); 275*455d1c46SAxel Dörfler rect.InsetBy(1, 1); 276*455d1c46SAxel Dörfler BRegion region(rect); 277*455d1c46SAxel Dörfler BRegion updateRegion(updateRect); 278*455d1c46SAxel Dörfler // why is there no IntersectWith(BRect &) version? 279*455d1c46SAxel Dörfler region.IntersectWith(&updateRegion); 280*455d1c46SAxel Dörfler for (int32 i = region.CountRects(); i-- > 0;) { 281*455d1c46SAxel Dörfler FillRect(region.RectAt(i)); 282*455d1c46SAxel Dörfler } 28352a38012Sejakowatz 284058691d4SStefano Ceccherini if (Label()) { 285105644bfSAxel Dörfler font_height fontHeight; 286105644bfSAxel Dörfler GetFontHeight(&fontHeight); 2879cb2dbe2SMarc Flerackers 288105644bfSAxel Dörfler float y = fontHeight.ascent + fText->Frame().top + 1; 28952a38012Sejakowatz float x; 2909cb2dbe2SMarc Flerackers 291058691d4SStefano Ceccherini switch (fLabelAlign) { 29252a38012Sejakowatz case B_ALIGN_RIGHT: 2939cb2dbe2SMarc Flerackers x = fDivider - StringWidth(Label()) - 3.0f; 29452a38012Sejakowatz break; 29552a38012Sejakowatz 29652a38012Sejakowatz case B_ALIGN_CENTER: 2979cb2dbe2SMarc Flerackers x = fDivider - StringWidth(Label()) / 2.0f; 29852a38012Sejakowatz break; 29952a38012Sejakowatz 30052a38012Sejakowatz default: 30152a38012Sejakowatz x = 3.0f; 30252a38012Sejakowatz break; 30352a38012Sejakowatz } 30452a38012Sejakowatz 305105644bfSAxel Dörfler SetHighColor(IsEnabled() ? darkenMax 306105644bfSAxel Dörfler : tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DISABLED_LABEL_TINT)); 30752a38012Sejakowatz DrawString(Label(), BPoint(x, y)); 30852a38012Sejakowatz } 30952a38012Sejakowatz } 310058691d4SStefano Ceccherini 311058691d4SStefano Ceccherini 312058691d4SStefano Ceccherini void 313058691d4SStefano Ceccherini BTextControl::MouseDown(BPoint where) 31452a38012Sejakowatz { 315058691d4SStefano Ceccherini if (!fText->IsFocus()) { 3169cb2dbe2SMarc Flerackers fText->MakeFocus(true); 3179cb2dbe2SMarc Flerackers fText->SelectAll(); 31852a38012Sejakowatz } 31952a38012Sejakowatz } 320058691d4SStefano Ceccherini 321058691d4SStefano Ceccherini 322058691d4SStefano Ceccherini void 323058691d4SStefano Ceccherini BTextControl::AttachedToWindow() 32452a38012Sejakowatz { 32552a38012Sejakowatz BControl::AttachedToWindow(); 32652a38012Sejakowatz 3279cb2dbe2SMarc Flerackers bool enabled = IsEnabled(); 3289cb2dbe2SMarc Flerackers rgb_color textColor; 3299cb2dbe2SMarc Flerackers rgb_color color = HighColor(); 3309cb2dbe2SMarc Flerackers BFont font; 3319cb2dbe2SMarc Flerackers 3329cb2dbe2SMarc Flerackers fText->GetFontAndColor(0, &font, &color); 3339cb2dbe2SMarc Flerackers 3349cb2dbe2SMarc Flerackers if (enabled) 3359cb2dbe2SMarc Flerackers textColor = color; 3369cb2dbe2SMarc Flerackers else 3379cb2dbe2SMarc Flerackers textColor = tint_color(color, B_LIGHTEN_2_TINT); 3389cb2dbe2SMarc Flerackers 3399cb2dbe2SMarc Flerackers fText->SetFontAndColor(&font, B_FONT_ALL, &textColor); 3409cb2dbe2SMarc Flerackers 341058691d4SStefano Ceccherini if (enabled) { 3429cb2dbe2SMarc Flerackers color.red = 255; 3439cb2dbe2SMarc Flerackers color.green = 255; 3449cb2dbe2SMarc Flerackers color.blue = 255; 345058691d4SStefano Ceccherini } else 3469cb2dbe2SMarc Flerackers color = tint_color(color, B_LIGHTEN_2_TINT); 3479cb2dbe2SMarc Flerackers 3489cb2dbe2SMarc Flerackers fText->SetViewColor(color); 3499cb2dbe2SMarc Flerackers fText->SetLowColor(color); 3509cb2dbe2SMarc Flerackers 3519cb2dbe2SMarc Flerackers fText->MakeEditable(enabled); 35252a38012Sejakowatz } 353058691d4SStefano Ceccherini 354058691d4SStefano Ceccherini 355058691d4SStefano Ceccherini void 356058691d4SStefano Ceccherini BTextControl::MakeFocus(bool state) 35752a38012Sejakowatz { 3586d8d6cadSStephan Aßmus if (state != fText->IsFocus()) { 35952a38012Sejakowatz fText->MakeFocus(state); 3609cb2dbe2SMarc Flerackers 3619cb2dbe2SMarc Flerackers if (state) 3629cb2dbe2SMarc Flerackers fText->SelectAll(); 36352a38012Sejakowatz } 3646d8d6cadSStephan Aßmus } 365058691d4SStefano Ceccherini 366058691d4SStefano Ceccherini 367058691d4SStefano Ceccherini void 368058691d4SStefano Ceccherini BTextControl::SetEnabled(bool state) 36952a38012Sejakowatz { 3709cb2dbe2SMarc Flerackers if (IsEnabled() == state) 3719cb2dbe2SMarc Flerackers return; 3729cb2dbe2SMarc Flerackers 373058691d4SStefano Ceccherini if (Window()) { 3749cb2dbe2SMarc Flerackers fText->MakeEditable(state); 3759cb2dbe2SMarc Flerackers 3769cb2dbe2SMarc Flerackers rgb_color textColor; 3779cb2dbe2SMarc Flerackers rgb_color color = {0, 0, 0, 255}; 3789cb2dbe2SMarc Flerackers BFont font; 3799cb2dbe2SMarc Flerackers 3809cb2dbe2SMarc Flerackers fText->GetFontAndColor(0, &font, &color); 3819cb2dbe2SMarc Flerackers 3829cb2dbe2SMarc Flerackers if (state) 3839cb2dbe2SMarc Flerackers textColor = color; 3849cb2dbe2SMarc Flerackers else 3859cb2dbe2SMarc Flerackers textColor = tint_color(color, B_DISABLED_LABEL_TINT); 3869cb2dbe2SMarc Flerackers 3879cb2dbe2SMarc Flerackers fText->SetFontAndColor(&font, B_FONT_ALL, &textColor); 3889cb2dbe2SMarc Flerackers 389058691d4SStefano Ceccherini if (state) { 3909cb2dbe2SMarc Flerackers color.red = 255; 3919cb2dbe2SMarc Flerackers color.green = 255; 3929cb2dbe2SMarc Flerackers color.blue = 255; 393058691d4SStefano Ceccherini } else 3949cb2dbe2SMarc Flerackers color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 3959cb2dbe2SMarc Flerackers B_LIGHTEN_2_TINT); 3969cb2dbe2SMarc Flerackers 3979cb2dbe2SMarc Flerackers fText->SetViewColor(color); 3989cb2dbe2SMarc Flerackers fText->SetLowColor(color); 3999cb2dbe2SMarc Flerackers 4009cb2dbe2SMarc Flerackers fText->Invalidate(); 4019cb2dbe2SMarc Flerackers Window()->UpdateIfNeeded(); 4029cb2dbe2SMarc Flerackers } 4039cb2dbe2SMarc Flerackers 40452a38012Sejakowatz BControl::SetEnabled(state); 40552a38012Sejakowatz } 406058691d4SStefano Ceccherini 407058691d4SStefano Ceccherini 408058691d4SStefano Ceccherini void 409105644bfSAxel Dörfler BTextControl::GetPreferredSize(float *_width, float *_height) 41052a38012Sejakowatz { 411105644bfSAxel Dörfler if (_height) { 412105644bfSAxel Dörfler // we need enough space for the label and the child text view 413105644bfSAxel Dörfler font_height fontHeight; 414105644bfSAxel Dörfler GetFontHeight(&fontHeight); 415105644bfSAxel Dörfler float labelHeight = ceil(fontHeight.ascent + fontHeight.descent 416105644bfSAxel Dörfler + fontHeight.leading); 417105644bfSAxel Dörfler float textHeight = fText->LineHeight(0) + 4.0; 41852a38012Sejakowatz 419105644bfSAxel Dörfler *_height = max_c(labelHeight, textHeight); 420105644bfSAxel Dörfler } 421105644bfSAxel Dörfler 422105644bfSAxel Dörfler if (_width) { 42352a38012Sejakowatz // TODO: this one I need to find out 424105644bfSAxel Dörfler float width = 20.0f + ceilf(StringWidth(Label())); 425105644bfSAxel Dörfler if (width < Bounds().Width()) 426105644bfSAxel Dörfler width = Bounds().Width(); 427105644bfSAxel Dörfler *_width = width; 428105644bfSAxel Dörfler } 42952a38012Sejakowatz } 430058691d4SStefano Ceccherini 431058691d4SStefano Ceccherini 432058691d4SStefano Ceccherini void 433058691d4SStefano Ceccherini BTextControl::ResizeToPreferred() 43452a38012Sejakowatz { 435105644bfSAxel Dörfler // TODO: change divider? 436105644bfSAxel Dörfler BView::ResizeToPreferred(); 43752a38012Sejakowatz } 438058691d4SStefano Ceccherini 439058691d4SStefano Ceccherini 440058691d4SStefano Ceccherini void 441058691d4SStefano Ceccherini BTextControl::SetFlags(uint32 flags) 44252a38012Sejakowatz { 443058691d4SStefano Ceccherini if (!fSkipSetFlags) { 4449cb2dbe2SMarc Flerackers // If the textview is navigable, set it to not navigable if needed 4459cb2dbe2SMarc Flerackers // Else if it is not navigable, set it to navigable if needed 446058691d4SStefano Ceccherini if (fText->Flags() & B_NAVIGABLE) { 4479cb2dbe2SMarc Flerackers if (!(flags & B_NAVIGABLE)) 4489cb2dbe2SMarc Flerackers fText->SetFlags(fText->Flags() & ~B_NAVIGABLE); 449058691d4SStefano Ceccherini 450058691d4SStefano Ceccherini } else { 4519cb2dbe2SMarc Flerackers if (flags & B_NAVIGABLE) 4529cb2dbe2SMarc Flerackers fText->SetFlags(fText->Flags() | B_NAVIGABLE); 4539cb2dbe2SMarc Flerackers } 4549cb2dbe2SMarc Flerackers 4559cb2dbe2SMarc Flerackers // Don't make this one navigable 4569cb2dbe2SMarc Flerackers flags &= ~B_NAVIGABLE; 4579cb2dbe2SMarc Flerackers } 4589cb2dbe2SMarc Flerackers 45952a38012Sejakowatz BView::SetFlags(flags); 46052a38012Sejakowatz } 461058691d4SStefano Ceccherini 462058691d4SStefano Ceccherini 463058691d4SStefano Ceccherini void 464058691d4SStefano Ceccherini BTextControl::MessageReceived(BMessage *msg) 46552a38012Sejakowatz { 466058691d4SStefano Ceccherini switch(msg->what) { 4679cb2dbe2SMarc Flerackers case B_SET_PROPERTY: 4689cb2dbe2SMarc Flerackers case B_GET_PROPERTY: 4699cb2dbe2SMarc Flerackers // TODO 47052a38012Sejakowatz break; 47152a38012Sejakowatz default: 47252a38012Sejakowatz BControl::MessageReceived(msg); 47352a38012Sejakowatz break; 47452a38012Sejakowatz } 47552a38012Sejakowatz } 476058691d4SStefano Ceccherini 477058691d4SStefano Ceccherini 478058691d4SStefano Ceccherini BHandler * 479058691d4SStefano Ceccherini BTextControl::ResolveSpecifier(BMessage *msg, int32 index, 48052a38012Sejakowatz BMessage *specifier, int32 form, 48152a38012Sejakowatz const char *property) 48252a38012Sejakowatz { 4839cb2dbe2SMarc Flerackers /* 4849cb2dbe2SMarc Flerackers BPropertyInfo propInfo(prop_list); 4859cb2dbe2SMarc Flerackers BHandler *target = NULL; 4869cb2dbe2SMarc Flerackers 4879cb2dbe2SMarc Flerackers if (propInfo.FindMatch(message, 0, specifier, what, property) < B_OK) 4889cb2dbe2SMarc Flerackers return BControl::ResolveSpecifier(message, index, specifier, what, 4899cb2dbe2SMarc Flerackers property); 4909cb2dbe2SMarc Flerackers else 4919cb2dbe2SMarc Flerackers return this; 4929cb2dbe2SMarc Flerackers */ 4939cb2dbe2SMarc Flerackers return BControl::ResolveSpecifier(msg, index, specifier, form, property); 49452a38012Sejakowatz } 495058691d4SStefano Ceccherini 496058691d4SStefano Ceccherini 497058691d4SStefano Ceccherini status_t 498058691d4SStefano Ceccherini BTextControl::GetSupportedSuites(BMessage *data) 49952a38012Sejakowatz { 5009cb2dbe2SMarc Flerackers return BControl::GetSupportedSuites(data); 50152a38012Sejakowatz } 502058691d4SStefano Ceccherini 503058691d4SStefano Ceccherini 504058691d4SStefano Ceccherini void 505058691d4SStefano Ceccherini BTextControl::MouseUp(BPoint pt) 50652a38012Sejakowatz { 50752a38012Sejakowatz BControl::MouseUp(pt); 50852a38012Sejakowatz } 509058691d4SStefano Ceccherini 510058691d4SStefano Ceccherini 511058691d4SStefano Ceccherini void 512058691d4SStefano Ceccherini BTextControl::MouseMoved(BPoint pt, uint32 code, const BMessage *msg) 51352a38012Sejakowatz { 51452a38012Sejakowatz BControl::MouseMoved(pt, code, msg); 51552a38012Sejakowatz } 516058691d4SStefano Ceccherini 517058691d4SStefano Ceccherini 518058691d4SStefano Ceccherini void 519058691d4SStefano Ceccherini BTextControl::DetachedFromWindow() 52052a38012Sejakowatz { 52152a38012Sejakowatz BControl::DetachedFromWindow(); 52252a38012Sejakowatz } 523058691d4SStefano Ceccherini 524058691d4SStefano Ceccherini 525058691d4SStefano Ceccherini void 526058691d4SStefano Ceccherini BTextControl::AllAttached() 52752a38012Sejakowatz { 52852a38012Sejakowatz BControl::AllAttached(); 52952a38012Sejakowatz } 530058691d4SStefano Ceccherini 531058691d4SStefano Ceccherini 532058691d4SStefano Ceccherini void 533058691d4SStefano Ceccherini BTextControl::AllDetached() 53452a38012Sejakowatz { 53552a38012Sejakowatz BControl::AllDetached(); 53652a38012Sejakowatz } 537058691d4SStefano Ceccherini 538058691d4SStefano Ceccherini 539058691d4SStefano Ceccherini void 540058691d4SStefano Ceccherini BTextControl::FrameMoved(BPoint newPosition) 54152a38012Sejakowatz { 54252a38012Sejakowatz BControl::FrameMoved(newPosition); 54352a38012Sejakowatz } 544058691d4SStefano Ceccherini 545058691d4SStefano Ceccherini 546058691d4SStefano Ceccherini void 547058691d4SStefano Ceccherini BTextControl::FrameResized(float newWidth, float newHeight) 54852a38012Sejakowatz { 54952a38012Sejakowatz BControl::FrameResized(newWidth, newHeight); 55052a38012Sejakowatz } 551058691d4SStefano Ceccherini 552058691d4SStefano Ceccherini 553058691d4SStefano Ceccherini void 554058691d4SStefano Ceccherini BTextControl::WindowActivated(bool active) 55552a38012Sejakowatz { 5566d8d6cadSStephan Aßmus if (fText->IsFocus()) { 5576d8d6cadSStephan Aßmus BRect rect(fText->Frame()); 5586d8d6cadSStephan Aßmus rect.InsetBy(-1.0, -1.0); 5596d8d6cadSStephan Aßmus Invalidate(rect); 5606d8d6cadSStephan Aßmus } 56152a38012Sejakowatz } 562058691d4SStefano Ceccherini 563058691d4SStefano Ceccherini 564058691d4SStefano Ceccherini status_t 565058691d4SStefano Ceccherini BTextControl::Perform(perform_code d, void *arg) 56652a38012Sejakowatz { 56752a38012Sejakowatz return BControl::Perform(d, arg); 56852a38012Sejakowatz } 569058691d4SStefano Ceccherini 570058691d4SStefano Ceccherini 5719cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl1() {} 5729cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl2() {} 5739cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl3() {} 5749cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl4() {} 575058691d4SStefano Ceccherini 576058691d4SStefano Ceccherini 577058691d4SStefano Ceccherini BTextControl & 578058691d4SStefano Ceccherini BTextControl::operator=(const BTextControl&) 57952a38012Sejakowatz { 58052a38012Sejakowatz return *this; 58152a38012Sejakowatz } 582058691d4SStefano Ceccherini 583058691d4SStefano Ceccherini 584058691d4SStefano Ceccherini void 585058691d4SStefano Ceccherini BTextControl::CommitValue() 5869cb2dbe2SMarc Flerackers { 5879cb2dbe2SMarc Flerackers } 588058691d4SStefano Ceccherini 589058691d4SStefano Ceccherini 590058691d4SStefano Ceccherini void 591*455d1c46SAxel Dörfler BTextControl::InitData(const char *label, const char *initialText, 5929cb2dbe2SMarc Flerackers BMessage *data) 5939cb2dbe2SMarc Flerackers { 5949cb2dbe2SMarc Flerackers BRect bounds(Bounds()); 5959cb2dbe2SMarc Flerackers 5969cb2dbe2SMarc Flerackers fText = NULL; 5979cb2dbe2SMarc Flerackers fModificationMessage = NULL; 5989cb2dbe2SMarc Flerackers fLabelAlign = B_ALIGN_LEFT; 5999cb2dbe2SMarc Flerackers fDivider = 0.0f; 6009cb2dbe2SMarc Flerackers fPrevWidth = 0; 6019cb2dbe2SMarc Flerackers fPrevHeight = 0; 6029cb2dbe2SMarc Flerackers fSkipSetFlags = false; 6039cb2dbe2SMarc Flerackers 6049cb2dbe2SMarc Flerackers int32 flags = 0; 6059cb2dbe2SMarc Flerackers 606918a22d9SDarkWyrm BFont font(be_plain_font); 6079cb2dbe2SMarc Flerackers 6089cb2dbe2SMarc Flerackers if (!data || !data->HasString("_fname")) 609058691d4SStefano Ceccherini flags |= B_FONT_FAMILY_AND_STYLE; 6109cb2dbe2SMarc Flerackers 6119cb2dbe2SMarc Flerackers if (!data || !data->HasFloat("_fflt")) 612058691d4SStefano Ceccherini flags |= B_FONT_SIZE; 6139cb2dbe2SMarc Flerackers 6149cb2dbe2SMarc Flerackers if (flags != 0) 6159cb2dbe2SMarc Flerackers SetFont(&font, flags); 6169cb2dbe2SMarc Flerackers 6179cb2dbe2SMarc Flerackers if (label) 6182e6a5805SStephan Aßmus fDivider = floorf(bounds.Width() / 2.0f); 6199cb2dbe2SMarc Flerackers 620105644bfSAxel Dörfler uint32 navigableFlags = Flags() & B_NAVIGABLE; 621105644bfSAxel Dörfler if (navigableFlags != 0) { 6229cb2dbe2SMarc Flerackers fSkipSetFlags = true; 6239cb2dbe2SMarc Flerackers SetFlags(Flags() & ~B_NAVIGABLE); 6249cb2dbe2SMarc Flerackers fSkipSetFlags = false; 6259cb2dbe2SMarc Flerackers } 6269cb2dbe2SMarc Flerackers 6279cb2dbe2SMarc Flerackers if (data) 628058691d4SStefano Ceccherini fText = static_cast<_BTextInput_ *>(FindView("_input_")); 629058691d4SStefano Ceccherini else { 6302e6a5805SStephan Aßmus BRect frame(fDivider, bounds.top, 6312e6a5805SStephan Aßmus bounds.right, bounds.bottom); 632105644bfSAxel Dörfler // we are stroking the frame around the text view, which 6332e6a5805SStephan Aßmus // is 2 pixels wide 634*455d1c46SAxel Dörfler frame.InsetBy(4.0, 3.0); 6359cb2dbe2SMarc Flerackers BRect textRect(frame.OffsetToCopy(0.0f, 0.0f)); 6369cb2dbe2SMarc Flerackers 6379cb2dbe2SMarc Flerackers fText = new _BTextInput_(frame, textRect, 6387a70a2d6SStephan Aßmus B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, 639105644bfSAxel Dörfler B_WILL_DRAW | B_FRAME_EVENTS | navigableFlags); 6409cb2dbe2SMarc Flerackers AddChild(fText); 6419cb2dbe2SMarc Flerackers 642*455d1c46SAxel Dörfler SetText(initialText); 6439cb2dbe2SMarc Flerackers fText->SetAlignment(B_ALIGN_LEFT); 6449cb2dbe2SMarc Flerackers fText->AlignTextRect(); 6459cb2dbe2SMarc Flerackers } 6469cb2dbe2SMarc Flerackers } 647