* Implemented a lot of layout related methods and resolved a few TODOs by
doing a lot of these things the same way as BMenuField are already doing. Perhaps a private helper class could be refactored from these two controls to avoid duplicating a lot of this code, although there are a few subtle differences here and there. These changes make a BTextControl behave properly in the layout management frame work, in case CreateLabelLayoutItem() and CreateTextViewLayoutItem() are _not_ used to layout the BTextControl. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27584 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -80,12 +80,22 @@ public:
|
|||||||
virtual status_t GetSupportedSuites(BMessage* data);
|
virtual status_t GetSupportedSuites(BMessage* data);
|
||||||
virtual void SetFlags(uint32 flags);
|
virtual void SetFlags(uint32 flags);
|
||||||
|
|
||||||
|
virtual BSize MinSize();
|
||||||
|
virtual BSize MaxSize();
|
||||||
|
virtual BSize PreferredSize();
|
||||||
|
|
||||||
|
virtual void InvalidateLayout(bool descendants = false);
|
||||||
|
|
||||||
BLayoutItem* CreateLabelLayoutItem();
|
BLayoutItem* CreateLabelLayoutItem();
|
||||||
BLayoutItem* CreateTextViewLayoutItem();
|
BLayoutItem* CreateTextViewLayoutItem();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void DoLayout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class LabelLayoutItem;
|
class LabelLayoutItem;
|
||||||
class TextViewLayoutItem;
|
class TextViewLayoutItem;
|
||||||
|
struct LayoutData;
|
||||||
|
|
||||||
friend class _BTextInput_;
|
friend class _BTextInput_;
|
||||||
friend class LabelLayoutItem;
|
friend class LabelLayoutItem;
|
||||||
@@ -108,18 +118,17 @@ private:
|
|||||||
void _LayoutTextView();
|
void _LayoutTextView();
|
||||||
void _UpdateFrame();
|
void _UpdateFrame();
|
||||||
|
|
||||||
|
void _ValidateLayoutData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BPrivate::_BTextInput_* fText;
|
BPrivate::_BTextInput_* fText;
|
||||||
char* fLabel;
|
|
||||||
BMessage* fModificationMessage;
|
BMessage* fModificationMessage;
|
||||||
alignment fLabelAlign;
|
alignment fLabelAlign;
|
||||||
float fDivider;
|
float fDivider;
|
||||||
float fPreviousWidth;
|
|
||||||
float fPreviousHeight;
|
|
||||||
BLayoutItem* fLabelLayoutItem;
|
|
||||||
BLayoutItem* fTextViewLayoutItem;
|
|
||||||
|
|
||||||
uint32 _reserved[5];
|
LayoutData* fLayoutData;
|
||||||
|
|
||||||
|
uint32 _reserved[9];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _TEXT_CONTROL_H
|
#endif // _TEXT_CONTROL_H
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#ifdef TRACE_TEXT_CONTROL
|
#ifdef TRACE_TEXT_CONTROL
|
||||||
# include <FunctionTracer.h>
|
# include <FunctionTracer.h>
|
||||||
static int32 sFunctionDepth = -1;
|
static int32 sFunctionDepth = -1;
|
||||||
# define CALLED(x...) FunctionTracer _ft("BMenuField", __FUNCTION__, \
|
# define CALLED(x...) FunctionTracer _ft("BTextControl", __FUNCTION__, \
|
||||||
sFunctionDepth)
|
sFunctionDepth)
|
||||||
# define TRACE(x...) { BString _to; \
|
# define TRACE(x...) { BString _to; \
|
||||||
_to.Append(' ', (sFunctionDepth + 1) * 2); \
|
_to.Append(' ', (sFunctionDepth + 1) * 2); \
|
||||||
@@ -84,9 +84,36 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct BTextControl::LayoutData {
|
||||||
|
LayoutData(float width, float height)
|
||||||
|
: label_layout_item(NULL),
|
||||||
|
text_view_layout_item(NULL),
|
||||||
|
previous_width(width),
|
||||||
|
previous_height(height),
|
||||||
|
valid(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelLayoutItem* label_layout_item;
|
||||||
|
TextViewLayoutItem* text_view_layout_item;
|
||||||
|
float previous_width; // used in FrameResized() for
|
||||||
|
float previous_height; // invalidation
|
||||||
|
font_height font_info;
|
||||||
|
float label_width;
|
||||||
|
float label_height;
|
||||||
|
BSize min;
|
||||||
|
BSize text_view_min;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
static const int32 kFrameMargin = 2;
|
||||||
|
static const int32 kLabelInputSpacing = 3;
|
||||||
|
|
||||||
|
|
||||||
BTextControl::BTextControl(BRect frame, const char* name, const char* label,
|
BTextControl::BTextControl(BRect frame, const char* name, const char* label,
|
||||||
const char* text, BMessage* message, uint32 mask, uint32 flags)
|
const char* text, BMessage* message, uint32 mask, uint32 flags)
|
||||||
: BControl(frame, name, label, message, mask, flags | B_FRAME_EVENTS)
|
: BControl(frame, name, label, message, mask, flags | B_FRAME_EVENTS)
|
||||||
@@ -347,8 +374,8 @@ BTextControl::Draw(BRect updateRect)
|
|||||||
// label
|
// label
|
||||||
|
|
||||||
if (Label()) {
|
if (Label()) {
|
||||||
font_height fontHeight;
|
_ValidateLayoutData();
|
||||||
GetFontHeight(&fontHeight);
|
font_height& fontHeight = fLayoutData->font_info;
|
||||||
|
|
||||||
float y = Bounds().top + (Bounds().Height() + 1 - fontHeight.ascent
|
float y = Bounds().top + (Bounds().Height() + 1 - fontHeight.ascent
|
||||||
- fontHeight.descent) / 2 + fontHeight.ascent;
|
- fontHeight.descent) / 2 + fontHeight.ascent;
|
||||||
@@ -357,7 +384,7 @@ BTextControl::Draw(BRect updateRect)
|
|||||||
float labelWidth = StringWidth(Label());
|
float labelWidth = StringWidth(Label());
|
||||||
switch (fLabelAlign) {
|
switch (fLabelAlign) {
|
||||||
case B_ALIGN_RIGHT:
|
case B_ALIGN_RIGHT:
|
||||||
x = fDivider - labelWidth - 3.0;
|
x = fDivider - labelWidth - kLabelInputSpacing;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_ALIGN_CENTER:
|
case B_ALIGN_CENTER:
|
||||||
@@ -371,7 +398,7 @@ BTextControl::Draw(BRect updateRect)
|
|||||||
|
|
||||||
BRect labelArea(x, Bounds().top, x + labelWidth, Bounds().bottom);
|
BRect labelArea(x, Bounds().top, x + labelWidth, Bounds().bottom);
|
||||||
if (x < fDivider && updateRect.Intersects(labelArea)) {
|
if (x < fDivider && updateRect.Intersects(labelArea)) {
|
||||||
labelArea.right = fText->Frame().left - 3;
|
labelArea.right = fText->Frame().left - kLabelInputSpacing;
|
||||||
|
|
||||||
BRegion clipRegion(labelArea);
|
BRegion clipRegion(labelArea);
|
||||||
ConstrainClippingRegion(&clipRegion);
|
ConstrainClippingRegion(&clipRegion);
|
||||||
@@ -436,25 +463,15 @@ BTextControl::SetEnabled(bool enabled)
|
|||||||
void
|
void
|
||||||
BTextControl::GetPreferredSize(float *_width, float *_height)
|
BTextControl::GetPreferredSize(float *_width, float *_height)
|
||||||
{
|
{
|
||||||
if (_height) {
|
CALLED();
|
||||||
// we need enough space for the label and the child text view
|
|
||||||
font_height fontHeight;
|
|
||||||
GetFontHeight(&fontHeight);
|
|
||||||
float labelHeight = ceil(fontHeight.ascent + fontHeight.descent
|
|
||||||
+ fontHeight.leading);
|
|
||||||
float textHeight = ceilf(fText->LineHeight(0) + 1.0) + 4.0;
|
|
||||||
|
|
||||||
*_height = max_c(labelHeight, textHeight);
|
_ValidateLayoutData();
|
||||||
}
|
|
||||||
|
|
||||||
if (_width) {
|
if (_width)
|
||||||
*_width = Bounds().Width();
|
*_width = fLayoutData->min.width;
|
||||||
const char* label = Label();
|
|
||||||
if (label) {
|
if (_height)
|
||||||
float width = ceilf(StringWidth(label));
|
*_height = fLayoutData->min.height;
|
||||||
*_width = (width * 1.3) + width + 4.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -583,41 +600,50 @@ BTextControl::FrameResized(float width, float height)
|
|||||||
|
|
||||||
BControl::FrameResized(width, height);
|
BControl::FrameResized(width, height);
|
||||||
|
|
||||||
|
// TODO: this causes flickering still...
|
||||||
|
|
||||||
// changes in width
|
// changes in width
|
||||||
|
|
||||||
BRect bounds = Bounds();
|
BRect bounds = Bounds();
|
||||||
const float border = 2.0f;
|
|
||||||
|
|
||||||
if (bounds.Width() > fPreviousWidth) {
|
if (bounds.Width() > fLayoutData->previous_width) {
|
||||||
// invalidate the region between the old and the new right border
|
// invalidate the region between the old and the new right border
|
||||||
BRect rect = bounds;
|
BRect rect = bounds;
|
||||||
rect.left += fPreviousWidth - border;
|
rect.left += fLayoutData->previous_width - kFrameMargin;
|
||||||
rect.right--;
|
rect.right--;
|
||||||
Invalidate(rect);
|
Invalidate(rect);
|
||||||
} else if (bounds.Width() < fPreviousWidth) {
|
} else if (bounds.Width() < fLayoutData->previous_width) {
|
||||||
// invalidate the region of the new right border
|
// invalidate the region of the new right border
|
||||||
BRect rect = bounds;
|
BRect rect = bounds;
|
||||||
rect.left = rect.right - border;
|
rect.left = rect.right - kFrameMargin;
|
||||||
Invalidate(rect);
|
Invalidate(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// changes in height
|
// changes in height
|
||||||
|
|
||||||
if (bounds.Height() > fPreviousHeight) {
|
if (bounds.Height() > fLayoutData->previous_height) {
|
||||||
// invalidate the region between the old and the new bottom border
|
// invalidate the region between the old and the new bottom border
|
||||||
BRect rect = bounds;
|
BRect rect = bounds;
|
||||||
rect.top += fPreviousHeight - border;
|
rect.top += fLayoutData->previous_height - kFrameMargin;
|
||||||
rect.bottom--;
|
rect.bottom--;
|
||||||
Invalidate(rect);
|
Invalidate(rect);
|
||||||
} else if (bounds.Height() < fPreviousHeight) {
|
// invalidate label area
|
||||||
|
rect = bounds;
|
||||||
|
rect.right = fDivider;
|
||||||
|
Invalidate(rect);
|
||||||
|
} else if (bounds.Height() < fLayoutData->previous_height) {
|
||||||
// invalidate the region of the new bottom border
|
// invalidate the region of the new bottom border
|
||||||
BRect rect = bounds;
|
BRect rect = bounds;
|
||||||
rect.top = rect.bottom - border;
|
rect.top = rect.bottom - kFrameMargin;
|
||||||
|
Invalidate(rect);
|
||||||
|
// invalidate label area
|
||||||
|
rect = bounds;
|
||||||
|
rect.right = fDivider;
|
||||||
Invalidate(rect);
|
Invalidate(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
fPreviousWidth = uint16(bounds.Width());
|
fLayoutData->previous_width = bounds.Width();
|
||||||
fPreviousHeight = uint16(bounds.Height());
|
fLayoutData->previous_height = bounds.Height();
|
||||||
|
|
||||||
TRACE("width: %.2f, height: %.2f\n", bounds.Width(), bounds.Height());
|
TRACE("width: %.2f, height: %.2f\n", bounds.Width(), bounds.Height());
|
||||||
}
|
}
|
||||||
@@ -639,28 +665,130 @@ BTextControl::WindowActivated(bool active)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
BSize
|
||||||
BTextControl::Perform(perform_code d, void *arg)
|
BTextControl::MinSize()
|
||||||
{
|
{
|
||||||
return BControl::Perform(d, arg);
|
CALLED();
|
||||||
|
|
||||||
|
_ValidateLayoutData();
|
||||||
|
return BLayoutUtils::ComposeSize(ExplicitMinSize(), fLayoutData->min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
BTextControl::MaxSize()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
_ValidateLayoutData();
|
||||||
|
|
||||||
|
BSize max = fLayoutData->min;
|
||||||
|
max.width = B_SIZE_UNLIMITED;
|
||||||
|
|
||||||
|
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), max);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
BTextControl::PreferredSize()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
_ValidateLayoutData();
|
||||||
|
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), fLayoutData->min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BTextControl::InvalidateLayout(bool descendants)
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
fLayoutData->valid = false;
|
||||||
|
|
||||||
|
BView::InvalidateLayout(descendants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BLayoutItem*
|
BLayoutItem*
|
||||||
BTextControl::CreateLabelLayoutItem()
|
BTextControl::CreateLabelLayoutItem()
|
||||||
{
|
{
|
||||||
if (!fLabelLayoutItem)
|
if (!fLayoutData->label_layout_item)
|
||||||
fLabelLayoutItem = new LabelLayoutItem(this);
|
fLayoutData->label_layout_item = new LabelLayoutItem(this);
|
||||||
return fLabelLayoutItem;
|
return fLayoutData->label_layout_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BLayoutItem*
|
BLayoutItem*
|
||||||
BTextControl::CreateTextViewLayoutItem()
|
BTextControl::CreateTextViewLayoutItem()
|
||||||
{
|
{
|
||||||
if (!fTextViewLayoutItem)
|
if (!fLayoutData->text_view_layout_item)
|
||||||
fTextViewLayoutItem = new TextViewLayoutItem(this);
|
fLayoutData->text_view_layout_item = new TextViewLayoutItem(this);
|
||||||
return fTextViewLayoutItem;
|
return fLayoutData->text_view_layout_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BTextControl::DoLayout()
|
||||||
|
{
|
||||||
|
// Bail out, if we shan't do layout.
|
||||||
|
if (!(Flags() & B_SUPPORTS_LAYOUT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
// If the user set a layout, we let the base class version call its
|
||||||
|
// hook.
|
||||||
|
if (GetLayout()) {
|
||||||
|
BView::DoLayout();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ValidateLayoutData();
|
||||||
|
|
||||||
|
// validate current size
|
||||||
|
BSize size(Bounds().Size());
|
||||||
|
if (size.width < fLayoutData->min.width)
|
||||||
|
size.width = fLayoutData->min.width;
|
||||||
|
if (size.height < fLayoutData->min.height)
|
||||||
|
size.height = fLayoutData->min.height;
|
||||||
|
|
||||||
|
// divider
|
||||||
|
float divider = 0;
|
||||||
|
if (fLayoutData->label_layout_item && fLayoutData->text_view_layout_item) {
|
||||||
|
// We have layout items. They define the divider location.
|
||||||
|
divider = fLayoutData->text_view_layout_item->Frame().left
|
||||||
|
- fLayoutData->label_layout_item->Frame().left;
|
||||||
|
} else {
|
||||||
|
if (fLayoutData->label_width > 0)
|
||||||
|
divider = fLayoutData->label_width + 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// text view
|
||||||
|
BRect dirty(fText->Frame());
|
||||||
|
BRect textFrame(divider + 1, kFrameMargin, size.width - 2,
|
||||||
|
size.height - kFrameMargin);
|
||||||
|
|
||||||
|
// place the text view and set the divider
|
||||||
|
BLayoutUtils::AlignInFrame(fText, textFrame);
|
||||||
|
|
||||||
|
fDivider = divider;
|
||||||
|
|
||||||
|
// invalidate dirty region
|
||||||
|
dirty = dirty | fText->Frame();
|
||||||
|
dirty.InsetBy(-kFrameMargin, -kFrameMargin);
|
||||||
|
|
||||||
|
Invalidate(dirty);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BTextControl::Perform(perform_code d, void *arg)
|
||||||
|
{
|
||||||
|
return BControl::Perform(d, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -723,10 +851,7 @@ BTextControl::_InitData(const char* label, const char* initialText,
|
|||||||
fModificationMessage = NULL;
|
fModificationMessage = NULL;
|
||||||
fLabelAlign = B_ALIGN_LEFT;
|
fLabelAlign = B_ALIGN_LEFT;
|
||||||
fDivider = 0.0f;
|
fDivider = 0.0f;
|
||||||
fPreviousWidth = bounds.Width();
|
fLayoutData = new LayoutData(bounds.Width(), bounds.Height());
|
||||||
fPreviousHeight = bounds.Height();
|
|
||||||
fLabelLayoutItem = NULL;
|
|
||||||
fTextViewLayoutItem = NULL;
|
|
||||||
|
|
||||||
int32 flags = 0;
|
int32 flags = 0;
|
||||||
|
|
||||||
@@ -755,7 +880,7 @@ BTextControl::_InitData(const char* label, const char* initialText,
|
|||||||
BRect frame(fDivider, bounds.top, bounds.right, bounds.bottom);
|
BRect frame(fDivider, bounds.top, bounds.right, bounds.bottom);
|
||||||
// we are stroking the frame around the text view, which
|
// we are stroking the frame around the text view, which
|
||||||
// is 2 pixels wide
|
// is 2 pixels wide
|
||||||
frame.InsetBy(2.0, 3.0);
|
frame.InsetBy(kFrameMargin, kFrameMargin);
|
||||||
BRect textRect(frame.OffsetToCopy(B_ORIGIN));
|
BRect textRect(frame.OffsetToCopy(B_ORIGIN));
|
||||||
|
|
||||||
fText = new BPrivate::_BTextInput_(frame, textRect,
|
fText = new BPrivate::_BTextInput_(frame, textRect,
|
||||||
@@ -774,14 +899,11 @@ BTextControl::_ValidateLayout()
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
float height;
|
_ValidateLayoutData();
|
||||||
BTextControl::GetPreferredSize(NULL, &height);
|
|
||||||
|
|
||||||
ResizeTo(Bounds().Width(), height);
|
ResizeTo(Bounds().Width(), fLayoutData->min.height);
|
||||||
|
|
||||||
_LayoutTextView();
|
_LayoutTextView();
|
||||||
|
|
||||||
fPreviousHeight = Bounds().Height();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -809,17 +931,81 @@ BTextControl::_LayoutTextView()
|
|||||||
void
|
void
|
||||||
BTextControl::_UpdateFrame()
|
BTextControl::_UpdateFrame()
|
||||||
{
|
{
|
||||||
if (fLabelLayoutItem && fTextViewLayoutItem) {
|
CALLED();
|
||||||
BRect labelFrame = fLabelLayoutItem->Frame();
|
|
||||||
BRect textFrame = fTextViewLayoutItem->Frame();
|
if (fLayoutData->label_layout_item && fLayoutData->text_view_layout_item) {
|
||||||
|
BRect labelFrame = fLayoutData->label_layout_item->Frame();
|
||||||
|
BRect textFrame = fLayoutData->text_view_layout_item->Frame();
|
||||||
|
|
||||||
|
// update divider
|
||||||
|
fDivider = textFrame.left - labelFrame.left;
|
||||||
|
|
||||||
MoveTo(labelFrame.left, labelFrame.top);
|
MoveTo(labelFrame.left, labelFrame.top);
|
||||||
|
BSize oldSize = Bounds().Size();
|
||||||
ResizeTo(textFrame.left + textFrame.Width() - labelFrame.left,
|
ResizeTo(textFrame.left + textFrame.Width() - labelFrame.left,
|
||||||
textFrame.top + textFrame.Height() - labelFrame.top);
|
textFrame.top + textFrame.Height() - labelFrame.top);
|
||||||
SetDivider(textFrame.left - labelFrame.left);
|
BSize newSize = Bounds().Size();
|
||||||
|
|
||||||
|
// If the size changes, ResizeTo() will trigger a relayout, otherwise
|
||||||
|
// we need to do that explicitly.
|
||||||
|
if (newSize != oldSize)
|
||||||
|
Relayout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BTextControl::_ValidateLayoutData()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
if (fLayoutData->valid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// cache font height
|
||||||
|
font_height& fh = fLayoutData->font_info;
|
||||||
|
GetFontHeight(&fh);
|
||||||
|
|
||||||
|
if (Label() != NULL) {
|
||||||
|
fLayoutData->label_width = ceilf(StringWidth(Label()));
|
||||||
|
fLayoutData->label_height = ceilf(fh.ascent) + ceilf(fh.descent);
|
||||||
|
} else {
|
||||||
|
fLayoutData->label_width = 0;
|
||||||
|
fLayoutData->label_height = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the minimal divider
|
||||||
|
float divider = 0;
|
||||||
|
if (fLayoutData->label_width > 0)
|
||||||
|
divider = fLayoutData->label_width + 5;
|
||||||
|
|
||||||
|
// If we shan't do real layout, we let the current divider take influence.
|
||||||
|
if (!(Flags() & B_SUPPORTS_LAYOUT))
|
||||||
|
divider = max_c(divider, fDivider);
|
||||||
|
|
||||||
|
// get the minimal (== preferred) text view size
|
||||||
|
fLayoutData->text_view_min = fText->MinSize();
|
||||||
|
|
||||||
|
TRACE("text view min width: %.2f\n", fLayoutData->text_view_min.width);
|
||||||
|
|
||||||
|
// compute our minimal (== preferred) size
|
||||||
|
BSize min(fLayoutData->text_view_min);
|
||||||
|
min.width += 2 * kFrameMargin;
|
||||||
|
min.height += 2 * kFrameMargin;
|
||||||
|
|
||||||
|
if (divider > 0)
|
||||||
|
min.width += divider;
|
||||||
|
if (fLayoutData->label_height > min.height)
|
||||||
|
min.height = fLayoutData->label_height;
|
||||||
|
|
||||||
|
fLayoutData->min = min;
|
||||||
|
|
||||||
|
fLayoutData->valid = true;
|
||||||
|
|
||||||
|
TRACE("width: %.2f, height: %.2f\n", min.width, min.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -869,17 +1055,13 @@ BTextControl::LabelLayoutItem::View()
|
|||||||
BSize
|
BSize
|
||||||
BTextControl::LabelLayoutItem::BaseMinSize()
|
BTextControl::LabelLayoutItem::BaseMinSize()
|
||||||
{
|
{
|
||||||
// TODO: Cache the info. Might be too expensive for this call.
|
fParent->_ValidateLayoutData();
|
||||||
const char* label = fParent->Label();
|
|
||||||
if (!label)
|
if (!fParent->Label())
|
||||||
return BSize(-1, -1);
|
return BSize(-1, -1);
|
||||||
|
|
||||||
BSize size;
|
return BSize(fParent->fLayoutData->label_width + 5,
|
||||||
fParent->GetPreferredSize(NULL, &size.height);
|
fParent->fLayoutData->label_height);
|
||||||
|
|
||||||
size.width = fParent->StringWidth(label) + 2 * 3 - 1;
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -911,6 +1093,9 @@ BTextControl::TextViewLayoutItem::TextViewLayoutItem(BTextControl* parent)
|
|||||||
: fParent(parent),
|
: fParent(parent),
|
||||||
fFrame()
|
fFrame()
|
||||||
{
|
{
|
||||||
|
// by default the part right of the divider shall have an unlimited maximum
|
||||||
|
// width
|
||||||
|
SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -953,12 +1138,11 @@ BTextControl::TextViewLayoutItem::View()
|
|||||||
BSize
|
BSize
|
||||||
BTextControl::TextViewLayoutItem::BaseMinSize()
|
BTextControl::TextViewLayoutItem::BaseMinSize()
|
||||||
{
|
{
|
||||||
// TODO: Cache the info. Might be too expensive for this call.
|
fParent->_ValidateLayoutData();
|
||||||
BSize size;
|
|
||||||
fParent->GetPreferredSize(NULL, &size.height);
|
|
||||||
|
|
||||||
// mmh, some arbitrary minimal width
|
BSize size = fParent->fLayoutData->text_view_min;
|
||||||
size.width = 30;
|
size.width += 2 * kFrameMargin;
|
||||||
|
size.height += 2 * kFrameMargin;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <InterfaceDefs.h>
|
#include <InterfaceDefs.h>
|
||||||
|
#include <LayoutUtils.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <TextControl.h>
|
#include <TextControl.h>
|
||||||
#include <TextView.h>
|
#include <TextView.h>
|
||||||
@@ -147,6 +148,16 @@ _BTextInput_::MakeFocus(bool state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BSize
|
||||||
|
_BTextInput_::MinSize()
|
||||||
|
{
|
||||||
|
BSize min;
|
||||||
|
min.height = ceilf(LineHeight(0) + 1.0);
|
||||||
|
min.width = min.height * 3;
|
||||||
|
return BLayoutUtils::ComposeSize(ExplicitMinSize(), min);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_BTextInput_::AlignTextRect()
|
_BTextInput_::AlignTextRect()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ virtual void FrameResized(float width, float height);
|
|||||||
virtual void KeyDown(const char *bytes, int32 numBytes);
|
virtual void KeyDown(const char *bytes, int32 numBytes);
|
||||||
virtual void MakeFocus(bool focusState = true);
|
virtual void MakeFocus(bool focusState = true);
|
||||||
|
|
||||||
|
virtual BSize MinSize();
|
||||||
|
|
||||||
void AlignTextRect();
|
void AlignTextRect();
|
||||||
void SetInitialText();
|
void SetInitialText();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user