BStringView: add support for multiline strings
* Actually draw the string at the bottom of the frame. * Unfortunately BStringList cannot be cached because there is no space left in the class. * Change SGI and PNG translators to use it in place of BTextView. Change-Id: I07e12bf1a8dc956d18c9624604c7b63453ad15a2 Reviewed-on: https://review.haiku-os.org/620 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
22e03e588e
commit
800e6fe412
@@ -79,6 +79,7 @@ private:
|
||||
|
||||
private:
|
||||
BSize _ValidatePreferredSize();
|
||||
float _StringWidth(const char* text);
|
||||
|
||||
private:
|
||||
char* fText;
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <MenuItem.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <StringView.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#define PNG_NO_PEDANTIC_WARNINGS
|
||||
@@ -69,13 +68,10 @@ PNGView::PNGView(const BRect &frame, const char *name, uint32 resizeMode,
|
||||
menuField->SetDivider(menuField->StringWidth(menuField->Label()) + 7.0f);
|
||||
menuField->ResizeToPreferred();
|
||||
|
||||
fCopyrightView = new BTextView("PNG copyright");
|
||||
fCopyrightView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
fCopyrightView->SetLowColor(fCopyrightView->ViewColor());
|
||||
fCopyrightView->MakeEditable(false);
|
||||
fCopyrightView->SetWordWrap(false);
|
||||
fCopyrightView->MakeResizable(true);
|
||||
fCopyrightView->SetText(png_get_copyright(NULL));
|
||||
BString pngCopyright = png_get_copyright(NULL);
|
||||
pngCopyright.ReplaceLast("\n", "");
|
||||
BStringView* pngCopyrightView = new BStringView(
|
||||
"PNG copyright", pngCopyright);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
@@ -88,7 +84,7 @@ PNGView::PNGView(const BRect &frame, const char *name, uint32 resizeMode,
|
||||
.AddGlue()
|
||||
.End()
|
||||
.AddGlue()
|
||||
.Add(fCopyrightView);
|
||||
.Add(pngCopyrightView);
|
||||
}
|
||||
|
||||
|
||||
@@ -118,14 +114,6 @@ PNGView::AttachedToWindow()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PNGView::FrameResized(float width, float height)
|
||||
{
|
||||
// This works around a flaw of BTextView
|
||||
fCopyrightView->SetTextRect(fCopyrightView->Bounds());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PNGView::MessageReceived(BMessage *message)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <View.h>
|
||||
|
||||
class BPopUpMenu;
|
||||
class BTextView;
|
||||
|
||||
|
||||
// Config panel messages
|
||||
@@ -33,7 +32,6 @@ class PNGView : public BView {
|
||||
~PNGView();
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void FrameResized(float width, float height);
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
|
||||
private:
|
||||
@@ -41,7 +39,6 @@ class PNGView : public BView {
|
||||
|
||||
private:
|
||||
BPopUpMenu* fInterlaceMenu;
|
||||
BTextView* fCopyrightView;
|
||||
TranslatorSettings* fSettings;
|
||||
// the actual settings for the translator,
|
||||
// shared with the translator
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
#include <PopUpMenu.h>
|
||||
#include <String.h>
|
||||
#include <StringView.h>
|
||||
#include <TextView.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "SGIImage.h"
|
||||
@@ -114,16 +113,11 @@ SGIView::SGIView(const char* name, uint32 flags, TranslatorSettings* settings)
|
||||
BStringView* detailView = new BStringView("details", detail);
|
||||
detailView->SetExplicitAlignment(labelAlignment);
|
||||
|
||||
BTextView* infoView = new BTextView("info");
|
||||
infoView->SetText(BString(B_TRANSLATE("written by:\n"))
|
||||
BStringView* infoView = new BStringView("info",
|
||||
BString(B_TRANSLATE("written by:\n"))
|
||||
.Append(author)
|
||||
.Append(B_TRANSLATE("\nbased on GIMP SGI plugin v1.5:\n"))
|
||||
.Append(kSGICopyright).String());
|
||||
infoView->SetExplicitAlignment(labelAlignment);
|
||||
infoView->SetWordWrap(false);
|
||||
infoView->MakeEditable(false);
|
||||
infoView->MakeResizable(true);
|
||||
infoView->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
@@ -141,12 +135,6 @@ SGIView::SGIView(const char* name, uint32 flags, TranslatorSettings* settings)
|
||||
GetFont(&font);
|
||||
SetExplicitPreferredSize(BSize((font.Size() * 390) / 12,
|
||||
(font.Size() * 180) / 12));
|
||||
|
||||
// TODO: remove this workaround for ticket #4217
|
||||
infoView->SetExplicitPreferredSize(
|
||||
BSize(infoView->LineWidth(3), infoView->TextHeight(0, 80)));
|
||||
infoView->SetExplicitMaxSize(infoView->ExplicitPreferredSize());
|
||||
infoView->SetExplicitMinSize(infoView->ExplicitPreferredSize());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <LayoutUtils.h>
|
||||
#include <Message.h>
|
||||
#include <PropertyInfo.h>
|
||||
#include <StringList.h>
|
||||
#include <View.h>
|
||||
#include <Window.h>
|
||||
|
||||
@@ -55,7 +56,7 @@ BStringView::BStringView(BRect frame, const char* name, const char* text,
|
||||
fText(text ? strdup(text) : NULL),
|
||||
fTruncation(B_NO_TRUNCATION),
|
||||
fAlign(B_ALIGN_LEFT),
|
||||
fPreferredSize(text ? StringWidth(text) : 0.0, -1)
|
||||
fPreferredSize(text ? _StringWidth(text) : 0.0, -1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -66,7 +67,7 @@ BStringView::BStringView(const char* name, const char* text, uint32 flags)
|
||||
fText(text ? strdup(text) : NULL),
|
||||
fTruncation(B_NO_TRUNCATION),
|
||||
fAlign(B_ALIGN_LEFT),
|
||||
fPreferredSize(text ? StringWidth(text) : 0.0, -1)
|
||||
fPreferredSize(text ? _StringWidth(text) : 0.0, -1)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -273,36 +274,41 @@ 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);
|
||||
BStringList lines;
|
||||
BString(fText).Split("\n", false, lines);
|
||||
for (int i = 0; i < lines.CountStrings(); i++) {
|
||||
const char* text = lines.StringAt(i).String();
|
||||
float width = StringWidth(text);
|
||||
BString truncated;
|
||||
if (fTruncation != B_NO_TRUNCATION && width > bounds.Width()) {
|
||||
// The string needs to be truncated
|
||||
// TODO: we should cache this
|
||||
truncated = lines.StringAt(i);
|
||||
TruncateString(&truncated, fTruncation, bounds.Width());
|
||||
text = truncated.String();
|
||||
width = StringWidth(text);
|
||||
}
|
||||
|
||||
float y = (bounds.top + bounds.bottom - ceilf(fontHeight.descent))
|
||||
- ceilf(fontHeight.ascent + fontHeight.descent + fontHeight.leading)
|
||||
* (lines.CountStrings() - i - 1);
|
||||
float x;
|
||||
switch (fAlign) {
|
||||
case B_ALIGN_RIGHT:
|
||||
x = bounds.Width() - width;
|
||||
break;
|
||||
|
||||
case B_ALIGN_CENTER:
|
||||
x = (bounds.Width() - width) / 2.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
x = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
DrawString(text, BPoint(x, y));
|
||||
}
|
||||
|
||||
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() - width;
|
||||
break;
|
||||
|
||||
case B_ALIGN_CENTER:
|
||||
x = (bounds.Width() - width) / 2.0;
|
||||
break;
|
||||
|
||||
default:
|
||||
x = 0.0;
|
||||
break;
|
||||
}
|
||||
|
||||
DrawString(text, BPoint(x, y));
|
||||
}
|
||||
|
||||
|
||||
@@ -391,7 +397,7 @@ BStringView::SetText(const char* text)
|
||||
free(fText);
|
||||
fText = text ? strdup(text) : NULL;
|
||||
|
||||
float newStringWidth = StringWidth(fText);
|
||||
float newStringWidth = _StringWidth(fText);
|
||||
if (fPreferredSize.width != newStringWidth) {
|
||||
fPreferredSize.width = newStringWidth;
|
||||
InvalidateLayout();
|
||||
@@ -476,7 +482,7 @@ BStringView::SetFont(const BFont* font, uint32 mask)
|
||||
{
|
||||
BView::SetFont(font, mask);
|
||||
|
||||
fPreferredSize.width = StringWidth(fText);
|
||||
fPreferredSize.width = _StringWidth(fText);
|
||||
|
||||
Invalidate();
|
||||
InvalidateLayout();
|
||||
@@ -585,8 +591,15 @@ BStringView::_ValidatePreferredSize()
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
|
||||
int32 lines = 0;
|
||||
char* temp = fText;
|
||||
do {
|
||||
temp = strchr(temp + 1, '\n');
|
||||
lines++;
|
||||
} while (temp != NULL);
|
||||
|
||||
fPreferredSize.height = ceilf(fontHeight.ascent + fontHeight.descent
|
||||
+ fontHeight.leading);
|
||||
+ fontHeight.leading) * lines;
|
||||
|
||||
ResetLayoutInvalidation();
|
||||
}
|
||||
@@ -595,6 +608,24 @@ BStringView::_ValidatePreferredSize()
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
BStringView::_StringWidth(const char* text)
|
||||
{
|
||||
if(text == NULL)
|
||||
return 0.0f;
|
||||
|
||||
float maxWidth = 0.0f;
|
||||
BStringList lines;
|
||||
BString(fText).Split("\n", false, lines);
|
||||
for (int i = 0; i < lines.CountStrings(); i++) {
|
||||
float width = StringWidth(lines.StringAt(i));
|
||||
if (maxWidth < width)
|
||||
maxWidth = width;
|
||||
}
|
||||
return maxWidth;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void
|
||||
B_IF_GCC_2(InvalidateLayout__11BStringViewb,
|
||||
_ZN11BStringView16InvalidateLayoutEb)(BView* view, bool descendants)
|
||||
|
||||
Reference in New Issue
Block a user