1105644bfSAxel Dörfler /* 2*d9385a9dSJohn Scipione * Copyright 2001-2020 Haiku Inc. All rights reserved. 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> 89ecf9d1cSIngo Weinhold * Ingo Weinhold <bonefish@cs.tu-berlin.de> 9*d9385a9dSJohn Scipione * John Scipione <jscipione@gmail.com> 10105644bfSAxel Dörfler */ 11105644bfSAxel Dörfler 1209d87d91SAxel Dörfler 13991c062fSAxel Dörfler /*! BTextControl displays text that can act like a control. */ 14105644bfSAxel Dörfler 15c121b41fSRene Gollent 162f86ba45SStephan Aßmus #include <TextControl.h> 17105644bfSAxel Dörfler 1809d87d91SAxel Dörfler #include <string.h> 1909d87d91SAxel Dörfler 209ecf9d1cSIngo Weinhold #include <AbstractLayoutItem.h> 212f86ba45SStephan Aßmus #include <ControlLook.h> 229ecf9d1cSIngo Weinhold #include <LayoutUtils.h> 23058691d4SStefano Ceccherini #include <Message.h> 242a30a9e9SRene Gollent #include <PropertyInfo.h> 25455d1c46SAxel Dörfler #include <Region.h> 2652a38012Sejakowatz #include <Window.h> 2752a38012Sejakowatz 2839fbf550SOliver Tappe #include <binary_compatibility/Interface.h> 295c47e35eSAlex Wilson #include <binary_compatibility/Support.h> 3039fbf550SOliver Tappe 3152a38012Sejakowatz #include "TextInput.h" 3252a38012Sejakowatz 3352a38012Sejakowatz 3493ba577cSStephan Aßmus //#define TRACE_TEXT_CONTROL 3593ba577cSStephan Aßmus #ifdef TRACE_TEXT_CONTROL 3673161598SJérôme Duval # include <stdio.h> 3793ba577cSStephan Aßmus # include <FunctionTracer.h> 3893ba577cSStephan Aßmus static int32 sFunctionDepth = -1; 39349c911eSStephan Aßmus # define CALLED(x...) FunctionTracer _ft("BTextControl", __FUNCTION__, \ 4093ba577cSStephan Aßmus sFunctionDepth) 4193ba577cSStephan Aßmus # define TRACE(x...) { BString _to; \ 4293ba577cSStephan Aßmus _to.Append(' ', (sFunctionDepth + 1) * 2); \ 4393ba577cSStephan Aßmus printf("%s", _to.String()); printf(x); } 4493ba577cSStephan Aßmus #else 4593ba577cSStephan Aßmus # define CALLED(x...) 4693ba577cSStephan Aßmus # define TRACE(x...) 4793ba577cSStephan Aßmus #endif 4893ba577cSStephan Aßmus 4993ba577cSStephan Aßmus 505c47e35eSAlex Wilson namespace { 515c47e35eSAlex Wilson const char* const kFrameField = "BTextControl:layoutitem:frame"; 525c47e35eSAlex Wilson const char* const kTextViewItemField = "BTextControl:textViewItem"; 535c47e35eSAlex Wilson const char* const kLabelItemField = "BMenuField:labelItem"; 545c47e35eSAlex Wilson } 555c47e35eSAlex Wilson 565c47e35eSAlex Wilson 572a30a9e9SRene Gollent static property_info sPropertyList[] = { 582a30a9e9SRene Gollent { 592a30a9e9SRene Gollent "Value", 602a30a9e9SRene Gollent { B_GET_PROPERTY, B_SET_PROPERTY }, 612a30a9e9SRene Gollent { B_DIRECT_SPECIFIER }, 622a30a9e9SRene Gollent NULL, 0, 632a30a9e9SRene Gollent { B_STRING_TYPE } 642a30a9e9SRene Gollent }, 65346d1496SHumdinger 66346d1496SHumdinger { 0 } 672a30a9e9SRene Gollent }; 682a30a9e9SRene Gollent 692a30a9e9SRene Gollent 709ecf9d1cSIngo Weinhold class BTextControl::LabelLayoutItem : public BAbstractLayoutItem { 719ecf9d1cSIngo Weinhold public: 729ecf9d1cSIngo Weinhold LabelLayoutItem(BTextControl* parent); 735c47e35eSAlex Wilson LabelLayoutItem(BMessage* from); 749ecf9d1cSIngo Weinhold 759ecf9d1cSIngo Weinhold virtual bool IsVisible(); 769ecf9d1cSIngo Weinhold virtual void SetVisible(bool visible); 779ecf9d1cSIngo Weinhold 789ecf9d1cSIngo Weinhold virtual BRect Frame(); 799ecf9d1cSIngo Weinhold virtual void SetFrame(BRect frame); 809ecf9d1cSIngo Weinhold 815c47e35eSAlex Wilson void SetParent(BTextControl* parent); 829ecf9d1cSIngo Weinhold virtual BView* View(); 839ecf9d1cSIngo Weinhold 849ecf9d1cSIngo Weinhold virtual BSize BaseMinSize(); 859ecf9d1cSIngo Weinhold virtual BSize BaseMaxSize(); 869ecf9d1cSIngo Weinhold virtual BSize BasePreferredSize(); 879ecf9d1cSIngo Weinhold virtual BAlignment BaseAlignment(); 889ecf9d1cSIngo Weinhold 8909d87d91SAxel Dörfler BRect FrameInParent() const; 9009d87d91SAxel Dörfler 915c47e35eSAlex Wilson virtual status_t Archive(BMessage* into, bool deep = true) const; 925c47e35eSAlex Wilson static BArchivable* Instantiate(BMessage* from); 9309d87d91SAxel Dörfler 949ecf9d1cSIngo Weinhold private: 959ecf9d1cSIngo Weinhold BTextControl* fParent; 969ecf9d1cSIngo Weinhold BRect fFrame; 979ecf9d1cSIngo Weinhold }; 989ecf9d1cSIngo Weinhold 999ecf9d1cSIngo Weinhold 1009ecf9d1cSIngo Weinhold class BTextControl::TextViewLayoutItem : public BAbstractLayoutItem { 1019ecf9d1cSIngo Weinhold public: 1029ecf9d1cSIngo Weinhold TextViewLayoutItem(BTextControl* parent); 1035c47e35eSAlex Wilson TextViewLayoutItem(BMessage* from); 1049ecf9d1cSIngo Weinhold 1059ecf9d1cSIngo Weinhold virtual bool IsVisible(); 1069ecf9d1cSIngo Weinhold virtual void SetVisible(bool visible); 1079ecf9d1cSIngo Weinhold 1089ecf9d1cSIngo Weinhold virtual BRect Frame(); 1099ecf9d1cSIngo Weinhold virtual void SetFrame(BRect frame); 1109ecf9d1cSIngo Weinhold 1115c47e35eSAlex Wilson void SetParent(BTextControl* parent); 1129ecf9d1cSIngo Weinhold virtual BView* View(); 1139ecf9d1cSIngo Weinhold 1149ecf9d1cSIngo Weinhold virtual BSize BaseMinSize(); 1159ecf9d1cSIngo Weinhold virtual BSize BaseMaxSize(); 1169ecf9d1cSIngo Weinhold virtual BSize BasePreferredSize(); 1179ecf9d1cSIngo Weinhold virtual BAlignment BaseAlignment(); 1189ecf9d1cSIngo Weinhold 11909d87d91SAxel Dörfler BRect FrameInParent() const; 12009d87d91SAxel Dörfler 1215c47e35eSAlex Wilson virtual status_t Archive(BMessage* into, bool deep = true) const; 1225c47e35eSAlex Wilson static BArchivable* Instantiate(BMessage* from); 1239ecf9d1cSIngo Weinhold private: 1249ecf9d1cSIngo Weinhold BTextControl* fParent; 1259ecf9d1cSIngo Weinhold BRect fFrame; 1269ecf9d1cSIngo Weinhold }; 1279ecf9d1cSIngo Weinhold 1289ecf9d1cSIngo Weinhold 129349c911eSStephan Aßmus struct BTextControl::LayoutData { 130349c911eSStephan Aßmus LayoutData(float width, float height) 1315c47e35eSAlex Wilson : 1325c47e35eSAlex Wilson label_layout_item(NULL), 133349c911eSStephan Aßmus text_view_layout_item(NULL), 134349c911eSStephan Aßmus previous_width(width), 135349c911eSStephan Aßmus previous_height(height), 136349c911eSStephan Aßmus valid(false) 137349c911eSStephan Aßmus { 138349c911eSStephan Aßmus } 139349c911eSStephan Aßmus 140349c911eSStephan Aßmus LabelLayoutItem* label_layout_item; 141349c911eSStephan Aßmus TextViewLayoutItem* text_view_layout_item; 142349c911eSStephan Aßmus float previous_width; // used in FrameResized() for 143349c911eSStephan Aßmus float previous_height; // invalidation 144349c911eSStephan Aßmus font_height font_info; 145349c911eSStephan Aßmus float label_width; 146349c911eSStephan Aßmus float label_height; 147349c911eSStephan Aßmus BSize min; 148349c911eSStephan Aßmus BSize text_view_min; 149349c911eSStephan Aßmus bool valid; 150349c911eSStephan Aßmus }; 151349c911eSStephan Aßmus 152349c911eSStephan Aßmus 153349c911eSStephan Aßmus static const int32 kFrameMargin = 2; 154349c911eSStephan Aßmus static const int32 kLabelInputSpacing = 3; 155349c911eSStephan Aßmus 156349c911eSStephan Aßmus 157b11edca4SJohn Scipione // #pragma mark - BTextControl 158b11edca4SJohn Scipione 159b11edca4SJohn Scipione 16052a38012Sejakowatz BTextControl::BTextControl(BRect frame, const char* name, const char* label, 161f4664459SJohn Scipione const char* text, BMessage* message, uint32 resizeMask, uint32 flags) 1625c47e35eSAlex Wilson : 163f4664459SJohn Scipione BControl(frame, name, label, message, resizeMask, flags | B_FRAME_EVENTS) 16452a38012Sejakowatz { 1655c47e35eSAlex Wilson _InitData(label); 1665c47e35eSAlex Wilson _InitText(text); 1679ecf9d1cSIngo Weinhold _ValidateLayout(); 1689ecf9d1cSIngo Weinhold } 16952a38012Sejakowatz 170105644bfSAxel Dörfler 1719ecf9d1cSIngo Weinhold BTextControl::BTextControl(const char* name, const char* label, 172991c062fSAxel Dörfler const char* text, BMessage* message, uint32 flags) 1735c47e35eSAlex Wilson : 1745c47e35eSAlex Wilson BControl(name, label, message, flags | B_FRAME_EVENTS) 1759ecf9d1cSIngo Weinhold { 1765c47e35eSAlex Wilson _InitData(label); 1775c47e35eSAlex Wilson _InitText(text); 1789ecf9d1cSIngo Weinhold _ValidateLayout(); 1799ecf9d1cSIngo Weinhold } 180105644bfSAxel Dörfler 181ffe72abdSAxel Dörfler 182991c062fSAxel Dörfler BTextControl::BTextControl(const char* label, const char* text, 183991c062fSAxel Dörfler BMessage* message) 1845c47e35eSAlex Wilson : 1855c47e35eSAlex Wilson BControl(NULL, label, message, 18693ba577cSStephan Aßmus B_WILL_DRAW | B_NAVIGABLE | B_FRAME_EVENTS) 1879ecf9d1cSIngo Weinhold { 1885c47e35eSAlex Wilson _InitData(label); 1895c47e35eSAlex Wilson _InitText(text); 1909ecf9d1cSIngo Weinhold _ValidateLayout(); 19152a38012Sejakowatz } 192058691d4SStefano Ceccherini 193058691d4SStefano Ceccherini 19452a38012Sejakowatz BTextControl::~BTextControl() 19552a38012Sejakowatz { 1969cb2dbe2SMarc Flerackers SetModificationMessage(NULL); 19753aaed9fSStephan Aßmus delete fLayoutData; 19852a38012Sejakowatz } 199058691d4SStefano Ceccherini 200058691d4SStefano Ceccherini 201f4664459SJohn Scipione // #pragma mark - Archiving 202f4664459SJohn Scipione 203f4664459SJohn Scipione 204ffe72abdSAxel Dörfler BTextControl::BTextControl(BMessage* archive) 2055c47e35eSAlex Wilson : 2065c47e35eSAlex Wilson BControl(BUnarchiver::PrepareArchive(archive)) 20752a38012Sejakowatz { 2085c47e35eSAlex Wilson BUnarchiver unarchiver(archive); 20952a38012Sejakowatz 2105c47e35eSAlex Wilson _InitData(Label(), archive); 21152a38012Sejakowatz 2125c47e35eSAlex Wilson if (!BUnarchiver::IsArchiveManaged(archive)) 2135c47e35eSAlex Wilson _InitText(NULL, archive); 21452a38012Sejakowatz 2155c47e35eSAlex Wilson status_t err = B_OK; 216ffe72abdSAxel Dörfler if (archive->HasFloat("_divide")) 2175c47e35eSAlex Wilson err = archive->FindFloat("_divide", &fDivider); 2189cb2dbe2SMarc Flerackers 2195c47e35eSAlex Wilson if (err == B_OK && archive->HasMessage("_mod_msg")) { 220ffe72abdSAxel Dörfler BMessage* message = new BMessage; 2215c47e35eSAlex Wilson err = archive->FindMessage("_mod_msg", message); 222ffe72abdSAxel Dörfler SetModificationMessage(message); 2239cb2dbe2SMarc Flerackers } 2245c47e35eSAlex Wilson 2255c47e35eSAlex Wilson unarchiver.Finish(err); 22652a38012Sejakowatz } 227058691d4SStefano Ceccherini 228058691d4SStefano Ceccherini 229058691d4SStefano Ceccherini BArchivable* 230058691d4SStefano Ceccherini BTextControl::Instantiate(BMessage* archive) 23152a38012Sejakowatz { 2329cb2dbe2SMarc Flerackers if (validate_instantiation(archive, "BTextControl")) 2339cb2dbe2SMarc Flerackers return new BTextControl(archive); 234991c062fSAxel Dörfler 23552a38012Sejakowatz return NULL; 23652a38012Sejakowatz } 237058691d4SStefano Ceccherini 238058691d4SStefano Ceccherini 239058691d4SStefano Ceccherini status_t 240058691d4SStefano Ceccherini BTextControl::Archive(BMessage* data, bool deep) const 24152a38012Sejakowatz { 2425c47e35eSAlex Wilson BArchiver archiver(data); 243f4664459SJohn Scipione status_t result = BControl::Archive(data, deep); 24452a38012Sejakowatz 245f4664459SJohn Scipione alignment labelAlignment; 246f4664459SJohn Scipione alignment textAlignment; 247f4664459SJohn Scipione if (result == B_OK) 248058691d4SStefano Ceccherini GetAlignment(&labelAlignment, &textAlignment); 2499cb2dbe2SMarc Flerackers 250f4664459SJohn Scipione if (result == B_OK) 251f4664459SJohn Scipione result = data->AddInt32("_a_label", labelAlignment); 2529cb2dbe2SMarc Flerackers 253f4664459SJohn Scipione if (result == B_OK) 254f4664459SJohn Scipione result = data->AddInt32("_a_text", textAlignment); 2559cb2dbe2SMarc Flerackers 256f4664459SJohn Scipione if (result == B_OK) 257f4664459SJohn Scipione result = data->AddFloat("_divide", Divider()); 258f4664459SJohn Scipione 259f4664459SJohn Scipione if (result == B_OK && ModificationMessage() != NULL) 260f4664459SJohn Scipione result = data->AddMessage("_mod_msg", ModificationMessage()); 261f4664459SJohn Scipione 262f4664459SJohn Scipione return archiver.Finish(result); 2635c47e35eSAlex Wilson } 2645c47e35eSAlex Wilson 2655c47e35eSAlex Wilson 2665c47e35eSAlex Wilson status_t 2675c47e35eSAlex Wilson BTextControl::AllArchived(BMessage* into) const 2685c47e35eSAlex Wilson { 2695c47e35eSAlex Wilson BArchiver archiver(into); 2705c47e35eSAlex Wilson status_t err = B_OK; 2715c47e35eSAlex Wilson 2725c47e35eSAlex Wilson if (archiver.IsArchived(fLayoutData->text_view_layout_item)) { 2735c47e35eSAlex Wilson err = archiver.AddArchivable(kTextViewItemField, 2745c47e35eSAlex Wilson fLayoutData->text_view_layout_item); 2755c47e35eSAlex Wilson } 2765c47e35eSAlex Wilson 2775c47e35eSAlex Wilson if (err == B_OK && archiver.IsArchived(fLayoutData->label_layout_item)) { 2785c47e35eSAlex Wilson err = archiver.AddArchivable(kLabelItemField, 2795c47e35eSAlex Wilson fLayoutData->label_layout_item); 2805c47e35eSAlex Wilson } 2815c47e35eSAlex Wilson 2825c47e35eSAlex Wilson return err; 2835c47e35eSAlex Wilson } 2845c47e35eSAlex Wilson 2855c47e35eSAlex Wilson 2865c47e35eSAlex Wilson status_t 2875c47e35eSAlex Wilson BTextControl::AllUnarchived(const BMessage* from) 2885c47e35eSAlex Wilson { 2895c47e35eSAlex Wilson status_t err; 2905c47e35eSAlex Wilson if ((err = BControl::AllUnarchived(from)) != B_OK) 2915c47e35eSAlex Wilson return err; 2925c47e35eSAlex Wilson 2935c47e35eSAlex Wilson _InitText(NULL, from); 2945c47e35eSAlex Wilson 2955c47e35eSAlex Wilson BUnarchiver unarchiver(from); 2965c47e35eSAlex Wilson if (unarchiver.IsInstantiated(kTextViewItemField)) { 2975c47e35eSAlex Wilson err = unarchiver.FindObject(kTextViewItemField, 2985c47e35eSAlex Wilson BUnarchiver::B_DONT_ASSUME_OWNERSHIP, 2995c47e35eSAlex Wilson fLayoutData->text_view_layout_item); 3005c47e35eSAlex Wilson 3015c47e35eSAlex Wilson if (err == B_OK) 3025c47e35eSAlex Wilson fLayoutData->text_view_layout_item->SetParent(this); 3035c47e35eSAlex Wilson else 3045c47e35eSAlex Wilson return err; 3055c47e35eSAlex Wilson } 3065c47e35eSAlex Wilson 3075c47e35eSAlex Wilson if (unarchiver.IsInstantiated(kLabelItemField)) { 3085c47e35eSAlex Wilson err = unarchiver.FindObject(kLabelItemField, 3095c47e35eSAlex Wilson BUnarchiver::B_DONT_ASSUME_OWNERSHIP, 3105c47e35eSAlex Wilson fLayoutData->label_layout_item); 3115c47e35eSAlex Wilson 3125c47e35eSAlex Wilson if (err == B_OK) 3135c47e35eSAlex Wilson fLayoutData->label_layout_item->SetParent(this); 3145c47e35eSAlex Wilson } 3155c47e35eSAlex Wilson return err; 31652a38012Sejakowatz } 317058691d4SStefano Ceccherini 318058691d4SStefano Ceccherini 319f4664459SJohn Scipione // #pragma mark - Hook methods 320f4664459SJohn Scipione 321f4664459SJohn Scipione 322058691d4SStefano Ceccherini void 323f4664459SJohn Scipione BTextControl::AllAttached() 32452a38012Sejakowatz { 325f4664459SJohn Scipione BControl::AllAttached(); 32652a38012Sejakowatz } 327058691d4SStefano Ceccherini 328058691d4SStefano Ceccherini 329058691d4SStefano Ceccherini void 330f4664459SJohn Scipione BTextControl::AllDetached() 33113d147b1SAdrien Destugues { 332f4664459SJohn Scipione BControl::AllDetached(); 33352a38012Sejakowatz } 334058691d4SStefano Ceccherini 335058691d4SStefano Ceccherini 336058691d4SStefano Ceccherini void 337058691d4SStefano Ceccherini BTextControl::AttachedToWindow() 33852a38012Sejakowatz { 33952a38012Sejakowatz BControl::AttachedToWindow(); 34052a38012Sejakowatz 34179c35b39SAxel Dörfler _UpdateTextViewColors(IsEnabled()); 3423a3f6c1eSAxel Dörfler fText->MakeEditable(IsEnabled()); 34352a38012Sejakowatz } 344058691d4SStefano Ceccherini 345058691d4SStefano Ceccherini 346058691d4SStefano Ceccherini void 347058691d4SStefano Ceccherini BTextControl::DetachedFromWindow() 34852a38012Sejakowatz { 34952a38012Sejakowatz BControl::DetachedFromWindow(); 35052a38012Sejakowatz } 351058691d4SStefano Ceccherini 352058691d4SStefano Ceccherini 353058691d4SStefano Ceccherini void 354f4664459SJohn Scipione BTextControl::Draw(BRect updateRect) 35552a38012Sejakowatz { 356f4664459SJohn Scipione bool enabled = IsEnabled(); 357f4664459SJohn Scipione bool active = fText->IsFocus() && Window()->IsActive(); 358f4664459SJohn Scipione 359f4664459SJohn Scipione BRect rect = fText->Frame(); 360f4664459SJohn Scipione rect.InsetBy(-2, -2); 361f4664459SJohn Scipione 3627a96554cSlooncraz rgb_color base = ViewColor(); 363f4664459SJohn Scipione uint32 flags = fLook; 364f4664459SJohn Scipione if (!enabled) 365f4664459SJohn Scipione flags |= BControlLook::B_DISABLED; 366f4664459SJohn Scipione 367f4664459SJohn Scipione if (active) 368f4664459SJohn Scipione flags |= BControlLook::B_FOCUSED; 369f4664459SJohn Scipione 370f4664459SJohn Scipione be_control_look->DrawTextControlBorder(this, rect, updateRect, base, 371f4664459SJohn Scipione flags); 372f4664459SJohn Scipione 373f4664459SJohn Scipione if (Label() != NULL) { 374f4664459SJohn Scipione if (fLayoutData->label_layout_item != NULL) { 375f4664459SJohn Scipione rect = fLayoutData->label_layout_item->FrameInParent(); 376f4664459SJohn Scipione } else { 377f4664459SJohn Scipione rect = Bounds(); 378f4664459SJohn Scipione rect.right = fDivider - kLabelInputSpacing; 37952a38012Sejakowatz } 380058691d4SStefano Ceccherini 3818b902d94SJohn Scipione // erase the is control flag before drawing the label so that the label 3828b902d94SJohn Scipione // will get drawn using B_PANEL_TEXT_COLOR 3838b902d94SJohn Scipione flags &= ~BControlLook::B_IS_CONTROL; 3848b902d94SJohn Scipione 385f4664459SJohn Scipione be_control_look->DrawLabel(this, Label(), rect, updateRect, 386f4664459SJohn Scipione base, flags, BAlignment(fLabelAlign, B_ALIGN_MIDDLE)); 387f4664459SJohn Scipione } 38852a38012Sejakowatz } 389058691d4SStefano Ceccherini 390058691d4SStefano Ceccherini 391058691d4SStefano Ceccherini void 392058691d4SStefano Ceccherini BTextControl::FrameMoved(BPoint newPosition) 39352a38012Sejakowatz { 39452a38012Sejakowatz BControl::FrameMoved(newPosition); 39552a38012Sejakowatz } 396058691d4SStefano Ceccherini 397058691d4SStefano Ceccherini 398058691d4SStefano Ceccherini void 399ffe72abdSAxel Dörfler BTextControl::FrameResized(float width, float height) 40052a38012Sejakowatz { 40193ba577cSStephan Aßmus CALLED(); 40293ba577cSStephan Aßmus 403ffe72abdSAxel Dörfler BControl::FrameResized(width, height); 404ffe72abdSAxel Dörfler 405349c911eSStephan Aßmus // TODO: this causes flickering still... 406349c911eSStephan Aßmus 407ffe72abdSAxel Dörfler // changes in width 408ffe72abdSAxel Dörfler 409ffe72abdSAxel Dörfler BRect bounds = Bounds(); 410ffe72abdSAxel Dörfler 411349c911eSStephan Aßmus if (bounds.Width() > fLayoutData->previous_width) { 412ffe72abdSAxel Dörfler // invalidate the region between the old and the new right border 413ffe72abdSAxel Dörfler BRect rect = bounds; 414349c911eSStephan Aßmus rect.left += fLayoutData->previous_width - kFrameMargin; 415ffe72abdSAxel Dörfler rect.right--; 416ffe72abdSAxel Dörfler Invalidate(rect); 417349c911eSStephan Aßmus } else if (bounds.Width() < fLayoutData->previous_width) { 418ffe72abdSAxel Dörfler // invalidate the region of the new right border 419ffe72abdSAxel Dörfler BRect rect = bounds; 420349c911eSStephan Aßmus rect.left = rect.right - kFrameMargin; 421ffe72abdSAxel Dörfler Invalidate(rect); 422ffe72abdSAxel Dörfler } 423ffe72abdSAxel Dörfler 424ffe72abdSAxel Dörfler // changes in height 425ffe72abdSAxel Dörfler 426349c911eSStephan Aßmus if (bounds.Height() > fLayoutData->previous_height) { 427ffe72abdSAxel Dörfler // invalidate the region between the old and the new bottom border 428ffe72abdSAxel Dörfler BRect rect = bounds; 429349c911eSStephan Aßmus rect.top += fLayoutData->previous_height - kFrameMargin; 430ffe72abdSAxel Dörfler rect.bottom--; 431ffe72abdSAxel Dörfler Invalidate(rect); 432349c911eSStephan Aßmus // invalidate label area 433349c911eSStephan Aßmus rect = bounds; 434349c911eSStephan Aßmus rect.right = fDivider; 435349c911eSStephan Aßmus Invalidate(rect); 436349c911eSStephan Aßmus } else if (bounds.Height() < fLayoutData->previous_height) { 437ffe72abdSAxel Dörfler // invalidate the region of the new bottom border 438ffe72abdSAxel Dörfler BRect rect = bounds; 439349c911eSStephan Aßmus rect.top = rect.bottom - kFrameMargin; 440349c911eSStephan Aßmus Invalidate(rect); 441349c911eSStephan Aßmus // invalidate label area 442349c911eSStephan Aßmus rect = bounds; 443349c911eSStephan Aßmus rect.right = fDivider; 444ffe72abdSAxel Dörfler Invalidate(rect); 445ffe72abdSAxel Dörfler } 446ffe72abdSAxel Dörfler 447349c911eSStephan Aßmus fLayoutData->previous_width = bounds.Width(); 448349c911eSStephan Aßmus fLayoutData->previous_height = bounds.Height(); 44993ba577cSStephan Aßmus 45093ba577cSStephan Aßmus TRACE("width: %.2f, height: %.2f\n", bounds.Width(), bounds.Height()); 45152a38012Sejakowatz } 452058691d4SStefano Ceccherini 453058691d4SStefano Ceccherini 454f4664459SJohn Scipione status_t 455f4664459SJohn Scipione BTextControl::Invoke(BMessage* message) 456f4664459SJohn Scipione { 457f4664459SJohn Scipione return BControl::Invoke(message); 458f4664459SJohn Scipione } 459f4664459SJohn Scipione 460f4664459SJohn Scipione 461f4664459SJohn Scipione void 462f4664459SJohn Scipione BTextControl::LayoutInvalidated(bool descendants) 463f4664459SJohn Scipione { 464f4664459SJohn Scipione CALLED(); 465f4664459SJohn Scipione 466f4664459SJohn Scipione fLayoutData->valid = false; 467f4664459SJohn Scipione } 468f4664459SJohn Scipione 469f4664459SJohn Scipione 470f4664459SJohn Scipione void 471f4664459SJohn Scipione BTextControl::MessageReceived(BMessage* message) 472f4664459SJohn Scipione { 4737a96554cSlooncraz if (message->what == B_COLORS_UPDATED) { 4747a96554cSlooncraz 4757a96554cSlooncraz if (message->HasColor(ui_color_name(B_PANEL_BACKGROUND_COLOR)) 4767a96554cSlooncraz || message->HasColor(ui_color_name(B_PANEL_TEXT_COLOR)) 4777a96554cSlooncraz || message->HasColor(ui_color_name(B_DOCUMENT_BACKGROUND_COLOR)) 4787a96554cSlooncraz || message->HasColor(ui_color_name(B_DOCUMENT_TEXT_COLOR))) { 4797a96554cSlooncraz _UpdateTextViewColors(IsEnabled()); 4807a96554cSlooncraz } 4817a96554cSlooncraz } 4827a96554cSlooncraz 483f4664459SJohn Scipione if (message->what == B_GET_PROPERTY || message->what == B_SET_PROPERTY) { 484f4664459SJohn Scipione BMessage reply(B_REPLY); 485f4664459SJohn Scipione bool handled = false; 486f4664459SJohn Scipione 487f4664459SJohn Scipione BMessage specifier; 488f4664459SJohn Scipione int32 index; 489f4664459SJohn Scipione int32 form; 490f4664459SJohn Scipione const char* property; 491f4664459SJohn Scipione if (message->GetCurrentSpecifier(&index, &specifier, &form, &property) == B_OK) { 492f4664459SJohn Scipione if (strcmp(property, "Value") == 0) { 493f4664459SJohn Scipione if (message->what == B_GET_PROPERTY) { 494f4664459SJohn Scipione reply.AddString("result", fText->Text()); 495f4664459SJohn Scipione handled = true; 496f4664459SJohn Scipione } else { 497f4664459SJohn Scipione const char* value = NULL; 498f4664459SJohn Scipione // B_SET_PROPERTY 499f4664459SJohn Scipione if (message->FindString("data", &value) == B_OK) { 500f4664459SJohn Scipione fText->SetText(value); 501f4664459SJohn Scipione reply.AddInt32("error", B_OK); 502f4664459SJohn Scipione handled = true; 503f4664459SJohn Scipione } 504f4664459SJohn Scipione } 505f4664459SJohn Scipione } 506f4664459SJohn Scipione } 507f4664459SJohn Scipione 508f4664459SJohn Scipione if (handled) { 509f4664459SJohn Scipione message->SendReply(&reply); 510f4664459SJohn Scipione return; 511f4664459SJohn Scipione } 512f4664459SJohn Scipione } 513f4664459SJohn Scipione 514f4664459SJohn Scipione BControl::MessageReceived(message); 515f4664459SJohn Scipione } 516f4664459SJohn Scipione 517f4664459SJohn Scipione 518f4664459SJohn Scipione void 519f4664459SJohn Scipione BTextControl::MouseDown(BPoint where) 520f4664459SJohn Scipione { 521f4664459SJohn Scipione if (!fText->IsFocus()) 522f4664459SJohn Scipione fText->MakeFocus(true); 523f4664459SJohn Scipione } 524f4664459SJohn Scipione 525f4664459SJohn Scipione 526f4664459SJohn Scipione void 527f4664459SJohn Scipione BTextControl::MouseMoved(BPoint where, uint32 transit, 528f4664459SJohn Scipione const BMessage* dragMessage) 529f4664459SJohn Scipione { 530f4664459SJohn Scipione BControl::MouseMoved(where, transit, dragMessage); 531f4664459SJohn Scipione } 532f4664459SJohn Scipione 533f4664459SJohn Scipione 534f4664459SJohn Scipione void 535f4664459SJohn Scipione BTextControl::MouseUp(BPoint where) 536f4664459SJohn Scipione { 537f4664459SJohn Scipione BControl::MouseUp(where); 538f4664459SJohn Scipione } 539f4664459SJohn Scipione 540f4664459SJohn Scipione 541058691d4SStefano Ceccherini void 542058691d4SStefano Ceccherini BTextControl::WindowActivated(bool active) 54352a38012Sejakowatz { 5446d8d6cadSStephan Aßmus if (fText->IsFocus()) { 545dde10e45SStephan Aßmus // invalidate to remove/show focus indication 5462c5a8894SStephan Aßmus BRect rect = fText->Frame(); 5472c5a8894SStephan Aßmus rect.InsetBy(-1, -1); 5486d8d6cadSStephan Aßmus Invalidate(rect); 549dde10e45SStephan Aßmus 550dde10e45SStephan Aßmus // help out embedded text view which doesn't 551dde10e45SStephan Aßmus // get notified of this 552dde10e45SStephan Aßmus fText->Invalidate(); 5536d8d6cadSStephan Aßmus } 55452a38012Sejakowatz } 555058691d4SStefano Ceccherini 556058691d4SStefano Ceccherini 557f4664459SJohn Scipione // #pragma mark - Getters and Setters 558f4664459SJohn Scipione 559f4664459SJohn Scipione 560f4664459SJohn Scipione void 561f4664459SJohn Scipione BTextControl::SetText(const char* text) 562f4664459SJohn Scipione { 563f4664459SJohn Scipione if (InvokeKind() != B_CONTROL_INVOKED) 564f4664459SJohn Scipione return; 565f4664459SJohn Scipione 566f4664459SJohn Scipione CALLED(); 567f4664459SJohn Scipione 568f4664459SJohn Scipione fText->SetText(text); 569f4664459SJohn Scipione 570f4664459SJohn Scipione if (fText->IsFocus()) { 571f4664459SJohn Scipione fText->SetInitialText(); 572f4664459SJohn Scipione fText->SelectAll(); 573f4664459SJohn Scipione } 574f4664459SJohn Scipione 575f4664459SJohn Scipione fText->Invalidate(); 576f4664459SJohn Scipione } 577f4664459SJohn Scipione 578f4664459SJohn Scipione 579f4664459SJohn Scipione const char* 580f4664459SJohn Scipione BTextControl::Text() const 581f4664459SJohn Scipione { 582f4664459SJohn Scipione return fText->Text(); 583f4664459SJohn Scipione } 584f4664459SJohn Scipione 585f4664459SJohn Scipione 5868bc3ecb0SAxel Dörfler int32 5878bc3ecb0SAxel Dörfler BTextControl::TextLength() const 5888bc3ecb0SAxel Dörfler { 5898bc3ecb0SAxel Dörfler return fText->TextLength(); 5908bc3ecb0SAxel Dörfler } 5918bc3ecb0SAxel Dörfler 5928bc3ecb0SAxel Dörfler 593f4664459SJohn Scipione void 594f4664459SJohn Scipione BTextControl::MarkAsInvalid(bool invalid) 595f4664459SJohn Scipione { 596f4664459SJohn Scipione uint32 look = fLook; 597f4664459SJohn Scipione 598f4664459SJohn Scipione if (invalid) 599f4664459SJohn Scipione fLook |= BControlLook::B_INVALID; 600f4664459SJohn Scipione else 601f4664459SJohn Scipione fLook &= ~BControlLook::B_INVALID; 602f4664459SJohn Scipione 603f4664459SJohn Scipione if (look != fLook) 604f4664459SJohn Scipione Invalidate(); 605f4664459SJohn Scipione } 606f4664459SJohn Scipione 607f4664459SJohn Scipione 608f4664459SJohn Scipione void 609f4664459SJohn Scipione BTextControl::SetValue(int32 value) 610f4664459SJohn Scipione { 611f4664459SJohn Scipione BControl::SetValue(value); 612f4664459SJohn Scipione } 613f4664459SJohn Scipione 614f4664459SJohn Scipione 615f4664459SJohn Scipione BTextView* 616f4664459SJohn Scipione BTextControl::TextView() const 617f4664459SJohn Scipione { 618f4664459SJohn Scipione return fText; 619f4664459SJohn Scipione } 620f4664459SJohn Scipione 621f4664459SJohn Scipione 622f4664459SJohn Scipione void 623f4664459SJohn Scipione BTextControl::SetModificationMessage(BMessage* message) 624f4664459SJohn Scipione { 625f4664459SJohn Scipione delete fModificationMessage; 626f4664459SJohn Scipione fModificationMessage = message; 627f4664459SJohn Scipione } 628f4664459SJohn Scipione 629f4664459SJohn Scipione 630f4664459SJohn Scipione BMessage* 631f4664459SJohn Scipione BTextControl::ModificationMessage() const 632f4664459SJohn Scipione { 633f4664459SJohn Scipione return fModificationMessage; 634f4664459SJohn Scipione } 635f4664459SJohn Scipione 636f4664459SJohn Scipione 637f4664459SJohn Scipione void 638f4664459SJohn Scipione BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment) 639f4664459SJohn Scipione { 640f4664459SJohn Scipione fText->SetAlignment(textAlignment); 641f4664459SJohn Scipione 642f4664459SJohn Scipione if (fLabelAlign != labelAlignment) { 643f4664459SJohn Scipione fLabelAlign = labelAlignment; 644f4664459SJohn Scipione Invalidate(); 645f4664459SJohn Scipione } 646f4664459SJohn Scipione } 647f4664459SJohn Scipione 648f4664459SJohn Scipione 649f4664459SJohn Scipione void 650f4664459SJohn Scipione BTextControl::GetAlignment(alignment* _label, alignment* _text) const 651f4664459SJohn Scipione { 652f4664459SJohn Scipione if (_label != NULL) 653f4664459SJohn Scipione *_label = fLabelAlign; 654f4664459SJohn Scipione 655f4664459SJohn Scipione if (_text != NULL) 656f4664459SJohn Scipione *_text = fText->Alignment(); 657f4664459SJohn Scipione } 658f4664459SJohn Scipione 659f4664459SJohn Scipione 660f4664459SJohn Scipione void 661f4664459SJohn Scipione BTextControl::SetDivider(float position) 662f4664459SJohn Scipione { 663f4664459SJohn Scipione fDivider = floorf(position + 0.5); 664f4664459SJohn Scipione 665f4664459SJohn Scipione _LayoutTextView(); 666f4664459SJohn Scipione 667f4664459SJohn Scipione if (Window()) { 668f4664459SJohn Scipione fText->Invalidate(); 669f4664459SJohn Scipione Invalidate(); 670f4664459SJohn Scipione } 671f4664459SJohn Scipione } 672f4664459SJohn Scipione 673f4664459SJohn Scipione 674f4664459SJohn Scipione float 675f4664459SJohn Scipione BTextControl::Divider() const 676f4664459SJohn Scipione { 677f4664459SJohn Scipione return fDivider; 678f4664459SJohn Scipione } 679f4664459SJohn Scipione 680f4664459SJohn Scipione 681f4664459SJohn Scipione void 682f4664459SJohn Scipione BTextControl::MakeFocus(bool state) 683f4664459SJohn Scipione { 684f4664459SJohn Scipione if (state != fText->IsFocus()) { 685f4664459SJohn Scipione fText->MakeFocus(state); 686f4664459SJohn Scipione 687f4664459SJohn Scipione if (state) 688f4664459SJohn Scipione fText->SelectAll(); 689f4664459SJohn Scipione } 690f4664459SJohn Scipione } 691f4664459SJohn Scipione 692f4664459SJohn Scipione 693f4664459SJohn Scipione void 694f4664459SJohn Scipione BTextControl::SetEnabled(bool enable) 695f4664459SJohn Scipione { 696f4664459SJohn Scipione if (IsEnabled() == enable) 697f4664459SJohn Scipione return; 698f4664459SJohn Scipione 699f4664459SJohn Scipione if (Window() != NULL) { 700f4664459SJohn Scipione fText->MakeEditable(enable); 701f4664459SJohn Scipione if (enable) 702f4664459SJohn Scipione fText->SetFlags(fText->Flags() | B_NAVIGABLE); 703f4664459SJohn Scipione else 704f4664459SJohn Scipione fText->SetFlags(fText->Flags() & ~B_NAVIGABLE); 705f4664459SJohn Scipione 706f4664459SJohn Scipione _UpdateTextViewColors(enable); 707f4664459SJohn Scipione 708f4664459SJohn Scipione fText->Invalidate(); 709f4664459SJohn Scipione Window()->UpdateIfNeeded(); 710f4664459SJohn Scipione } 711f4664459SJohn Scipione 712f4664459SJohn Scipione BControl::SetEnabled(enable); 713f4664459SJohn Scipione } 714f4664459SJohn Scipione 715f4664459SJohn Scipione 716f4664459SJohn Scipione void 717f4664459SJohn Scipione BTextControl::GetPreferredSize(float* _width, float* _height) 718f4664459SJohn Scipione { 719f4664459SJohn Scipione CALLED(); 720f4664459SJohn Scipione 721f4664459SJohn Scipione _ValidateLayoutData(); 722f4664459SJohn Scipione 723f4664459SJohn Scipione if (_width) { 724f4664459SJohn Scipione float minWidth = fLayoutData->min.width; 725f4664459SJohn Scipione if (Label() == NULL && !(Flags() & B_SUPPORTS_LAYOUT)) { 726f4664459SJohn Scipione // Indeed, only if there is no label! BeOS backwards compatible 727f4664459SJohn Scipione // behavior: 728f4664459SJohn Scipione minWidth = max_c(minWidth, Bounds().Width()); 729f4664459SJohn Scipione } 730f4664459SJohn Scipione *_width = minWidth; 731f4664459SJohn Scipione } 732f4664459SJohn Scipione 733f4664459SJohn Scipione if (_height) 734f4664459SJohn Scipione *_height = fLayoutData->min.height; 735f4664459SJohn Scipione } 736f4664459SJohn Scipione 737f4664459SJohn Scipione 738f4664459SJohn Scipione void 739f4664459SJohn Scipione BTextControl::ResizeToPreferred() 740f4664459SJohn Scipione { 741f4664459SJohn Scipione BView::ResizeToPreferred(); 742f4664459SJohn Scipione 743f4664459SJohn Scipione fDivider = 0.0; 744f4664459SJohn Scipione const char* label = Label(); 745f4664459SJohn Scipione if (label) 746f4664459SJohn Scipione fDivider = ceil(StringWidth(label)) + 2.0; 747f4664459SJohn Scipione 748f4664459SJohn Scipione _LayoutTextView(); 749f4664459SJohn Scipione } 750f4664459SJohn Scipione 751f4664459SJohn Scipione 752f4664459SJohn Scipione void 753f4664459SJohn Scipione BTextControl::SetFlags(uint32 flags) 754f4664459SJohn Scipione { 755f4664459SJohn Scipione // If the textview is navigable, set it to not navigable if needed 756f4664459SJohn Scipione // Else if it is not navigable, set it to navigable if needed 757f4664459SJohn Scipione if (fText->Flags() & B_NAVIGABLE) { 758f4664459SJohn Scipione if (!(flags & B_NAVIGABLE)) 759f4664459SJohn Scipione fText->SetFlags(fText->Flags() & ~B_NAVIGABLE); 760f4664459SJohn Scipione 761f4664459SJohn Scipione } else { 762f4664459SJohn Scipione if (flags & B_NAVIGABLE) 763f4664459SJohn Scipione fText->SetFlags(fText->Flags() | B_NAVIGABLE); 764f4664459SJohn Scipione } 765f4664459SJohn Scipione 766f4664459SJohn Scipione // Don't make this one navigable 767f4664459SJohn Scipione flags &= ~B_NAVIGABLE; 768f4664459SJohn Scipione 769f4664459SJohn Scipione BView::SetFlags(flags); 770f4664459SJohn Scipione } 771f4664459SJohn Scipione 772f4664459SJohn Scipione 773f4664459SJohn Scipione // #pragma mark - Scripting 774f4664459SJohn Scipione 775f4664459SJohn Scipione 776f4664459SJohn Scipione BHandler* 777f4664459SJohn Scipione BTextControl::ResolveSpecifier(BMessage* message, int32 index, 778f4664459SJohn Scipione BMessage* specifier, int32 what, const char* property) 779f4664459SJohn Scipione { 780f4664459SJohn Scipione BPropertyInfo propInfo(sPropertyList); 781f4664459SJohn Scipione 782f4664459SJohn Scipione if (propInfo.FindMatch(message, 0, specifier, what, property) >= B_OK) 783f4664459SJohn Scipione return this; 784f4664459SJohn Scipione 785f4664459SJohn Scipione return BControl::ResolveSpecifier(message, index, specifier, what, 786f4664459SJohn Scipione property); 787f4664459SJohn Scipione } 788f4664459SJohn Scipione 789f4664459SJohn Scipione 790f4664459SJohn Scipione status_t 791f4664459SJohn Scipione BTextControl::GetSupportedSuites(BMessage* data) 792f4664459SJohn Scipione { 793f4664459SJohn Scipione return BControl::GetSupportedSuites(data); 794f4664459SJohn Scipione } 795f4664459SJohn Scipione 796f4664459SJohn Scipione 797f4664459SJohn Scipione // #pragma mark - Layout 798f4664459SJohn Scipione 799f4664459SJohn Scipione 800349c911eSStephan Aßmus BSize 801349c911eSStephan Aßmus BTextControl::MinSize() 80252a38012Sejakowatz { 803349c911eSStephan Aßmus CALLED(); 804349c911eSStephan Aßmus 805349c911eSStephan Aßmus _ValidateLayoutData(); 806349c911eSStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitMinSize(), fLayoutData->min); 807349c911eSStephan Aßmus } 808349c911eSStephan Aßmus 809349c911eSStephan Aßmus 810349c911eSStephan Aßmus BSize 811349c911eSStephan Aßmus BTextControl::MaxSize() 812349c911eSStephan Aßmus { 813349c911eSStephan Aßmus CALLED(); 814349c911eSStephan Aßmus 815349c911eSStephan Aßmus _ValidateLayoutData(); 816349c911eSStephan Aßmus 817349c911eSStephan Aßmus BSize max = fLayoutData->min; 818349c911eSStephan Aßmus max.width = B_SIZE_UNLIMITED; 819349c911eSStephan Aßmus 820349c911eSStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitMaxSize(), max); 821349c911eSStephan Aßmus } 822349c911eSStephan Aßmus 823349c911eSStephan Aßmus 824349c911eSStephan Aßmus BSize 825349c911eSStephan Aßmus BTextControl::PreferredSize() 826349c911eSStephan Aßmus { 827349c911eSStephan Aßmus CALLED(); 828349c911eSStephan Aßmus 829349c911eSStephan Aßmus _ValidateLayoutData(); 830349c911eSStephan Aßmus return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), fLayoutData->min); 831349c911eSStephan Aßmus } 832349c911eSStephan Aßmus 833349c911eSStephan Aßmus 83446d6e9d9SRene Gollent BAlignment 83546d6e9d9SRene Gollent BTextControl::LayoutAlignment() 83646d6e9d9SRene Gollent { 83746d6e9d9SRene Gollent CALLED(); 83846d6e9d9SRene Gollent 83946d6e9d9SRene Gollent _ValidateLayoutData(); 84046d6e9d9SRene Gollent return BLayoutUtils::ComposeAlignment(ExplicitAlignment(), 841be92485fSHumdinger BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER)); 84246d6e9d9SRene Gollent } 84346d6e9d9SRene Gollent 84446d6e9d9SRene Gollent 8459ecf9d1cSIngo Weinhold BLayoutItem* 8469ecf9d1cSIngo Weinhold BTextControl::CreateLabelLayoutItem() 8479ecf9d1cSIngo Weinhold { 848349c911eSStephan Aßmus if (!fLayoutData->label_layout_item) 849349c911eSStephan Aßmus fLayoutData->label_layout_item = new LabelLayoutItem(this); 850b11edca4SJohn Scipione 851349c911eSStephan Aßmus return fLayoutData->label_layout_item; 8529ecf9d1cSIngo Weinhold } 8539ecf9d1cSIngo Weinhold 8549ecf9d1cSIngo Weinhold 8559ecf9d1cSIngo Weinhold BLayoutItem* 8569ecf9d1cSIngo Weinhold BTextControl::CreateTextViewLayoutItem() 8579ecf9d1cSIngo Weinhold { 858349c911eSStephan Aßmus if (!fLayoutData->text_view_layout_item) 859349c911eSStephan Aßmus fLayoutData->text_view_layout_item = new TextViewLayoutItem(this); 860b11edca4SJohn Scipione 861349c911eSStephan Aßmus return fLayoutData->text_view_layout_item; 862349c911eSStephan Aßmus } 863349c911eSStephan Aßmus 864349c911eSStephan Aßmus 865349c911eSStephan Aßmus void 866349c911eSStephan Aßmus BTextControl::DoLayout() 867349c911eSStephan Aßmus { 868349c911eSStephan Aßmus // Bail out, if we shan't do layout. 869349c911eSStephan Aßmus if (!(Flags() & B_SUPPORTS_LAYOUT)) 870349c911eSStephan Aßmus return; 871349c911eSStephan Aßmus 872349c911eSStephan Aßmus CALLED(); 873349c911eSStephan Aßmus 874349c911eSStephan Aßmus // If the user set a layout, we let the base class version call its 875349c911eSStephan Aßmus // hook. 876349c911eSStephan Aßmus if (GetLayout()) { 877349c911eSStephan Aßmus BView::DoLayout(); 878349c911eSStephan Aßmus return; 879349c911eSStephan Aßmus } 880349c911eSStephan Aßmus 881349c911eSStephan Aßmus _ValidateLayoutData(); 882349c911eSStephan Aßmus 883349c911eSStephan Aßmus // validate current size 884349c911eSStephan Aßmus BSize size(Bounds().Size()); 885349c911eSStephan Aßmus if (size.width < fLayoutData->min.width) 886349c911eSStephan Aßmus size.width = fLayoutData->min.width; 887b11edca4SJohn Scipione 888349c911eSStephan Aßmus if (size.height < fLayoutData->min.height) 889349c911eSStephan Aßmus size.height = fLayoutData->min.height; 890349c911eSStephan Aßmus 89109d87d91SAxel Dörfler BRect dirty(fText->Frame()); 89209d87d91SAxel Dörfler BRect textFrame; 89309d87d91SAxel Dörfler 894349c911eSStephan Aßmus // divider 895349c911eSStephan Aßmus float divider = 0; 89609d87d91SAxel Dörfler if (fLayoutData->text_view_layout_item != NULL) { 89709d87d91SAxel Dörfler if (fLayoutData->label_layout_item != NULL) { 898349c911eSStephan Aßmus // We have layout items. They define the divider location. 89909d87d91SAxel Dörfler divider = fabs(fLayoutData->text_view_layout_item->Frame().left 90009d87d91SAxel Dörfler - fLayoutData->label_layout_item->Frame().left); 90109d87d91SAxel Dörfler } 90209d87d91SAxel Dörfler textFrame = fLayoutData->text_view_layout_item->FrameInParent(); 903349c911eSStephan Aßmus } else { 90409d87d91SAxel Dörfler if (fLayoutData->label_width > 0) { 90509d87d91SAxel Dörfler divider = fLayoutData->label_width 90609d87d91SAxel Dörfler + be_control_look->DefaultLabelSpacing(); 90709d87d91SAxel Dörfler } 90809d87d91SAxel Dörfler textFrame.Set(divider, 0, size.width, size.height); 909349c911eSStephan Aßmus } 910349c911eSStephan Aßmus 911349c911eSStephan Aßmus // place the text view and set the divider 91209d87d91SAxel Dörfler textFrame.InsetBy(kFrameMargin, kFrameMargin); 913349c911eSStephan Aßmus BLayoutUtils::AlignInFrame(fText, textFrame); 914*d9385a9dSJohn Scipione fText->SetTextRect(textFrame.OffsetToCopy(B_ORIGIN)); 915349c911eSStephan Aßmus 916349c911eSStephan Aßmus fDivider = divider; 917349c911eSStephan Aßmus 918349c911eSStephan Aßmus // invalidate dirty region 919349c911eSStephan Aßmus dirty = dirty | fText->Frame(); 920349c911eSStephan Aßmus dirty.InsetBy(-kFrameMargin, -kFrameMargin); 921349c911eSStephan Aßmus 922349c911eSStephan Aßmus Invalidate(dirty); 923349c911eSStephan Aßmus } 924349c911eSStephan Aßmus 925349c911eSStephan Aßmus 926f4664459SJohn Scipione // #pragma mark - protected methods 927f4664459SJohn Scipione 928f4664459SJohn Scipione 929be436742SIngo Weinhold status_t 930be436742SIngo Weinhold BTextControl::SetIcon(const BBitmap* icon, uint32 flags) 931be436742SIngo Weinhold { 932be436742SIngo Weinhold return BControl::SetIcon(icon, flags); 933be436742SIngo Weinhold } 934be436742SIngo Weinhold 935be436742SIngo Weinhold 936f4664459SJohn Scipione // #pragma mark - private methods 937349c911eSStephan Aßmus 938349c911eSStephan Aßmus 939349c911eSStephan Aßmus status_t 94039fbf550SOliver Tappe BTextControl::Perform(perform_code code, void* _data) 941349c911eSStephan Aßmus { 94239fbf550SOliver Tappe switch (code) { 94339fbf550SOliver Tappe case PERFORM_CODE_MIN_SIZE: 94439fbf550SOliver Tappe ((perform_data_min_size*)_data)->return_value 94539fbf550SOliver Tappe = BTextControl::MinSize(); 94639fbf550SOliver Tappe return B_OK; 947b11edca4SJohn Scipione 94839fbf550SOliver Tappe case PERFORM_CODE_MAX_SIZE: 94939fbf550SOliver Tappe ((perform_data_max_size*)_data)->return_value 95039fbf550SOliver Tappe = BTextControl::MaxSize(); 95139fbf550SOliver Tappe return B_OK; 952b11edca4SJohn Scipione 95339fbf550SOliver Tappe case PERFORM_CODE_PREFERRED_SIZE: 95439fbf550SOliver Tappe ((perform_data_preferred_size*)_data)->return_value 95539fbf550SOliver Tappe = BTextControl::PreferredSize(); 95639fbf550SOliver Tappe return B_OK; 957b11edca4SJohn Scipione 95839fbf550SOliver Tappe case PERFORM_CODE_LAYOUT_ALIGNMENT: 95939fbf550SOliver Tappe ((perform_data_layout_alignment*)_data)->return_value 96039fbf550SOliver Tappe = BTextControl::LayoutAlignment(); 96139fbf550SOliver Tappe return B_OK; 962b11edca4SJohn Scipione 96339fbf550SOliver Tappe case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH: 96439fbf550SOliver Tappe ((perform_data_has_height_for_width*)_data)->return_value 96539fbf550SOliver Tappe = BTextControl::HasHeightForWidth(); 96639fbf550SOliver Tappe return B_OK; 967b11edca4SJohn Scipione 96839fbf550SOliver Tappe case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH: 96939fbf550SOliver Tappe { 97039fbf550SOliver Tappe perform_data_get_height_for_width* data 97139fbf550SOliver Tappe = (perform_data_get_height_for_width*)_data; 97239fbf550SOliver Tappe BTextControl::GetHeightForWidth(data->width, &data->min, &data->max, 97339fbf550SOliver Tappe &data->preferred); 97439fbf550SOliver Tappe return B_OK; 97539fbf550SOliver Tappe } 976b11edca4SJohn Scipione 97739fbf550SOliver Tappe case PERFORM_CODE_SET_LAYOUT: 97839fbf550SOliver Tappe { 97939fbf550SOliver Tappe perform_data_set_layout* data = (perform_data_set_layout*)_data; 98039fbf550SOliver Tappe BTextControl::SetLayout(data->layout); 98139fbf550SOliver Tappe return B_OK; 98239fbf550SOliver Tappe } 983b11edca4SJohn Scipione 984eee4243dSAlex Wilson case PERFORM_CODE_LAYOUT_INVALIDATED: 98539fbf550SOliver Tappe { 986eee4243dSAlex Wilson perform_data_layout_invalidated* data 987eee4243dSAlex Wilson = (perform_data_layout_invalidated*)_data; 988eee4243dSAlex Wilson BTextControl::LayoutInvalidated(data->descendants); 98939fbf550SOliver Tappe return B_OK; 99039fbf550SOliver Tappe } 991b11edca4SJohn Scipione 99239fbf550SOliver Tappe case PERFORM_CODE_DO_LAYOUT: 99339fbf550SOliver Tappe { 99439fbf550SOliver Tappe BTextControl::DoLayout(); 99539fbf550SOliver Tappe return B_OK; 99639fbf550SOliver Tappe } 997b11edca4SJohn Scipione 998be436742SIngo Weinhold case PERFORM_CODE_SET_ICON: 999be436742SIngo Weinhold { 1000be436742SIngo Weinhold perform_data_set_icon* data = (perform_data_set_icon*)_data; 1001be436742SIngo Weinhold return BTextControl::SetIcon(data->icon, data->flags); 1002be436742SIngo Weinhold } 1003b11edca4SJohn Scipione 10045c47e35eSAlex Wilson case PERFORM_CODE_ALL_UNARCHIVED: 10055c47e35eSAlex Wilson { 10065c47e35eSAlex Wilson perform_data_all_unarchived* data 10075c47e35eSAlex Wilson = (perform_data_all_unarchived*)_data; 10085c47e35eSAlex Wilson data->return_value = BTextControl::AllUnarchived(data->archive); 10095c47e35eSAlex Wilson return B_OK; 10105c47e35eSAlex Wilson } 1011b11edca4SJohn Scipione 10125c47e35eSAlex Wilson case PERFORM_CODE_ALL_ARCHIVED: 10135c47e35eSAlex Wilson { 10145c47e35eSAlex Wilson perform_data_all_archived* data 10155c47e35eSAlex Wilson = (perform_data_all_archived*)_data; 10165c47e35eSAlex Wilson data->return_value = BTextControl::AllArchived(data->archive); 10175c47e35eSAlex Wilson return B_OK; 10185c47e35eSAlex Wilson } 101939fbf550SOliver Tappe } 102039fbf550SOliver Tappe 102139fbf550SOliver Tappe return BControl::Perform(code, _data); 10229ecf9d1cSIngo Weinhold } 10239ecf9d1cSIngo Weinhold 10249ecf9d1cSIngo Weinhold 1025f4664459SJohn Scipione // #pragma mark - FBC padding 1026f4664459SJohn Scipione 1027f4664459SJohn Scipione 10289cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl1() {} 10299cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl2() {} 10309cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl3() {} 10319cb2dbe2SMarc Flerackers void BTextControl::_ReservedTextControl4() {} 1032058691d4SStefano Ceccherini 1033058691d4SStefano Ceccherini 1034058691d4SStefano Ceccherini BTextControl& 1035058691d4SStefano Ceccherini BTextControl::operator=(const BTextControl&) 103652a38012Sejakowatz { 103752a38012Sejakowatz return *this; 103852a38012Sejakowatz } 1039058691d4SStefano Ceccherini 1040058691d4SStefano Ceccherini 1041058691d4SStefano Ceccherini void 1042f4664459SJohn Scipione BTextControl::_UpdateTextViewColors(bool enable) 10433a3f6c1eSAxel Dörfler { 10447a96554cSlooncraz rgb_color textColor = ui_color(B_DOCUMENT_TEXT_COLOR); 10457a96554cSlooncraz rgb_color viewColor = ui_color(B_DOCUMENT_BACKGROUND_COLOR); 10463a3f6c1eSAxel Dörfler BFont font; 10473a3f6c1eSAxel Dörfler 1048aae7000dSAxel Dörfler fText->GetFontAndColor(0, &font); 10493a3f6c1eSAxel Dörfler 10507a96554cSlooncraz if (!enable) { 10517a96554cSlooncraz textColor = disable_color(textColor, ViewColor()); 10527a96554cSlooncraz viewColor = disable_color(ViewColor(), viewColor); 105312aefeb4SAxel Dörfler } 10543a3f6c1eSAxel Dörfler 10553a3f6c1eSAxel Dörfler fText->SetFontAndColor(&font, B_FONT_ALL, &textColor); 10567a96554cSlooncraz fText->SetViewColor(viewColor); 10577a96554cSlooncraz fText->SetLowColor(viewColor); 10583a3f6c1eSAxel Dörfler } 10593a3f6c1eSAxel Dörfler 10603a3f6c1eSAxel Dörfler 10613a3f6c1eSAxel Dörfler void 1062ffe72abdSAxel Dörfler BTextControl::_CommitValue() 10639cb2dbe2SMarc Flerackers { 10649cb2dbe2SMarc Flerackers } 1065058691d4SStefano Ceccherini 1066058691d4SStefano Ceccherini 1067058691d4SStefano Ceccherini void 10685c47e35eSAlex Wilson BTextControl::_InitData(const char* label, const BMessage* archive) 10699cb2dbe2SMarc Flerackers { 10709cb2dbe2SMarc Flerackers BRect bounds(Bounds()); 10719cb2dbe2SMarc Flerackers 10729cb2dbe2SMarc Flerackers fText = NULL; 10739cb2dbe2SMarc Flerackers fModificationMessage = NULL; 10749cb2dbe2SMarc Flerackers fLabelAlign = B_ALIGN_LEFT; 10759cb2dbe2SMarc Flerackers fDivider = 0.0f; 1076349c911eSStephan Aßmus fLayoutData = new LayoutData(bounds.Width(), bounds.Height()); 10779cb2dbe2SMarc Flerackers 10789cb2dbe2SMarc Flerackers int32 flags = 0; 10799cb2dbe2SMarc Flerackers 1080918a22d9SDarkWyrm BFont font(be_plain_font); 10819cb2dbe2SMarc Flerackers 1082ffe72abdSAxel Dörfler if (!archive || !archive->HasString("_fname")) 1083058691d4SStefano Ceccherini flags |= B_FONT_FAMILY_AND_STYLE; 10849cb2dbe2SMarc Flerackers 1085ffe72abdSAxel Dörfler if (!archive || !archive->HasFloat("_fflt")) 1086058691d4SStefano Ceccherini flags |= B_FONT_SIZE; 10879cb2dbe2SMarc Flerackers 10889cb2dbe2SMarc Flerackers if (flags != 0) 10899cb2dbe2SMarc Flerackers SetFont(&font, flags); 10909cb2dbe2SMarc Flerackers 1091f4664459SJohn Scipione if (label != NULL) 10922e6a5805SStephan Aßmus fDivider = floorf(bounds.Width() / 2.0f); 109313d147b1SAdrien Destugues 109413d147b1SAdrien Destugues fLook = 0; 10955c47e35eSAlex Wilson } 10965c47e35eSAlex Wilson 10975c47e35eSAlex Wilson 10985c47e35eSAlex Wilson void 10995c47e35eSAlex Wilson BTextControl::_InitText(const char* initialText, const BMessage* archive) 11005c47e35eSAlex Wilson { 1101ffe72abdSAxel Dörfler if (archive) 1102b8872c02SStephan Aßmus fText = static_cast<BPrivate::_BTextInput_*>(FindView("_input_")); 1103991c062fSAxel Dörfler 1104991c062fSAxel Dörfler if (fText == NULL) { 11055c47e35eSAlex Wilson BRect bounds(Bounds()); 1106ee2a3473SStephan Aßmus BRect frame(fDivider, bounds.top, bounds.right, bounds.bottom); 1107105644bfSAxel Dörfler // we are stroking the frame around the text view, which 11082e6a5805SStephan Aßmus // is 2 pixels wide 1109349c911eSStephan Aßmus frame.InsetBy(kFrameMargin, kFrameMargin); 1110111b4fbcSStefano Ceccherini BRect textRect(frame.OffsetToCopy(B_ORIGIN)); 11119cb2dbe2SMarc Flerackers 1112b8872c02SStephan Aßmus fText = new BPrivate::_BTextInput_(frame, textRect, 11135c47e35eSAlex Wilson B_FOLLOW_ALL, B_WILL_DRAW | B_FRAME_EVENTS 11145c47e35eSAlex Wilson | (Flags() & B_NAVIGABLE)); 11159cb2dbe2SMarc Flerackers AddChild(fText); 11169cb2dbe2SMarc Flerackers 1117455d1c46SAxel Dörfler SetText(initialText); 11189cb2dbe2SMarc Flerackers fText->SetAlignment(B_ALIGN_LEFT); 11199cb2dbe2SMarc Flerackers } 11205c47e35eSAlex Wilson 11215c47e35eSAlex Wilson // Although this is not strictly initializing the text view, 11225c47e35eSAlex Wilson // it cannot be done while fText is NULL, so it resides here. 11235c47e35eSAlex Wilson if (archive) { 11245c47e35eSAlex Wilson int32 labelAlignment = B_ALIGN_LEFT; 11255c47e35eSAlex Wilson int32 textAlignment = B_ALIGN_LEFT; 11265c47e35eSAlex Wilson 11275c47e35eSAlex Wilson status_t err = B_OK; 11285c47e35eSAlex Wilson if (archive->HasInt32("_a_label")) 11295c47e35eSAlex Wilson err = archive->FindInt32("_a_label", &labelAlignment); 11305c47e35eSAlex Wilson 11315c47e35eSAlex Wilson if (err == B_OK && archive->HasInt32("_a_text")) 11325c47e35eSAlex Wilson err = archive->FindInt32("_a_text", &textAlignment); 11335c47e35eSAlex Wilson 11345c47e35eSAlex Wilson SetAlignment((alignment)labelAlignment, (alignment)textAlignment); 11355c47e35eSAlex Wilson } 113650960935SClemens Zeidler 113750960935SClemens Zeidler uint32 navigableFlags = Flags() & B_NAVIGABLE; 113850960935SClemens Zeidler if (navigableFlags != 0) 113950960935SClemens Zeidler BView::SetFlags(Flags() & ~B_NAVIGABLE); 11409cb2dbe2SMarc Flerackers } 11419ecf9d1cSIngo Weinhold 11429ecf9d1cSIngo Weinhold 11439ecf9d1cSIngo Weinhold void 11449ecf9d1cSIngo Weinhold BTextControl::_ValidateLayout() 11459ecf9d1cSIngo Weinhold { 114693ba577cSStephan Aßmus CALLED(); 114793ba577cSStephan Aßmus 1148349c911eSStephan Aßmus _ValidateLayoutData(); 11499ecf9d1cSIngo Weinhold 1150349c911eSStephan Aßmus ResizeTo(Bounds().Width(), fLayoutData->min.height); 11519ecf9d1cSIngo Weinhold 1152a431f44bSStephan Aßmus _LayoutTextView(); 11539ecf9d1cSIngo Weinhold } 11549ecf9d1cSIngo Weinhold 11559ecf9d1cSIngo Weinhold 11569ecf9d1cSIngo Weinhold void 1157a431f44bSStephan Aßmus BTextControl::_LayoutTextView() 1158a431f44bSStephan Aßmus { 115993ba577cSStephan Aßmus CALLED(); 116093ba577cSStephan Aßmus 116109d87d91SAxel Dörfler BRect frame; 116209d87d91SAxel Dörfler if (fLayoutData->text_view_layout_item != NULL) { 116309d87d91SAxel Dörfler frame = fLayoutData->text_view_layout_item->FrameInParent(); 116409d87d91SAxel Dörfler } else { 116509d87d91SAxel Dörfler frame = Bounds(); 1166a431f44bSStephan Aßmus frame.left = fDivider; 116709d87d91SAxel Dörfler } 116809d87d91SAxel Dörfler 1169a431f44bSStephan Aßmus // we are stroking the frame around the text view, which 1170a431f44bSStephan Aßmus // is 2 pixels wide 117184b7e122SStephan Aßmus frame.InsetBy(kFrameMargin, kFrameMargin); 1172a431f44bSStephan Aßmus fText->MoveTo(frame.left, frame.top); 1173a431f44bSStephan Aßmus fText->ResizeTo(frame.Width(), frame.Height()); 117493ba577cSStephan Aßmus 117593ba577cSStephan Aßmus TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height()); 117693ba577cSStephan Aßmus TRACE("fDivider: %.2f\n", fDivider); 117793ba577cSStephan Aßmus TRACE("fText frame: (%.2f, %.2f, %.2f, %.2f)\n", 117893ba577cSStephan Aßmus frame.left, frame.top, frame.right, frame.bottom); 1179a431f44bSStephan Aßmus } 1180a431f44bSStephan Aßmus 1181a431f44bSStephan Aßmus 1182a431f44bSStephan Aßmus void 11839ecf9d1cSIngo Weinhold BTextControl::_UpdateFrame() 11849ecf9d1cSIngo Weinhold { 1185349c911eSStephan Aßmus CALLED(); 1186349c911eSStephan Aßmus 118709d87d91SAxel Dörfler if (fLayoutData->text_view_layout_item != NULL) { 1188349c911eSStephan Aßmus BRect textFrame = fLayoutData->text_view_layout_item->Frame(); 118909d87d91SAxel Dörfler BRect labelFrame; 119009d87d91SAxel Dörfler if (fLayoutData->label_layout_item != NULL) 119109d87d91SAxel Dörfler labelFrame = fLayoutData->label_layout_item->Frame(); 119209d87d91SAxel Dörfler 119309d87d91SAxel Dörfler BRect frame; 119409d87d91SAxel Dörfler if (labelFrame.IsValid()) { 119509d87d91SAxel Dörfler frame = textFrame | labelFrame; 1196349c911eSStephan Aßmus 1197349c911eSStephan Aßmus // update divider 119809d87d91SAxel Dörfler fDivider = fabs(textFrame.left - labelFrame.left); 119909d87d91SAxel Dörfler } else { 120009d87d91SAxel Dörfler frame = textFrame; 120109d87d91SAxel Dörfler fDivider = 0; 120209d87d91SAxel Dörfler } 1203349c911eSStephan Aßmus 1204b11edca4SJohn Scipione // update our frame 120509d87d91SAxel Dörfler MoveTo(frame.left, frame.top); 1206b11edca4SJohn Scipione BSize oldSize(Bounds().Size()); 120709d87d91SAxel Dörfler ResizeTo(frame.Width(), frame.Height()); 1208b11edca4SJohn Scipione BSize newSize(Bounds().Size()); 1209349c911eSStephan Aßmus 1210349c911eSStephan Aßmus // If the size changes, ResizeTo() will trigger a relayout, otherwise 1211349c911eSStephan Aßmus // we need to do that explicitly. 1212349c911eSStephan Aßmus if (newSize != oldSize) 1213349c911eSStephan Aßmus Relayout(); 12149ecf9d1cSIngo Weinhold } 12159ecf9d1cSIngo Weinhold } 12169ecf9d1cSIngo Weinhold 12179ecf9d1cSIngo Weinhold 1218349c911eSStephan Aßmus void 1219349c911eSStephan Aßmus BTextControl::_ValidateLayoutData() 1220349c911eSStephan Aßmus { 1221349c911eSStephan Aßmus CALLED(); 1222349c911eSStephan Aßmus 1223349c911eSStephan Aßmus if (fLayoutData->valid) 1224349c911eSStephan Aßmus return; 1225349c911eSStephan Aßmus 1226349c911eSStephan Aßmus // cache font height 1227349c911eSStephan Aßmus font_height& fh = fLayoutData->font_info; 1228349c911eSStephan Aßmus GetFontHeight(&fh); 1229349c911eSStephan Aßmus 123060370b9aSJohn Scipione const char* label = Label(); 123160370b9aSJohn Scipione if (label != NULL) { 123260370b9aSJohn Scipione fLayoutData->label_width = ceilf(StringWidth(label)); 1233349c911eSStephan Aßmus fLayoutData->label_height = ceilf(fh.ascent) + ceilf(fh.descent); 1234349c911eSStephan Aßmus } else { 1235349c911eSStephan Aßmus fLayoutData->label_width = 0; 1236349c911eSStephan Aßmus fLayoutData->label_height = 0; 1237349c911eSStephan Aßmus } 1238349c911eSStephan Aßmus 1239349c911eSStephan Aßmus // compute the minimal divider 1240349c911eSStephan Aßmus float divider = 0; 124109d87d91SAxel Dörfler if (fLayoutData->label_width > 0) { 124209d87d91SAxel Dörfler divider = fLayoutData->label_width 124309d87d91SAxel Dörfler + be_control_look->DefaultLabelSpacing(); 124409d87d91SAxel Dörfler } 1245349c911eSStephan Aßmus 1246349c911eSStephan Aßmus // If we shan't do real layout, we let the current divider take influence. 1247349c911eSStephan Aßmus if (!(Flags() & B_SUPPORTS_LAYOUT)) 1248349c911eSStephan Aßmus divider = max_c(divider, fDivider); 1249349c911eSStephan Aßmus 1250349c911eSStephan Aßmus // get the minimal (== preferred) text view size 1251349c911eSStephan Aßmus fLayoutData->text_view_min = fText->MinSize(); 1252349c911eSStephan Aßmus 1253349c911eSStephan Aßmus TRACE("text view min width: %.2f\n", fLayoutData->text_view_min.width); 1254349c911eSStephan Aßmus 1255349c911eSStephan Aßmus // compute our minimal (== preferred) size 1256349c911eSStephan Aßmus BSize min(fLayoutData->text_view_min); 1257349c911eSStephan Aßmus min.width += 2 * kFrameMargin; 1258349c911eSStephan Aßmus min.height += 2 * kFrameMargin; 1259349c911eSStephan Aßmus 1260349c911eSStephan Aßmus if (divider > 0) 1261349c911eSStephan Aßmus min.width += divider; 1262b11edca4SJohn Scipione 1263349c911eSStephan Aßmus if (fLayoutData->label_height > min.height) 1264349c911eSStephan Aßmus min.height = fLayoutData->label_height; 1265349c911eSStephan Aßmus 1266349c911eSStephan Aßmus fLayoutData->min = min; 1267349c911eSStephan Aßmus 1268349c911eSStephan Aßmus fLayoutData->valid = true; 1269c944d11fSStephan Aßmus ResetLayoutInvalidation(); 1270349c911eSStephan Aßmus 1271349c911eSStephan Aßmus TRACE("width: %.2f, height: %.2f\n", min.width, min.height); 1272349c911eSStephan Aßmus } 1273349c911eSStephan Aßmus 1274349c911eSStephan Aßmus 1275b11edca4SJohn Scipione // #pragma mark - BTextControl::LabelLayoutItem 12769ecf9d1cSIngo Weinhold 12779ecf9d1cSIngo Weinhold 12789ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::LabelLayoutItem(BTextControl* parent) 12795c47e35eSAlex Wilson : 12805c47e35eSAlex Wilson fParent(parent), 12819ecf9d1cSIngo Weinhold fFrame() 12829ecf9d1cSIngo Weinhold { 12839ecf9d1cSIngo Weinhold } 12849ecf9d1cSIngo Weinhold 12859ecf9d1cSIngo Weinhold 12865c47e35eSAlex Wilson BTextControl::LabelLayoutItem::LabelLayoutItem(BMessage* from) 12875c47e35eSAlex Wilson : 12885c47e35eSAlex Wilson BAbstractLayoutItem(from), 12895c47e35eSAlex Wilson fParent(NULL), 12905c47e35eSAlex Wilson fFrame() 12915c47e35eSAlex Wilson { 12925c47e35eSAlex Wilson from->FindRect(kFrameField, &fFrame); 12935c47e35eSAlex Wilson } 12945c47e35eSAlex Wilson 12955c47e35eSAlex Wilson 12969ecf9d1cSIngo Weinhold bool 12979ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::IsVisible() 12989ecf9d1cSIngo Weinhold { 12999ecf9d1cSIngo Weinhold return !fParent->IsHidden(fParent); 13009ecf9d1cSIngo Weinhold } 13019ecf9d1cSIngo Weinhold 13029ecf9d1cSIngo Weinhold 13039ecf9d1cSIngo Weinhold void 13049ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::SetVisible(bool visible) 13059ecf9d1cSIngo Weinhold { 13069ecf9d1cSIngo Weinhold // not allowed 13079ecf9d1cSIngo Weinhold } 13089ecf9d1cSIngo Weinhold 13099ecf9d1cSIngo Weinhold 13109ecf9d1cSIngo Weinhold BRect 13119ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::Frame() 13129ecf9d1cSIngo Weinhold { 13139ecf9d1cSIngo Weinhold return fFrame; 13149ecf9d1cSIngo Weinhold } 13159ecf9d1cSIngo Weinhold 13169ecf9d1cSIngo Weinhold 13179ecf9d1cSIngo Weinhold void 13189ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::SetFrame(BRect frame) 13199ecf9d1cSIngo Weinhold { 13209ecf9d1cSIngo Weinhold fFrame = frame; 13219ecf9d1cSIngo Weinhold fParent->_UpdateFrame(); 13229ecf9d1cSIngo Weinhold } 13239ecf9d1cSIngo Weinhold 13249ecf9d1cSIngo Weinhold 13255c47e35eSAlex Wilson void 13265c47e35eSAlex Wilson BTextControl::LabelLayoutItem::SetParent(BTextControl* parent) 13275c47e35eSAlex Wilson { 13285c47e35eSAlex Wilson fParent = parent; 13295c47e35eSAlex Wilson } 13305c47e35eSAlex Wilson 13315c47e35eSAlex Wilson 13329ecf9d1cSIngo Weinhold BView* 13339ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::View() 13349ecf9d1cSIngo Weinhold { 13359ecf9d1cSIngo Weinhold return fParent; 13369ecf9d1cSIngo Weinhold } 13379ecf9d1cSIngo Weinhold 13389ecf9d1cSIngo Weinhold 13399ecf9d1cSIngo Weinhold BSize 13409ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BaseMinSize() 13419ecf9d1cSIngo Weinhold { 1342349c911eSStephan Aßmus fParent->_ValidateLayoutData(); 1343349c911eSStephan Aßmus 1344349c911eSStephan Aßmus if (!fParent->Label()) 13459ecf9d1cSIngo Weinhold return BSize(-1, -1); 13469ecf9d1cSIngo Weinhold 134709d87d91SAxel Dörfler return BSize(fParent->fLayoutData->label_width 134809d87d91SAxel Dörfler + be_control_look->DefaultLabelSpacing(), 1349349c911eSStephan Aßmus fParent->fLayoutData->label_height); 13509ecf9d1cSIngo Weinhold } 13519ecf9d1cSIngo Weinhold 13529ecf9d1cSIngo Weinhold 13539ecf9d1cSIngo Weinhold BSize 13549ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BaseMaxSize() 13559ecf9d1cSIngo Weinhold { 13569ecf9d1cSIngo Weinhold return BaseMinSize(); 13579ecf9d1cSIngo Weinhold } 13589ecf9d1cSIngo Weinhold 13599ecf9d1cSIngo Weinhold 13609ecf9d1cSIngo Weinhold BSize 13619ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BasePreferredSize() 13629ecf9d1cSIngo Weinhold { 13639ecf9d1cSIngo Weinhold return BaseMinSize(); 13649ecf9d1cSIngo Weinhold } 13659ecf9d1cSIngo Weinhold 13669ecf9d1cSIngo Weinhold 13679ecf9d1cSIngo Weinhold BAlignment 13689ecf9d1cSIngo Weinhold BTextControl::LabelLayoutItem::BaseAlignment() 13699ecf9d1cSIngo Weinhold { 13709ecf9d1cSIngo Weinhold return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); 13719ecf9d1cSIngo Weinhold } 13729ecf9d1cSIngo Weinhold 13739ecf9d1cSIngo Weinhold 137409d87d91SAxel Dörfler BRect 137509d87d91SAxel Dörfler BTextControl::LabelLayoutItem::FrameInParent() const 137609d87d91SAxel Dörfler { 137709d87d91SAxel Dörfler return fFrame.OffsetByCopy(-fParent->Frame().left, -fParent->Frame().top); 137809d87d91SAxel Dörfler } 137909d87d91SAxel Dörfler 138009d87d91SAxel Dörfler 13815c47e35eSAlex Wilson status_t 13825c47e35eSAlex Wilson BTextControl::LabelLayoutItem::Archive(BMessage* into, bool deep) const 13835c47e35eSAlex Wilson { 13845c47e35eSAlex Wilson BArchiver archiver(into); 13855c47e35eSAlex Wilson status_t err = BAbstractLayoutItem::Archive(into, deep); 13865c47e35eSAlex Wilson if (err == B_OK) 13875c47e35eSAlex Wilson err = into->AddRect(kFrameField, fFrame); 13885c47e35eSAlex Wilson 13895c47e35eSAlex Wilson return archiver.Finish(err); 13905c47e35eSAlex Wilson } 13915c47e35eSAlex Wilson 13925c47e35eSAlex Wilson 13935c47e35eSAlex Wilson BArchivable* 13945c47e35eSAlex Wilson BTextControl::LabelLayoutItem::Instantiate(BMessage* from) 13955c47e35eSAlex Wilson { 13965c47e35eSAlex Wilson if (validate_instantiation(from, "BTextControl::LabelLayoutItem")) 13975c47e35eSAlex Wilson return new LabelLayoutItem(from); 13985c47e35eSAlex Wilson return NULL; 13995c47e35eSAlex Wilson } 14005c47e35eSAlex Wilson 14015c47e35eSAlex Wilson 1402b11edca4SJohn Scipione // #pragma mark - BTextControl::TextViewLayoutItem 14039ecf9d1cSIngo Weinhold 14049ecf9d1cSIngo Weinhold 14059ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::TextViewLayoutItem(BTextControl* parent) 14065c47e35eSAlex Wilson : 14075c47e35eSAlex Wilson fParent(parent), 14089ecf9d1cSIngo Weinhold fFrame() 14099ecf9d1cSIngo Weinhold { 1410349c911eSStephan Aßmus // by default the part right of the divider shall have an unlimited maximum 1411349c911eSStephan Aßmus // width 1412349c911eSStephan Aßmus SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); 14139ecf9d1cSIngo Weinhold } 14149ecf9d1cSIngo Weinhold 14159ecf9d1cSIngo Weinhold 14165c47e35eSAlex Wilson BTextControl::TextViewLayoutItem::TextViewLayoutItem(BMessage* from) 14175c47e35eSAlex Wilson : 14185c47e35eSAlex Wilson BAbstractLayoutItem(from), 14195c47e35eSAlex Wilson fParent(NULL), 14205c47e35eSAlex Wilson fFrame() 14215c47e35eSAlex Wilson { 14225c47e35eSAlex Wilson from->FindRect(kFrameField, &fFrame); 14235c47e35eSAlex Wilson } 14245c47e35eSAlex Wilson 14255c47e35eSAlex Wilson 14269ecf9d1cSIngo Weinhold bool 14279ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::IsVisible() 14289ecf9d1cSIngo Weinhold { 14299ecf9d1cSIngo Weinhold return !fParent->IsHidden(fParent); 14309ecf9d1cSIngo Weinhold } 14319ecf9d1cSIngo Weinhold 14329ecf9d1cSIngo Weinhold 14339ecf9d1cSIngo Weinhold void 14349ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::SetVisible(bool visible) 14359ecf9d1cSIngo Weinhold { 14369ecf9d1cSIngo Weinhold // not allowed 14379ecf9d1cSIngo Weinhold } 14389ecf9d1cSIngo Weinhold 14399ecf9d1cSIngo Weinhold 14409ecf9d1cSIngo Weinhold BRect 14419ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::Frame() 14429ecf9d1cSIngo Weinhold { 14439ecf9d1cSIngo Weinhold return fFrame; 14449ecf9d1cSIngo Weinhold } 14459ecf9d1cSIngo Weinhold 14469ecf9d1cSIngo Weinhold 14479ecf9d1cSIngo Weinhold void 14489ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::SetFrame(BRect frame) 14499ecf9d1cSIngo Weinhold { 14509ecf9d1cSIngo Weinhold fFrame = frame; 14519ecf9d1cSIngo Weinhold fParent->_UpdateFrame(); 14529ecf9d1cSIngo Weinhold } 14539ecf9d1cSIngo Weinhold 14549ecf9d1cSIngo Weinhold 14555c47e35eSAlex Wilson void 14565c47e35eSAlex Wilson BTextControl::TextViewLayoutItem::SetParent(BTextControl* parent) 14575c47e35eSAlex Wilson { 14585c47e35eSAlex Wilson fParent = parent; 14595c47e35eSAlex Wilson } 14605c47e35eSAlex Wilson 14615c47e35eSAlex Wilson 14629ecf9d1cSIngo Weinhold BView* 14639ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::View() 14649ecf9d1cSIngo Weinhold { 14659ecf9d1cSIngo Weinhold return fParent; 14669ecf9d1cSIngo Weinhold } 14679ecf9d1cSIngo Weinhold 14689ecf9d1cSIngo Weinhold 14699ecf9d1cSIngo Weinhold BSize 14709ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BaseMinSize() 14719ecf9d1cSIngo Weinhold { 1472349c911eSStephan Aßmus fParent->_ValidateLayoutData(); 14739ecf9d1cSIngo Weinhold 1474349c911eSStephan Aßmus BSize size = fParent->fLayoutData->text_view_min; 1475349c911eSStephan Aßmus size.width += 2 * kFrameMargin; 1476349c911eSStephan Aßmus size.height += 2 * kFrameMargin; 14779ecf9d1cSIngo Weinhold 14789ecf9d1cSIngo Weinhold return size; 14799ecf9d1cSIngo Weinhold } 14809ecf9d1cSIngo Weinhold 14819ecf9d1cSIngo Weinhold 14829ecf9d1cSIngo Weinhold BSize 14839ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BaseMaxSize() 14849ecf9d1cSIngo Weinhold { 14859ecf9d1cSIngo Weinhold BSize size(BaseMinSize()); 14869ecf9d1cSIngo Weinhold size.width = B_SIZE_UNLIMITED; 1487b11edca4SJohn Scipione 14889ecf9d1cSIngo Weinhold return size; 14899ecf9d1cSIngo Weinhold } 14909ecf9d1cSIngo Weinhold 14919ecf9d1cSIngo Weinhold 14929ecf9d1cSIngo Weinhold BSize 14939ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BasePreferredSize() 14949ecf9d1cSIngo Weinhold { 14959ecf9d1cSIngo Weinhold BSize size(BaseMinSize()); 14969ecf9d1cSIngo Weinhold // puh, no idea... 14979ecf9d1cSIngo Weinhold size.width = 100; 1498b11edca4SJohn Scipione 14999ecf9d1cSIngo Weinhold return size; 15009ecf9d1cSIngo Weinhold } 15019ecf9d1cSIngo Weinhold 15029ecf9d1cSIngo Weinhold 15039ecf9d1cSIngo Weinhold BAlignment 15049ecf9d1cSIngo Weinhold BTextControl::TextViewLayoutItem::BaseAlignment() 15059ecf9d1cSIngo Weinhold { 15069ecf9d1cSIngo Weinhold return BAlignment(B_ALIGN_USE_FULL_WIDTH, B_ALIGN_USE_FULL_HEIGHT); 15079ecf9d1cSIngo Weinhold } 15089ecf9d1cSIngo Weinhold 15095c47e35eSAlex Wilson 151009d87d91SAxel Dörfler BRect 151109d87d91SAxel Dörfler BTextControl::TextViewLayoutItem::FrameInParent() const 151209d87d91SAxel Dörfler { 151309d87d91SAxel Dörfler return fFrame.OffsetByCopy(-fParent->Frame().left, -fParent->Frame().top); 151409d87d91SAxel Dörfler } 151509d87d91SAxel Dörfler 151609d87d91SAxel Dörfler 15175c47e35eSAlex Wilson status_t 15185c47e35eSAlex Wilson BTextControl::TextViewLayoutItem::Archive(BMessage* into, bool deep) const 15195c47e35eSAlex Wilson { 15205c47e35eSAlex Wilson BArchiver archiver(into); 15215c47e35eSAlex Wilson status_t err = BAbstractLayoutItem::Archive(into, deep); 15225c47e35eSAlex Wilson if (err == B_OK) 15235c47e35eSAlex Wilson err = into->AddRect(kFrameField, fFrame); 15245c47e35eSAlex Wilson 15255c47e35eSAlex Wilson return archiver.Finish(err); 15265c47e35eSAlex Wilson } 15275c47e35eSAlex Wilson 15285c47e35eSAlex Wilson 15295c47e35eSAlex Wilson BArchivable* 15305c47e35eSAlex Wilson BTextControl::TextViewLayoutItem::Instantiate(BMessage* from) 15315c47e35eSAlex Wilson { 15325c47e35eSAlex Wilson if (validate_instantiation(from, "BTextControl::TextViewLayoutItem")) 15335c47e35eSAlex Wilson return new TextViewLayoutItem(from); 1534b11edca4SJohn Scipione 15355c47e35eSAlex Wilson return NULL; 15365c47e35eSAlex Wilson } 15375c47e35eSAlex Wilson 15385c47e35eSAlex Wilson 1539466f2b8fSRene Gollent extern "C" void 15408adaa6c5SJerome Duval B_IF_GCC_2(InvalidateLayout__12BTextControlb, 15418adaa6c5SJerome Duval _ZN12BTextControl16InvalidateLayoutEb)(BView* view, bool descendants) 1542466f2b8fSRene Gollent { 1543f6c8d242SRene Gollent perform_data_layout_invalidated data; 1544f6c8d242SRene Gollent data.descendants = descendants; 1545f6c8d242SRene Gollent 1546f6c8d242SRene Gollent view->Perform(PERFORM_CODE_LAYOUT_INVALIDATED, &data); 1547466f2b8fSRene Gollent } 1548