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> 16455d1c46SAxel 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 { 28ffe72abdSAxel Dörfler _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 35455d1c46SAxel 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); 38ffe72abdSAxel Dörfler 39ffe72abdSAxel Dörfler fPreviousHeight = Bounds().Height(); 4052a38012Sejakowatz } 41058691d4SStefano Ceccherini 42058691d4SStefano Ceccherini 4352a38012Sejakowatz BTextControl::~BTextControl() 4452a38012Sejakowatz { 459cb2dbe2SMarc Flerackers SetModificationMessage(NULL); 4652a38012Sejakowatz } 47058691d4SStefano Ceccherini 48058691d4SStefano Ceccherini 49ffe72abdSAxel Dörfler BTextControl::BTextControl(BMessage* archive) 50ffe72abdSAxel Dörfler : BControl(archive) 5152a38012Sejakowatz { 52ffe72abdSAxel Dörfler _InitData(Label(), NULL, archive); 5352a38012Sejakowatz 54ffe72abdSAxel Dörfler int32 labelAlignment = B_ALIGN_LEFT; 55ffe72abdSAxel Dörfler int32 textAlignment = B_ALIGN_LEFT; 5652a38012Sejakowatz 57ffe72abdSAxel Dörfler if (archive->HasInt32("_a_label")) 58ffe72abdSAxel Dörfler archive->FindInt32("_a_label", &labelAlignment); 5952a38012Sejakowatz 60ffe72abdSAxel Dörfler if (archive->HasInt32("_a_text")) 61ffe72abdSAxel Dörfler archive->FindInt32("_a_text", &textAlignment); 6252a38012Sejakowatz 63ffe72abdSAxel Dörfler SetAlignment((alignment)labelAlignment, (alignment)textAlignment); 649cb2dbe2SMarc Flerackers 65ffe72abdSAxel Dörfler if (archive->HasFloat("_divide")) 66ffe72abdSAxel Dörfler archive->FindFloat("_a_text", &fDivider); 679cb2dbe2SMarc Flerackers 68ffe72abdSAxel Dörfler if (archive->HasMessage("_mod_msg")) { 69ffe72abdSAxel Dörfler BMessage* message = new BMessage; 70ffe72abdSAxel Dörfler archive->FindMessage("_mod_msg", message); 71ffe72abdSAxel Dörfler SetModificationMessage(message); 729cb2dbe2SMarc Flerackers } 7352a38012Sejakowatz } 74058691d4SStefano Ceccherini 75058691d4SStefano Ceccherini 76058691d4SStefano Ceccherini BArchivable * 77058691d4SStefano Ceccherini BTextControl::Instantiate(BMessage *archive) 7852a38012Sejakowatz { 799cb2dbe2SMarc Flerackers if (validate_instantiation(archive, "BTextControl")) 809cb2dbe2SMarc Flerackers return new BTextControl(archive); 819cb2dbe2SMarc Flerackers else 8252a38012Sejakowatz return NULL; 8352a38012Sejakowatz } 84058691d4SStefano Ceccherini 85058691d4SStefano Ceccherini 86058691d4SStefano Ceccherini status_t 87058691d4SStefano Ceccherini BTextControl::Archive(BMessage *data, bool deep) const 8852a38012Sejakowatz { 89*11d7ecebSJérôme Duval status_t ret = BView::Archive(data, deep); 90058691d4SStefano Ceccherini alignment labelAlignment, textAlignment; 9152a38012Sejakowatz 92058691d4SStefano Ceccherini GetAlignment(&labelAlignment, &textAlignment); 939cb2dbe2SMarc Flerackers 94*11d7ecebSJérôme Duval if (ret == B_OK) 95*11d7ecebSJérôme Duval ret = data->AddInt32("_a_label", labelAlignment); 96*11d7ecebSJérôme Duval if (ret == B_OK) 97*11d7ecebSJérôme Duval ret = data->AddInt32("_a_text", textAlignment); 98*11d7ecebSJérôme Duval if (ret == B_OK) 99*11d7ecebSJérôme Duval ret = data->AddFloat("_divide", Divider()); 1009cb2dbe2SMarc Flerackers 101*11d7ecebSJérôme Duval if (ModificationMessage() && (ret == B_OK)) 102*11d7ecebSJérôme Duval ret = data->AddMessage("_mod_msg", ModificationMessage()); 1039cb2dbe2SMarc Flerackers 104*11d7ecebSJérôme Duval return ret; 10552a38012Sejakowatz } 106058691d4SStefano Ceccherini 107058691d4SStefano Ceccherini 108058691d4SStefano Ceccherini void 109058691d4SStefano Ceccherini BTextControl::SetText(const char *text) 11052a38012Sejakowatz { 1119cb2dbe2SMarc Flerackers if (InvokeKind() != B_CONTROL_INVOKED) 1129cb2dbe2SMarc Flerackers return; 1139cb2dbe2SMarc Flerackers 11452a38012Sejakowatz fText->SetText(text); 1159cb2dbe2SMarc Flerackers 1169cb2dbe2SMarc Flerackers if (IsFocus()) 1179cb2dbe2SMarc Flerackers fText->SetInitialText(); 1189cb2dbe2SMarc Flerackers 1199cb2dbe2SMarc Flerackers fText->Invalidate(); 12052a38012Sejakowatz } 121058691d4SStefano Ceccherini 122058691d4SStefano Ceccherini 123058691d4SStefano Ceccherini const char * 124058691d4SStefano Ceccherini BTextControl::Text() const 12552a38012Sejakowatz { 12652a38012Sejakowatz return fText->Text(); 12752a38012Sejakowatz } 128058691d4SStefano Ceccherini 129058691d4SStefano Ceccherini 130058691d4SStefano Ceccherini void 131058691d4SStefano Ceccherini BTextControl::SetValue(int32 value) 13252a38012Sejakowatz { 1339cb2dbe2SMarc Flerackers BControl::SetValue(value); 13452a38012Sejakowatz } 135058691d4SStefano Ceccherini 136058691d4SStefano Ceccherini 137058691d4SStefano Ceccherini status_t 138058691d4SStefano Ceccherini BTextControl::Invoke(BMessage *message) 13952a38012Sejakowatz { 140058691d4SStefano Ceccherini return BControl::Invoke(message); 14152a38012Sejakowatz } 142058691d4SStefano Ceccherini 143058691d4SStefano Ceccherini 144058691d4SStefano Ceccherini BTextView * 145058691d4SStefano Ceccherini BTextControl::TextView() const 14652a38012Sejakowatz { 1479cb2dbe2SMarc Flerackers return fText; 14852a38012Sejakowatz } 149058691d4SStefano Ceccherini 150058691d4SStefano Ceccherini 151058691d4SStefano Ceccherini void 152058691d4SStefano Ceccherini BTextControl::SetModificationMessage(BMessage *message) 15352a38012Sejakowatz { 1549cb2dbe2SMarc Flerackers delete fModificationMessage; 15552a38012Sejakowatz fModificationMessage = message; 15652a38012Sejakowatz } 157058691d4SStefano Ceccherini 158058691d4SStefano Ceccherini 159058691d4SStefano Ceccherini BMessage * 160058691d4SStefano Ceccherini BTextControl::ModificationMessage() const 16152a38012Sejakowatz { 16252a38012Sejakowatz return fModificationMessage; 16352a38012Sejakowatz } 164058691d4SStefano Ceccherini 165058691d4SStefano Ceccherini 166058691d4SStefano Ceccherini void 167058691d4SStefano Ceccherini BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment) 16852a38012Sejakowatz { 169058691d4SStefano Ceccherini fText->SetAlignment(textAlignment); 1709cb2dbe2SMarc Flerackers fText->AlignTextRect(); 1719cb2dbe2SMarc Flerackers 172058691d4SStefano Ceccherini if (fLabelAlign != labelAlignment) { 173058691d4SStefano Ceccherini fLabelAlign = labelAlignment; 1749cb2dbe2SMarc Flerackers Invalidate(); 1759cb2dbe2SMarc Flerackers } 17652a38012Sejakowatz } 177058691d4SStefano Ceccherini 178058691d4SStefano Ceccherini 179058691d4SStefano Ceccherini void 180c432fbbbSAxel Dörfler BTextControl::GetAlignment(alignment* _label, alignment* _text) const 18152a38012Sejakowatz { 182c432fbbbSAxel Dörfler if (_label) 183c432fbbbSAxel Dörfler *_label = fLabelAlign; 184c432fbbbSAxel Dörfler if (_text) 185c432fbbbSAxel Dörfler *_text = fText->Alignment(); 18652a38012Sejakowatz } 1879cb2dbe2SMarc Flerackers 188058691d4SStefano Ceccherini 189058691d4SStefano Ceccherini void 190058691d4SStefano Ceccherini BTextControl::SetDivider(float dividingLine) 191058691d4SStefano Ceccherini { 1922e6a5805SStephan Aßmus dividingLine = floorf(dividingLine + 0.5); 1932e6a5805SStephan Aßmus 194058691d4SStefano Ceccherini float dx = fDivider - dividingLine; 195058691d4SStefano Ceccherini 196058691d4SStefano Ceccherini fDivider = dividingLine; 19752a38012Sejakowatz 1989cb2dbe2SMarc Flerackers fText->MoveBy(-dx, 0.0f); 1999cb2dbe2SMarc Flerackers fText->ResizeBy(dx, 0.0f); 20052a38012Sejakowatz 201058691d4SStefano Ceccherini if (Window()) { 20252a38012Sejakowatz fText->Invalidate(); 20352a38012Sejakowatz Invalidate(); 20452a38012Sejakowatz } 2059cb2dbe2SMarc Flerackers } 206058691d4SStefano Ceccherini 207058691d4SStefano Ceccherini 208058691d4SStefano Ceccherini float 209058691d4SStefano Ceccherini BTextControl::Divider() const 21052a38012Sejakowatz { 21152a38012Sejakowatz return fDivider; 21252a38012Sejakowatz } 213058691d4SStefano Ceccherini 214058691d4SStefano Ceccherini 215058691d4SStefano Ceccherini void 216058691d4SStefano Ceccherini BTextControl::Draw(BRect updateRect) 21752a38012Sejakowatz { 218c432fbbbSAxel Dörfler rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); 219c432fbbbSAxel Dörfler rgb_color lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT); 220c432fbbbSAxel Dörfler rgb_color lighten2 = tint_color(noTint, B_LIGHTEN_2_TINT); 221c432fbbbSAxel Dörfler rgb_color lightenMax = tint_color(noTint, B_LIGHTEN_MAX_TINT); 222c432fbbbSAxel Dörfler rgb_color darken1 = tint_color(noTint, B_DARKEN_1_TINT); 223c432fbbbSAxel Dörfler rgb_color darken2 = tint_color(noTint, B_DARKEN_2_TINT); 224c432fbbbSAxel Dörfler rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT); 225c432fbbbSAxel Dörfler rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); 2269cb2dbe2SMarc Flerackers 2279cb2dbe2SMarc Flerackers bool enabled = IsEnabled(); 2289cb2dbe2SMarc Flerackers bool active = false; 2299cb2dbe2SMarc Flerackers 2309cb2dbe2SMarc Flerackers if (fText->IsFocus() && Window()->IsActive()) 2319cb2dbe2SMarc Flerackers active = true; 2329cb2dbe2SMarc Flerackers 233455d1c46SAxel Dörfler // outer bevel 234455d1c46SAxel Dörfler 235455d1c46SAxel Dörfler BRect rect = Bounds(); 236455d1c46SAxel Dörfler rect.left = fDivider; 237455d1c46SAxel Dörfler 238455d1c46SAxel Dörfler if (enabled) 239455d1c46SAxel Dörfler SetHighColor(darken1); 240455d1c46SAxel Dörfler else 241455d1c46SAxel Dörfler SetHighColor(noTint); 242455d1c46SAxel Dörfler 243455d1c46SAxel Dörfler StrokeLine(rect.LeftBottom(), rect.LeftTop()); 244455d1c46SAxel Dörfler StrokeLine(rect.RightTop()); 245455d1c46SAxel Dörfler 246455d1c46SAxel Dörfler if (enabled) 247455d1c46SAxel Dörfler SetHighColor(lighten2); 248455d1c46SAxel Dörfler else 249455d1c46SAxel Dörfler SetHighColor(lighten1); 250455d1c46SAxel Dörfler 251455d1c46SAxel Dörfler StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 252455d1c46SAxel Dörfler StrokeLine(BPoint(rect.right, rect.top + 1.0f), rect.RightBottom()); 253455d1c46SAxel Dörfler 254455d1c46SAxel Dörfler // inner bevel 255455d1c46SAxel Dörfler 256455d1c46SAxel Dörfler rect.InsetBy(1.0f, 1.0f); 2579cb2dbe2SMarc Flerackers 258058691d4SStefano Ceccherini if (active) { 259105644bfSAxel Dörfler SetHighColor(navigationColor); 2609cb2dbe2SMarc Flerackers StrokeRect(rect); 261058691d4SStefano Ceccherini } else { 2629cb2dbe2SMarc Flerackers if (enabled) 2639cb2dbe2SMarc Flerackers SetHighColor(darken4); 2649cb2dbe2SMarc Flerackers else 2659cb2dbe2SMarc Flerackers SetHighColor(darken2); 2669cb2dbe2SMarc Flerackers 2679cb2dbe2SMarc Flerackers StrokeLine(rect.LeftTop(), rect.LeftBottom()); 2689cb2dbe2SMarc Flerackers StrokeLine(rect.LeftTop(), rect.RightTop()); 2699cb2dbe2SMarc Flerackers 270105644bfSAxel Dörfler SetHighColor(noTint); 2719cb2dbe2SMarc Flerackers StrokeLine(BPoint(rect.left + 1.0f, rect.bottom), rect.RightBottom()); 2729cb2dbe2SMarc Flerackers StrokeLine(BPoint(rect.right, rect.top + 1.0f)); 2739cb2dbe2SMarc Flerackers } 2749cb2dbe2SMarc Flerackers 275455d1c46SAxel Dörfler // area around text view 2769cb2dbe2SMarc Flerackers 277455d1c46SAxel Dörfler SetHighColor(fText->ViewColor()); 278455d1c46SAxel Dörfler rect.InsetBy(1, 1); 279455d1c46SAxel Dörfler BRegion region(rect); 280455d1c46SAxel Dörfler BRegion updateRegion(updateRect); 281455d1c46SAxel Dörfler // why is there no IntersectWith(BRect &) version? 282455d1c46SAxel Dörfler region.IntersectWith(&updateRegion); 283111b4fbcSStefano Ceccherini region.Exclude(fText->Frame()); 2840efe29e0SStefano Ceccherini FillRegion(®ion); 28552a38012Sejakowatz 2867a25fcafSStefano Ceccherini // label 2877a25fcafSStefano Ceccherini 288058691d4SStefano Ceccherini if (Label()) { 289105644bfSAxel Dörfler font_height fontHeight; 290105644bfSAxel Dörfler GetFontHeight(&fontHeight); 2919cb2dbe2SMarc Flerackers 292105644bfSAxel Dörfler float y = fontHeight.ascent + fText->Frame().top + 1; 29352a38012Sejakowatz float x; 2949cb2dbe2SMarc Flerackers 2957a25fcafSStefano Ceccherini float labelWidth = StringWidth(Label()); 296058691d4SStefano Ceccherini switch (fLabelAlign) { 29752a38012Sejakowatz case B_ALIGN_RIGHT: 2987a25fcafSStefano Ceccherini x = fDivider - labelWidth - 3.0f; 29952a38012Sejakowatz break; 30052a38012Sejakowatz 30152a38012Sejakowatz case B_ALIGN_CENTER: 3027a25fcafSStefano Ceccherini x = fDivider - labelWidth / 2.0f; 30352a38012Sejakowatz break; 30452a38012Sejakowatz 30552a38012Sejakowatz default: 30652a38012Sejakowatz x = 3.0f; 30752a38012Sejakowatz break; 30852a38012Sejakowatz } 30952a38012Sejakowatz 3107a25fcafSStefano Ceccherini BRect labelArea(x, fText->Frame().top, x + labelWidth, 3117a25fcafSStefano Ceccherini ceilf(fontHeight.ascent + fontHeight.descent) + 1); 3127a25fcafSStefano Ceccherini if (x < fDivider && updateRect.Intersects(labelArea)) { 3137a25fcafSStefano Ceccherini labelArea.right = fDivider; 3147a25fcafSStefano Ceccherini 3157a25fcafSStefano Ceccherini BRegion clipRegion(labelArea); 3167a25fcafSStefano Ceccherini ConstrainClippingRegion(&clipRegion); 317c432fbbbSAxel Dörfler SetHighColor(IsEnabled() ? ui_color(B_CONTROL_TEXT_COLOR) 318fa815db3SAxel Dörfler : tint_color(noTint, B_DISABLED_LABEL_TINT)); 31952a38012Sejakowatz DrawString(Label(), BPoint(x, y)); 32052a38012Sejakowatz } 32152a38012Sejakowatz } 3227a25fcafSStefano Ceccherini } 323058691d4SStefano Ceccherini 324058691d4SStefano Ceccherini 325058691d4SStefano Ceccherini void 326058691d4SStefano Ceccherini BTextControl::MouseDown(BPoint where) 32752a38012Sejakowatz { 328058691d4SStefano Ceccherini if (!fText->IsFocus()) { 3299cb2dbe2SMarc Flerackers fText->MakeFocus(true); 3309cb2dbe2SMarc Flerackers fText->SelectAll(); 33152a38012Sejakowatz } 33252a38012Sejakowatz } 333058691d4SStefano Ceccherini 334058691d4SStefano Ceccherini 335058691d4SStefano Ceccherini void 336058691d4SStefano Ceccherini BTextControl::AttachedToWindow() 33752a38012Sejakowatz { 33852a38012Sejakowatz BControl::AttachedToWindow(); 33952a38012Sejakowatz 34079c35b39SAxel Dörfler _UpdateTextViewColors(IsEnabled()); 3413a3f6c1eSAxel Dörfler fText->MakeEditable(IsEnabled()); 34252a38012Sejakowatz } 343058691d4SStefano Ceccherini 344058691d4SStefano Ceccherini 345058691d4SStefano Ceccherini void 346058691d4SStefano Ceccherini BTextControl::MakeFocus(bool state) 34752a38012Sejakowatz { 3486d8d6cadSStephan Aßmus if (state != fText->IsFocus()) { 34952a38012Sejakowatz fText->MakeFocus(state); 3509cb2dbe2SMarc Flerackers 3519cb2dbe2SMarc Flerackers if (state) 3529cb2dbe2SMarc Flerackers fText->SelectAll(); 35352a38012Sejakowatz } 3546d8d6cadSStephan Aßmus } 355058691d4SStefano Ceccherini 356058691d4SStefano Ceccherini 357058691d4SStefano Ceccherini void 35879c35b39SAxel Dörfler BTextControl::SetEnabled(bool enabled) 35952a38012Sejakowatz { 36079c35b39SAxel Dörfler if (IsEnabled() == enabled) 3619cb2dbe2SMarc Flerackers return; 3629cb2dbe2SMarc Flerackers 363058691d4SStefano Ceccherini if (Window()) { 36479c35b39SAxel Dörfler fText->MakeEditable(enabled); 3659cb2dbe2SMarc Flerackers 36679c35b39SAxel Dörfler _UpdateTextViewColors(enabled); 3679cb2dbe2SMarc Flerackers 3689cb2dbe2SMarc Flerackers fText->Invalidate(); 3699cb2dbe2SMarc Flerackers Window()->UpdateIfNeeded(); 3709cb2dbe2SMarc Flerackers } 3719cb2dbe2SMarc Flerackers 37279c35b39SAxel Dörfler BControl::SetEnabled(enabled); 37352a38012Sejakowatz } 374058691d4SStefano Ceccherini 375058691d4SStefano Ceccherini 376058691d4SStefano Ceccherini void 377105644bfSAxel Dörfler BTextControl::GetPreferredSize(float *_width, float *_height) 37852a38012Sejakowatz { 379105644bfSAxel Dörfler if (_height) { 380105644bfSAxel Dörfler // we need enough space for the label and the child text view 381105644bfSAxel Dörfler font_height fontHeight; 382105644bfSAxel Dörfler GetFontHeight(&fontHeight); 383105644bfSAxel Dörfler float labelHeight = ceil(fontHeight.ascent + fontHeight.descent 384105644bfSAxel Dörfler + fontHeight.leading); 385105644bfSAxel Dörfler float textHeight = fText->LineHeight(0) + 4.0; 38652a38012Sejakowatz 387105644bfSAxel Dörfler *_height = max_c(labelHeight, textHeight); 388105644bfSAxel Dörfler } 389105644bfSAxel Dörfler 390105644bfSAxel Dörfler if (_width) { 39152a38012Sejakowatz // TODO: this one I need to find out 392105644bfSAxel Dörfler float width = 20.0f + ceilf(StringWidth(Label())); 393105644bfSAxel Dörfler if (width < Bounds().Width()) 394105644bfSAxel Dörfler width = Bounds().Width(); 395105644bfSAxel Dörfler *_width = width; 396105644bfSAxel Dörfler } 39752a38012Sejakowatz } 398058691d4SStefano Ceccherini 399058691d4SStefano Ceccherini 400058691d4SStefano Ceccherini void 401058691d4SStefano Ceccherini BTextControl::ResizeToPreferred() 40252a38012Sejakowatz { 403105644bfSAxel Dörfler // TODO: change divider? 404105644bfSAxel Dörfler BView::ResizeToPreferred(); 40552a38012Sejakowatz } 406058691d4SStefano Ceccherini 407058691d4SStefano Ceccherini 408058691d4SStefano Ceccherini void 409058691d4SStefano Ceccherini BTextControl::SetFlags(uint32 flags) 41052a38012Sejakowatz { 411058691d4SStefano Ceccherini if (!fSkipSetFlags) { 4129cb2dbe2SMarc Flerackers // If the textview is navigable, set it to not navigable if needed 4139cb2dbe2SMarc Flerackers // Else if it is not navigable, set it to navigable if needed 414058691d4SStefano Ceccherini if (fText->Flags() & B_NAVIGABLE) { 4159cb2dbe2SMarc Flerackers if (!(flags & B_NAVIGABLE)) 4169cb2dbe2SMarc Flerackers fText->SetFlags(fText->Flags() & ~B_NAVIGABLE); 417058691d4SStefano Ceccherini 418058691d4SStefano Ceccherini } else { 4199cb2dbe2SMarc Flerackers if (flags & B_NAVIGABLE) 4209cb2dbe2SMarc Flerackers fText->SetFlags(fText->Flags() | B_NAVIGABLE); 4219cb2dbe2SMarc Flerackers } 4229cb2dbe2SMarc Flerackers 4239cb2dbe2SMarc Flerackers // Don't make this one navigable 4249cb2dbe2SMarc Flerackers flags &= ~B_NAVIGABLE; 4259cb2dbe2SMarc Flerackers } 4269cb2dbe2SMarc Flerackers 42752a38012Sejakowatz BView::SetFlags(flags); 42852a38012Sejakowatz } 429058691d4SStefano Ceccherini 430058691d4SStefano Ceccherini 431058691d4SStefano Ceccherini void 432058691d4SStefano Ceccherini BTextControl::MessageReceived(BMessage *msg) 43352a38012Sejakowatz { 434058691d4SStefano Ceccherini switch(msg->what) { 4359cb2dbe2SMarc Flerackers case B_SET_PROPERTY: 4369cb2dbe2SMarc Flerackers case B_GET_PROPERTY: 4379cb2dbe2SMarc Flerackers // TODO 43852a38012Sejakowatz break; 43952a38012Sejakowatz default: 44052a38012Sejakowatz BControl::MessageReceived(msg); 44152a38012Sejakowatz break; 44252a38012Sejakowatz } 44352a38012Sejakowatz } 444058691d4SStefano Ceccherini 445058691d4SStefano Ceccherini 446058691d4SStefano Ceccherini BHandler * 447058691d4SStefano Ceccherini BTextControl::ResolveSpecifier(BMessage *msg, int32 index, 44852a38012Sejakowatz BMessage *specifier, int32 form, 44952a38012Sejakowatz const char *property) 45052a38012Sejakowatz { 4519cb2dbe2SMarc Flerackers /* 4529cb2dbe2SMarc Flerackers BPropertyInfo propInfo(prop_list); 4539cb2dbe2SMarc Flerackers BHandler *target = NULL; 4549cb2dbe2SMarc Flerackers 4559cb2dbe2SMarc Flerackers if (propInfo.FindMatch(message, 0, specifier, what, property) < B_OK) 4569cb2dbe2SMarc Flerackers return BControl::ResolveSpecifier(message, index, specifier, what, 4579cb2dbe2SMarc Flerackers property); 4589cb2dbe2SMarc Flerackers else 4599cb2dbe2SMarc Flerackers return this; 4609cb2dbe2SMarc Flerackers */ 4619cb2dbe2SMarc Flerackers return BControl::ResolveSpecifier(msg, index, specifier, form, property); 46252a38012Sejakowatz } 463058691d4SStefano Ceccherini 464058691d4SStefano Ceccherini 465058691d4SStefano Ceccherini status_t 466058691d4SStefano Ceccherini BTextControl::GetSupportedSuites(BMessage *data) 46752a38012Sejakowatz { 4689cb2dbe2SMarc Flerackers return BControl::GetSupportedSuites(data); 46952a38012Sejakowatz } 470058691d4SStefano Ceccherini 471058691d4SStefano Ceccherini 472058691d4SStefano Ceccherini void 473058691d4SStefano Ceccherini BTextControl::MouseUp(BPoint pt) 47452a38012Sejakowatz { 47552a38012Sejakowatz BControl::MouseUp(pt); 47652a38012Sejakowatz } 477058691d4SStefano Ceccherini 478058691d4SStefano Ceccherini 479058691d4SStefano Ceccherini void 480058691d4SStefano Ceccherini BTextControl::MouseMoved(BPoint pt, uint32 code, const BMessage *msg) 48152a38012Sejakowatz { 48252a38012Sejakowatz BControl::MouseMoved(pt, code, msg); 48352a38012Sejakowatz } 484058691d4SStefano Ceccherini 485058691d4SStefano Ceccherini 486058691d4SStefano Ceccherini void 487058691d4SStefano Ceccherini BTextControl::DetachedFromWindow() 48852a38012Sejakowatz { 48952a38012Sejakowatz BControl::DetachedFromWindow(); 49052a38012Sejakowatz } 491058691d4SStefano Ceccherini 492058691d4SStefano Ceccherini 493058691d4SStefano Ceccherini void 494058691d4SStefano Ceccherini BTextControl::AllAttached() 49552a38012Sejakowatz { 49652a38012Sejakowatz BControl::AllAttached(); 49752a38012Sejakowatz } 498058691d4SStefano Ceccherini 499058691d4SStefano Ceccherini 500058691d4SStefano Ceccherini void 501058691d4SStefano Ceccherini BTextControl::AllDetached() 50252a38012Sejakowatz { 50352a38012Sejakowatz BControl::AllDetached(); 50452a38012Sejakowatz } 505058691d4SStefano Ceccherini 506058691d4SStefano Ceccherini 507058691d4SStefano Ceccherini void 508058691d4SStefano Ceccherini BTextControl::FrameMoved(BPoint newPosition) 50952a38012Sejakowatz { 51052a38012Sejakowatz BControl::FrameMoved(newPosition); 51152a38012Sejakowatz } 512058691d4SStefano Ceccherini 513058691d4SStefano Ceccherini 514058691d4SStefano Ceccherini void 515ffe72abdSAxel Dörfler BTextControl::FrameResized(float width, float height) 51652a38012Sejakowatz { 517ffe72abdSAxel Dörfler BControl::FrameResized(width, height); 518ffe72abdSAxel Dörfler 519ffe72abdSAxel Dörfler // changes in width 520ffe72abdSAxel Dörfler 521ffe72abdSAxel Dörfler BRect bounds = Bounds(); 522ffe72abdSAxel Dörfler const float border = 2.0f; 523ffe72abdSAxel Dörfler 524ffe72abdSAxel Dörfler if (bounds.Width() > fPreviousWidth) { 525ffe72abdSAxel Dörfler // invalidate the region between the old and the new right border 526ffe72abdSAxel Dörfler BRect rect = bounds; 527ffe72abdSAxel Dörfler rect.left += fPreviousWidth - border; 528ffe72abdSAxel Dörfler rect.right--; 529ffe72abdSAxel Dörfler Invalidate(rect); 530ffe72abdSAxel Dörfler } else if (bounds.Width() < fPreviousWidth) { 531ffe72abdSAxel Dörfler // invalidate the region of the new right border 532ffe72abdSAxel Dörfler BRect rect = bounds; 533ffe72abdSAxel Dörfler rect.left = rect.right - border; 534ffe72abdSAxel Dörfler Invalidate(rect); 535ffe72abdSAxel Dörfler } 536ffe72abdSAxel Dörfler 537ffe72abdSAxel Dörfler // changes in height 538ffe72abdSAxel Dörfler 539ffe72abdSAxel Dörfler if (bounds.Height() > fPreviousHeight) { 540ffe72abdSAxel Dörfler // invalidate the region between the old and the new bottom border 541ffe72abdSAxel Dörfler BRect rect = bounds; 542ffe72abdSAxel Dörfler rect.top += fPreviousHeight - border; 543ffe72abdSAxel Dörfler rect.bottom--; 544ffe72abdSAxel Dörfler Invalidate(rect); 545ffe72abdSAxel Dörfler } else if (bounds.Height() < fPreviousHeight) { 546ffe72abdSAxel Dörfler // invalidate the region of the new bottom border 547ffe72abdSAxel Dörfler BRect rect = bounds; 548ffe72abdSAxel Dörfler rect.top = rect.bottom - border; 549ffe72abdSAxel Dörfler Invalidate(rect); 550ffe72abdSAxel Dörfler } 551ffe72abdSAxel Dörfler 552ffe72abdSAxel Dörfler fPreviousWidth = uint16(bounds.Width()); 553ffe72abdSAxel Dörfler fPreviousHeight = uint16(bounds.Height()); 55452a38012Sejakowatz } 555058691d4SStefano Ceccherini 556058691d4SStefano Ceccherini 557058691d4SStefano Ceccherini void 558058691d4SStefano Ceccherini BTextControl::WindowActivated(bool active) 55952a38012Sejakowatz { 5606d8d6cadSStephan Aßmus if (fText->IsFocus()) { 561dde10e45SStephan Aßmus // invalidate to remove/show focus indication 562dde10e45SStephan Aßmus BRect rect = Bounds(); 563dde10e45SStephan Aßmus rect.left = fDivider; 5646d8d6cadSStephan Aßmus Invalidate(rect); 565dde10e45SStephan Aßmus 566dde10e45SStephan Aßmus // help out embedded text view which doesn't 567dde10e45SStephan Aßmus // get notified of this 568dde10e45SStephan Aßmus fText->Invalidate(); 5696d8d6cadSStephan Aßmus } 57052a38012Sejakowatz } 571058691d4SStefano Ceccherini 572058691d4SStefano Ceccherini 573058691d4SStefano Ceccherini status_t 574058691d4SStefano Ceccherini BTextControl::Perform(perform_code d, void *arg) 57552a38012Sejakowatz { 57652a38012Sejakowatz return BControl::Perform(d, arg); 57752a38012Sejakowatz } 578058691d4SStefano Ceccherini 579058691d4SStefano Ceccherini 5809cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl1() {} 5819cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl2() {} 5829cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl3() {} 5839cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl4() {} 584058691d4SStefano Ceccherini 585058691d4SStefano Ceccherini 586058691d4SStefano Ceccherini BTextControl & 587058691d4SStefano Ceccherini BTextControl::operator=(const BTextControl&) 58852a38012Sejakowatz { 58952a38012Sejakowatz return *this; 59052a38012Sejakowatz } 591058691d4SStefano Ceccherini 592058691d4SStefano Ceccherini 593058691d4SStefano Ceccherini void 59479c35b39SAxel Dörfler BTextControl::_UpdateTextViewColors(bool enabled) 5953a3f6c1eSAxel Dörfler { 5963a3f6c1eSAxel Dörfler rgb_color textColor; 597aae7000dSAxel Dörfler rgb_color color; 5983a3f6c1eSAxel Dörfler BFont font; 5993a3f6c1eSAxel Dörfler 600aae7000dSAxel Dörfler fText->GetFontAndColor(0, &font); 6013a3f6c1eSAxel Dörfler 6023a3f6c1eSAxel Dörfler if (enabled) 603aae7000dSAxel Dörfler textColor = ui_color(B_DOCUMENT_TEXT_COLOR); 60412aefeb4SAxel Dörfler else { 60512aefeb4SAxel Dörfler textColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 60612aefeb4SAxel Dörfler B_DISABLED_LABEL_TINT); 60712aefeb4SAxel Dörfler } 6083a3f6c1eSAxel Dörfler 6093a3f6c1eSAxel Dörfler fText->SetFontAndColor(&font, B_FONT_ALL, &textColor); 6103a3f6c1eSAxel Dörfler 6113a3f6c1eSAxel Dörfler if (enabled) { 612aae7000dSAxel Dörfler color = ui_color(B_DOCUMENT_BACKGROUND_COLOR); 6133a3f6c1eSAxel Dörfler } else { 6143a3f6c1eSAxel Dörfler color = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 6153a3f6c1eSAxel Dörfler B_LIGHTEN_2_TINT); 6163a3f6c1eSAxel Dörfler } 6173a3f6c1eSAxel Dörfler 6183a3f6c1eSAxel Dörfler fText->SetViewColor(color); 6193a3f6c1eSAxel Dörfler fText->SetLowColor(color); 6203a3f6c1eSAxel Dörfler } 6213a3f6c1eSAxel Dörfler 6223a3f6c1eSAxel Dörfler 6233a3f6c1eSAxel Dörfler void 624ffe72abdSAxel Dörfler BTextControl::_CommitValue() 6259cb2dbe2SMarc Flerackers { 6269cb2dbe2SMarc Flerackers } 627058691d4SStefano Ceccherini 628058691d4SStefano Ceccherini 629058691d4SStefano Ceccherini void 630ffe72abdSAxel Dörfler BTextControl::_InitData(const char* label, const char* initialText, 631ffe72abdSAxel Dörfler BMessage* archive) 6329cb2dbe2SMarc Flerackers { 6339cb2dbe2SMarc Flerackers BRect bounds(Bounds()); 6349cb2dbe2SMarc Flerackers 6359cb2dbe2SMarc Flerackers fText = NULL; 6369cb2dbe2SMarc Flerackers fModificationMessage = NULL; 6379cb2dbe2SMarc Flerackers fLabelAlign = B_ALIGN_LEFT; 6389cb2dbe2SMarc Flerackers fDivider = 0.0f; 639ffe72abdSAxel Dörfler fPreviousWidth = bounds.Width(); 640ffe72abdSAxel Dörfler fPreviousHeight = bounds.Height(); 6419cb2dbe2SMarc Flerackers fSkipSetFlags = false; 6429cb2dbe2SMarc Flerackers 6439cb2dbe2SMarc Flerackers int32 flags = 0; 6449cb2dbe2SMarc Flerackers 645918a22d9SDarkWyrm BFont font(be_plain_font); 6469cb2dbe2SMarc Flerackers 647ffe72abdSAxel Dörfler if (!archive || !archive->HasString("_fname")) 648058691d4SStefano Ceccherini flags |= B_FONT_FAMILY_AND_STYLE; 6499cb2dbe2SMarc Flerackers 650ffe72abdSAxel Dörfler if (!archive || !archive->HasFloat("_fflt")) 651058691d4SStefano Ceccherini flags |= B_FONT_SIZE; 6529cb2dbe2SMarc Flerackers 6539cb2dbe2SMarc Flerackers if (flags != 0) 6549cb2dbe2SMarc Flerackers SetFont(&font, flags); 6559cb2dbe2SMarc Flerackers 6569cb2dbe2SMarc Flerackers if (label) 6572e6a5805SStephan Aßmus fDivider = floorf(bounds.Width() / 2.0f); 6589cb2dbe2SMarc Flerackers 659105644bfSAxel Dörfler uint32 navigableFlags = Flags() & B_NAVIGABLE; 660105644bfSAxel Dörfler if (navigableFlags != 0) { 6619cb2dbe2SMarc Flerackers fSkipSetFlags = true; 6629cb2dbe2SMarc Flerackers SetFlags(Flags() & ~B_NAVIGABLE); 6639cb2dbe2SMarc Flerackers fSkipSetFlags = false; 6649cb2dbe2SMarc Flerackers } 6659cb2dbe2SMarc Flerackers 666ffe72abdSAxel Dörfler if (archive) 667058691d4SStefano Ceccherini fText = static_cast<_BTextInput_ *>(FindView("_input_")); 668058691d4SStefano Ceccherini else { 6692e6a5805SStephan Aßmus BRect frame(fDivider, bounds.top, 6702e6a5805SStephan Aßmus bounds.right, bounds.bottom); 671105644bfSAxel Dörfler // we are stroking the frame around the text view, which 6722e6a5805SStephan Aßmus // is 2 pixels wide 673455d1c46SAxel Dörfler frame.InsetBy(4.0, 3.0); 674111b4fbcSStefano Ceccherini BRect textRect(frame.OffsetToCopy(B_ORIGIN)); 6759cb2dbe2SMarc Flerackers 6769cb2dbe2SMarc Flerackers fText = new _BTextInput_(frame, textRect, 6777a70a2d6SStephan Aßmus B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, 678105644bfSAxel Dörfler B_WILL_DRAW | B_FRAME_EVENTS | navigableFlags); 6799cb2dbe2SMarc Flerackers AddChild(fText); 6809cb2dbe2SMarc Flerackers 681455d1c46SAxel Dörfler SetText(initialText); 6829cb2dbe2SMarc Flerackers fText->SetAlignment(B_ALIGN_LEFT); 6839cb2dbe2SMarc Flerackers fText->AlignTextRect(); 6849cb2dbe2SMarc Flerackers } 6859cb2dbe2SMarc Flerackers } 686