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:
Kacper Kasper
2018-11-03 16:44:10 +00:00
committed by waddlesplash
parent 22e03e588e
commit 800e6fe412
5 changed files with 73 additions and 68 deletions
+1
View File
@@ -79,6 +79,7 @@ private:
private:
BSize _ValidatePreferredSize();
float _StringWidth(const char* text);
private:
char* fText;
+5 -17
View File
@@ -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)
{
-3
View File
@@ -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
+2 -14
View File
@@ -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());
}
+41 -10
View File
@@ -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,20 +274,24 @@ BStringView::Draw(BRect updateRect)
BRect bounds = Bounds();
const char* text = fText;
float width = fPreferredSize.width;
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 = fText;
truncated = lines.StringAt(i);
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 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:
@@ -303,6 +308,7 @@ BStringView::Draw(BRect updateRect)
}
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)