diff --git a/headers/os/interface/Font.h b/headers/os/interface/Font.h index 7b7cd0ec64..eb7d59c674 100644 --- a/headers/os/interface/Font.h +++ b/headers/os/interface/Font.h @@ -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. */ #ifndef _FONT_H_ @@ -43,6 +43,7 @@ enum { // truncation modes enum { + B_NO_TRUNCATION = ~0U, B_TRUNCATE_END = 0, B_TRUNCATE_BEGINNING = 1, B_TRUNCATE_MIDDLE = 2, @@ -150,7 +151,7 @@ struct font_cache_info { struct tuned_font_info { float size; - float shear; + float shear; float rotation; uint32 flags; uint16 face; @@ -275,7 +276,7 @@ private: friend void _init_global_fonts_(); void _GetExtraFlags() const; - void _GetBoundingBoxes(const char charArray[], + void _GetBoundingBoxes(const char charArray[], int32 numChars, font_metric_mode mode, bool string_escapement, escapement_delta* delta, @@ -313,7 +314,7 @@ status_t get_font_family(int32 index, font_family* name, int32 count_font_styles(font_family name); status_t get_font_style(font_family family, int32 index, font_style* name, 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); bool update_font_families(bool checkOnly); diff --git a/headers/os/interface/StringView.h b/headers/os/interface/StringView.h index eae649252f..820b41a7da 100644 --- a/headers/os/interface/StringView.h +++ b/headers/os/interface/StringView.h @@ -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. */ #ifndef _STRING_VIEW_H @@ -28,6 +28,8 @@ public: const char* Text() const; void SetAlignment(alignment flag); alignment Alignment() const; + void SetTruncation(uint32 truncationMode); + uint32 Truncation() const; virtual void AttachedToWindow(); virtual void DetachedFromWindow(); @@ -80,9 +82,10 @@ private: private: char* fText; - float fStringWidth; + uint32 fTruncation; alignment fAlign; BSize fPreferredSize; }; + #endif // _STRING_VIEW_H diff --git a/src/kits/interface/Font.cpp b/src/kits/interface/Font.cpp index 796b6f5134..804307fe54 100644 --- a/src/kits/interface/Font.cpp +++ b/src/kits/interface/Font.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2014, Haiku, Inc. + * Copyright 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -908,6 +908,9 @@ BFont::GetTunedInfo(int32 index, tuned_font_info* info) const void 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 // array, because the string length increases by 3 bytes in the worst // case scenario. diff --git a/src/kits/interface/StringView.cpp b/src/kits/interface/StringView.cpp index 2cc6f5bd68..e4d1ca7fb5 100644 --- a/src/kits/interface/StringView.cpp +++ b/src/kits/interface/StringView.cpp @@ -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. * * Authors: + * Stephan Aßmus + * Axel Dörfler, axeld@pinc-software.de * Frans van Nispen (xlr8@tref.nl) * Ingo Weinhold - * Stephan Aßmus */ + //! 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), fText(text ? strdup(text) : NULL), - fStringWidth(text ? StringWidth(text) : 0.0), + fTruncation(B_NO_TRUNCATION), 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), fText(text ? strdup(text) : NULL), - fStringWidth(text ? StringWidth(text) : 0.0), + fTruncation(B_NO_TRUNCATION), fAlign(B_ALIGN_LEFT), - fPreferredSize(-1, -1) + fPreferredSize(text ? StringWidth(text) : 0.0, -1) { } @@ -72,18 +74,13 @@ BStringView::BStringView(BMessage* archive) : BView(archive), fText(NULL), - fStringWidth(0.0), - fPreferredSize(-1, -1) + fTruncation(B_NO_TRUNCATION), + fPreferredSize(0, -1) { - int32 align; - if (archive->FindInt32("_align", &align) == B_OK) - fAlign = (alignment)align; - else - fAlign = B_ALIGN_LEFT; + fAlign = (alignment)archive->GetInt32("_align", B_ALIGN_LEFT); + fTruncation = (uint32)archive->GetInt32("_truncation", B_NO_TRUNCATION); - const char* text; - if (archive->FindString("_text", &text) != B_OK) - text = NULL; + const char* text = archive->GetString("_text", NULL); SetText(text); SetFlags(Flags() | B_FULL_UPDATE_ON_RESIZE); @@ -112,15 +109,16 @@ BStringView::Instantiate(BMessage* data) status_t 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) - err = data->AddString("_text", fText); + if (status == B_OK && 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) - err = data->AddInt32("_align", fAlign); - - return err; + return status; } @@ -263,16 +261,28 @@ BStringView::Draw(BRect updateRect) 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) - ceilf(fontHeight.descent)) / 2.0 + ceilf(fontHeight.ascent); float x; switch (fAlign) { case B_ALIGN_RIGHT: - x = bounds.Width() - fStringWidth; + x = bounds.Width() - width; break; case B_ALIGN_CENTER: - x = (bounds.Width() - fStringWidth) / 2.0; + x = (bounds.Width() - width) / 2.0; break; default: @@ -280,7 +290,7 @@ BStringView::Draw(BRect updateRect) 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; float newStringWidth = StringWidth(fText); - if (fStringWidth != newStringWidth) { - fStringWidth = newStringWidth; + if (fPreferredSize.width != newStringWidth) { + fPreferredSize.width = newStringWidth; 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* BStringView::ResolveSpecifier(BMessage* message, int32 index, BMessage* specifier, int32 form, const char* property) @@ -437,7 +464,7 @@ BStringView::SetFont(const BFont* font, uint32 mask) { BView::SetFont(font, mask); - fStringWidth = StringWidth(fText); + fPreferredSize.width = StringWidth(fText); Invalidate(); InvalidateLayout(); @@ -448,7 +475,7 @@ void BStringView::LayoutInvalidated(bool descendants) { // invalidate cached preferred size - fPreferredSize.Set(-1, -1); + fPreferredSize.height = -1; } @@ -541,10 +568,7 @@ BStringView::operator=(const BStringView&) BSize BStringView::_ValidatePreferredSize() { - if (fPreferredSize.width < 0) { - // width - fPreferredSize.width = ceilf(fStringWidth); - + if (fPreferredSize.height < 0) { // height font_height fontHeight; GetFontHeight(&fontHeight);