BStringView: added truncation support.

* Added new truncation mode B_NO_TRUNCATION.
* The Truncation()/SetTruncation() methods itself are Dano-compatible,
  however, there was no B_NO_TRUNCATION.
This commit is contained in:
Axel Dörfler
2015-01-23 21:00:28 +01:00
parent 1bfa46f230
commit 95fdee0bc0
4 changed files with 72 additions and 41 deletions
+5 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2005-2009, Haiku, Inc. All rights reserved. * Copyright 2005-2015, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _FONT_H_ #ifndef _FONT_H_
@@ -43,6 +43,7 @@ enum {
// truncation modes // truncation modes
enum { enum {
B_NO_TRUNCATION = ~0U,
B_TRUNCATE_END = 0, B_TRUNCATE_END = 0,
B_TRUNCATE_BEGINNING = 1, B_TRUNCATE_BEGINNING = 1,
B_TRUNCATE_MIDDLE = 2, B_TRUNCATE_MIDDLE = 2,
@@ -150,7 +151,7 @@ struct font_cache_info {
struct tuned_font_info { struct tuned_font_info {
float size; float size;
float shear; float shear;
float rotation; float rotation;
uint32 flags; uint32 flags;
uint16 face; uint16 face;
@@ -275,7 +276,7 @@ private:
friend void _init_global_fonts_(); friend void _init_global_fonts_();
void _GetExtraFlags() const; void _GetExtraFlags() const;
void _GetBoundingBoxes(const char charArray[], void _GetBoundingBoxes(const char charArray[],
int32 numChars, font_metric_mode mode, int32 numChars, font_metric_mode mode,
bool string_escapement, bool string_escapement,
escapement_delta* delta, escapement_delta* delta,
@@ -313,7 +314,7 @@ status_t get_font_family(int32 index, font_family* name,
int32 count_font_styles(font_family name); int32 count_font_styles(font_family name);
status_t get_font_style(font_family family, int32 index, font_style* name, status_t get_font_style(font_family family, int32 index, font_style* name,
uint32* flags = NULL); uint32* flags = NULL);
status_t get_font_style(font_family family, int32 index, font_style* name, status_t get_font_style(font_family family, int32 index, font_style* name,
uint16* face, uint32* flags = NULL); uint16* face, uint32* flags = NULL);
bool update_font_families(bool checkOnly); bool update_font_families(bool checkOnly);
+5 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2009, Haiku, Inc. All rights reserved. * Copyright 2001-2015, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _STRING_VIEW_H #ifndef _STRING_VIEW_H
@@ -28,6 +28,8 @@ public:
const char* Text() const; const char* Text() const;
void SetAlignment(alignment flag); void SetAlignment(alignment flag);
alignment Alignment() const; alignment Alignment() const;
void SetTruncation(uint32 truncationMode);
uint32 Truncation() const;
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void DetachedFromWindow(); virtual void DetachedFromWindow();
@@ -80,9 +82,10 @@ private:
private: private:
char* fText; char* fText;
float fStringWidth; uint32 fTruncation;
alignment fAlign; alignment fAlign;
BSize fPreferredSize; BSize fPreferredSize;
}; };
#endif // _STRING_VIEW_H #endif // _STRING_VIEW_H
+4 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2014, Haiku, Inc. * Copyright 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -908,6 +908,9 @@ BFont::GetTunedInfo(int32 index, tuned_font_info* info) const
void void
BFont::TruncateString(BString* inOut, uint32 mode, float width) const BFont::TruncateString(BString* inOut, uint32 mode, float width) const
{ {
if (mode == B_NO_TRUNCATION)
return;
// NOTE: Careful, we cannot directly use "inOut->String()" as result // NOTE: Careful, we cannot directly use "inOut->String()" as result
// array, because the string length increases by 3 bytes in the worst // array, because the string length increases by 3 bytes in the worst
// case scenario. // case scenario.
+58 -34
View File
@@ -1,13 +1,15 @@
/* /*
* Copyright 2001-2008, Haiku, Inc. All rights reserved. * Copyright 2001-2015, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Stephan Aßmus <[email protected]>
* Axel Dörfler, [email protected]
* Frans van Nispen ([email protected]) * Frans van Nispen ([email protected])
* Ingo Weinhold <[email protected]> * Ingo Weinhold <[email protected]>
* Stephan Aßmus <[email protected]>
*/ */
//! BStringView draws a non-editable text string. //! BStringView draws a non-editable text string.
@@ -50,9 +52,9 @@ BStringView::BStringView(BRect frame, const char* name, const char* text,
: :
BView(frame, name, resizingMode, flags | B_FULL_UPDATE_ON_RESIZE), BView(frame, name, resizingMode, flags | B_FULL_UPDATE_ON_RESIZE),
fText(text ? strdup(text) : NULL), fText(text ? strdup(text) : NULL),
fStringWidth(text ? StringWidth(text) : 0.0), fTruncation(B_NO_TRUNCATION),
fAlign(B_ALIGN_LEFT), fAlign(B_ALIGN_LEFT),
fPreferredSize(-1, -1) fPreferredSize(text ? StringWidth(text) : 0.0, -1)
{ {
} }
@@ -61,9 +63,9 @@ BStringView::BStringView(const char* name, const char* text, uint32 flags)
: :
BView(name, flags | B_FULL_UPDATE_ON_RESIZE), BView(name, flags | B_FULL_UPDATE_ON_RESIZE),
fText(text ? strdup(text) : NULL), fText(text ? strdup(text) : NULL),
fStringWidth(text ? StringWidth(text) : 0.0), fTruncation(B_NO_TRUNCATION),
fAlign(B_ALIGN_LEFT), fAlign(B_ALIGN_LEFT),
fPreferredSize(-1, -1) fPreferredSize(text ? StringWidth(text) : 0.0, -1)
{ {
} }
@@ -72,18 +74,13 @@ BStringView::BStringView(BMessage* archive)
: :
BView(archive), BView(archive),
fText(NULL), fText(NULL),
fStringWidth(0.0), fTruncation(B_NO_TRUNCATION),
fPreferredSize(-1, -1) fPreferredSize(0, -1)
{ {
int32 align; fAlign = (alignment)archive->GetInt32("_align", B_ALIGN_LEFT);
if (archive->FindInt32("_align", &align) == B_OK) fTruncation = (uint32)archive->GetInt32("_truncation", B_NO_TRUNCATION);
fAlign = (alignment)align;
else
fAlign = B_ALIGN_LEFT;
const char* text; const char* text = archive->GetString("_text", NULL);
if (archive->FindString("_text", &text) != B_OK)
text = NULL;
SetText(text); SetText(text);
SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE); SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE);
@@ -112,15 +109,16 @@ BStringView::Instantiate(BMessage* data)
status_t status_t
BStringView::Archive(BMessage* data, bool deep) const BStringView::Archive(BMessage* data, bool deep) const
{ {
status_t err = BView::Archive(data, deep); status_t status = BView::Archive(data, deep);
if (err == B_OK && fText) if (status == B_OK && fText)
err = data->AddString("_text", fText); status = data->AddString("_text", fText);
if (status == B_OK && fTruncation != B_NO_TRUNCATION)
status = data->AddInt32("_truncation", fTruncation);
if (status == B_OK)
status = data->AddInt32("_align", fAlign);
if (err == B_OK) return status;
err = data->AddInt32("_align", fAlign);
return err;
} }
@@ -263,16 +261,28 @@ BStringView::Draw(BRect updateRect)
BRect bounds = Bounds(); BRect bounds = Bounds();
const char* text = fText;
float width = fPreferredSize.width;
BString truncated;
if (fTruncation != B_NO_TRUNCATION && width > bounds.Width()) {
// The string needs to be truncated
// TODO: we should cache this
truncated = fText;
TruncateString(&truncated, fTruncation, bounds.Width());
text = truncated.String();
width = StringWidth(text);
}
float y = (bounds.top + bounds.bottom - ceilf(fontHeight.ascent) float y = (bounds.top + bounds.bottom - ceilf(fontHeight.ascent)
- ceilf(fontHeight.descent)) / 2.0 + ceilf(fontHeight.ascent); - ceilf(fontHeight.descent)) / 2.0 + ceilf(fontHeight.ascent);
float x; float x;
switch (fAlign) { switch (fAlign) {
case B_ALIGN_RIGHT: case B_ALIGN_RIGHT:
x = bounds.Width() - fStringWidth; x = bounds.Width() - width;
break; break;
case B_ALIGN_CENTER: case B_ALIGN_CENTER:
x = (bounds.Width() - fStringWidth) / 2.0; x = (bounds.Width() - width) / 2.0;
break; break;
default: default:
@@ -280,7 +290,7 @@ BStringView::Draw(BRect updateRect)
break; break;
} }
DrawString(fText, BPoint(x, y)); DrawString(text, BPoint(x, y));
} }
@@ -370,8 +380,8 @@ BStringView::SetText(const char* text)
fText = text ? strdup(text) : NULL; fText = text ? strdup(text) : NULL;
float newStringWidth = StringWidth(fText); float newStringWidth = StringWidth(fText);
if (fStringWidth != newStringWidth) { if (fPreferredSize.width != newStringWidth) {
fStringWidth = newStringWidth; fPreferredSize.width = newStringWidth;
InvalidateLayout(); InvalidateLayout();
} }
@@ -401,6 +411,23 @@ BStringView::Alignment() const
} }
void
BStringView::SetTruncation(uint32 truncationMode)
{
if (fTruncation != truncationMode) {
fTruncation = truncationMode;
Invalidate();
}
}
uint32
BStringView::Truncation() const
{
return fTruncation;
}
BHandler* BHandler*
BStringView::ResolveSpecifier(BMessage* message, int32 index, BStringView::ResolveSpecifier(BMessage* message, int32 index,
BMessage* specifier, int32 form, const char* property) BMessage* specifier, int32 form, const char* property)
@@ -437,7 +464,7 @@ BStringView::SetFont(const BFont* font, uint32 mask)
{ {
BView::SetFont(font, mask); BView::SetFont(font, mask);
fStringWidth = StringWidth(fText); fPreferredSize.width = StringWidth(fText);
Invalidate(); Invalidate();
InvalidateLayout(); InvalidateLayout();
@@ -448,7 +475,7 @@ void
BStringView::LayoutInvalidated(bool descendants) BStringView::LayoutInvalidated(bool descendants)
{ {
// invalidate cached preferred size // invalidate cached preferred size
fPreferredSize.Set(-1, -1); fPreferredSize.height = -1;
} }
@@ -541,10 +568,7 @@ BStringView::operator=(const BStringView&)
BSize BSize
BStringView::_ValidatePreferredSize() BStringView::_ValidatePreferredSize()
{ {
if (fPreferredSize.width < 0) { if (fPreferredSize.height < 0) {
// width
fPreferredSize.width = ceilf(fStringWidth);
// height // height
font_height fontHeight; font_height fontHeight;
GetFontHeight(&fontHeight); GetFontHeight(&fontHeight);