Showimage: Add zoom level to StatusBar.

* Improve StatusBar graphics (Same style as StyledEdit).
* Resize the StatusBar to best fit.
* Fixes #7394.
This commit is contained in:
Janus 2015-04-07 17:17:32 +00:00
parent be63ec85a8
commit cae52eadac
5 changed files with 199 additions and 94 deletions

View File

@ -11,10 +11,12 @@
#include "ShowImageStatusView.h" #include "ShowImageStatusView.h"
#include <ControlLook.h>
#include <Entry.h> #include <Entry.h>
#include <MenuItem.h> #include <MenuItem.h>
#include <Path.h> #include <Path.h>
#include <PopUpMenu.h> #include <PopUpMenu.h>
#include <ScrollView.h>
#include <tracker_private.h> #include <tracker_private.h>
#include "DirMenu.h" #include "DirMenu.h"
@ -22,60 +24,106 @@
#include "ShowImageView.h" #include "ShowImageView.h"
#include "ShowImageWindow.h" #include "ShowImageWindow.h"
const float kHorzSpacing = 5.f;
ShowImageStatusView::ShowImageStatusView(BRect rect, const char* name,
uint32 resizingMode, uint32 flags) ShowImageStatusView::ShowImageStatusView(BScrollView* scrollView)
: :
BView(rect, name, resizingMode, flags) BView(BRect(), "statusview", B_FOLLOW_BOTTOM | B_FOLLOW_LEFT, B_WILL_DRAW),
fScrollView(scrollView),
fPreferredSize(0.0, 0.0)
{ {
SetViewColor(B_TRANSPARENT_32_BIT); memset(fCellWidth, 0, sizeof(fCellWidth));
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); }
SetHighColor(0, 0, 0, 255);
BFont font;
GetFont(&font); void
font.SetSize(10.0); ShowImageStatusView::AttachedToWindow()
SetFont(&font); {
SetFont(be_plain_font);
SetFontSize(10.0);
BScrollBar* scrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
MoveTo(0.0, scrollBar->Frame().top);
rgb_color color = B_TRANSPARENT_COLOR;
BView* parent = Parent();
if (parent != NULL)
color = parent->ViewColor();
if (color == B_TRANSPARENT_COLOR)
color = ui_color(B_PANEL_BACKGROUND_COLOR);
SetViewColor(color);
ResizeToPreferred();
}
void
ShowImageStatusView::GetPreferredSize(float* _width, float* _height)
{
_ValidatePreferredSize();
if (_width)
*_width = fPreferredSize.width;
if (_height)
*_height = fPreferredSize.height;
}
void
ShowImageStatusView::ResizeToPreferred()
{
float width, height;
GetPreferredSize(&width, &height);
if (Bounds().Width() > width)
width = Bounds().Width();
BView::ResizeTo(width, height);
} }
void void
ShowImageStatusView::Draw(BRect updateRect) ShowImageStatusView::Draw(BRect updateRect)
{ {
rgb_color darkShadow = tint_color(LowColor(), B_DARKEN_2_TINT); if (fPreferredSize.width <= 0)
rgb_color shadow = tint_color(LowColor(), B_DARKEN_1_TINT); return;
rgb_color light = tint_color(LowColor(), B_LIGHTEN_MAX_TINT);
BRect b(Bounds()); if (be_control_look != NULL) {
BRect bounds(Bounds());
be_control_look->DrawMenuBarBackground(this,
bounds, updateRect, ViewColor());
}
BeginLineArray(5); BRect bounds(Bounds());
AddLine(BPoint(b.left, b.top), rgb_color highColor = HighColor();
BPoint(b.right, b.top), darkShadow); SetHighColor(tint_color(ViewColor(), B_DARKEN_2_TINT));
b.top += 1.0; StrokeLine(bounds.LeftTop(), bounds.RightTop());
AddLine(BPoint(b.left, b.top),
BPoint(b.right, b.top), light);
AddLine(BPoint(b.right, b.top + 1.0),
BPoint(b.right, b.bottom), shadow);
AddLine(BPoint(b.right - 1.0, b.bottom),
BPoint(b.left + 1.0, b.bottom), shadow);
AddLine(BPoint(b.left, b.bottom),
BPoint(b.left, b.top + 1.0), light);
EndLineArray();
b.InsetBy(1.0, 1.0); float x = bounds.left;
for (size_t i = 0; i < kStatusCellCount - 1; i++) {
x += fCellWidth[i];
StrokeLine(BPoint(x, bounds.top + 3), BPoint(x, bounds.bottom - 3));
}
// Truncate and layout text SetLowColor(ViewColor());
BString truncated(fText); SetHighColor(highColor);
BFont font;
GetFont(&font);
font.TruncateString(&truncated, B_TRUNCATE_MIDDLE, b.Width() - 4.0);
font_height fh;
font.GetHeight(&fh);
FillRect(b, B_SOLID_LOW); font_height fontHeight;
SetDrawingMode(B_OP_OVER); GetFontHeight(&fontHeight);
DrawString(truncated.String(), BPoint(b.left + 2.0,
floorf(b.top + b.Height() / 2.0 + fh.ascent / 2.0))); x = bounds.left;
float y = (bounds.bottom + bounds.top
+ ceilf(fontHeight.ascent) - ceilf(fontHeight.descent)) / 2;
for (size_t i = 0; i < kStatusCellCount; i++) {
if (fCellText[i].Length() == 0)
continue;
DrawString(fCellText[i], BPoint(x + kHorzSpacing, y));
x += fCellWidth[i];
}
} }
@ -101,11 +149,81 @@ ShowImageStatusView::MouseDown(BPoint where)
void void
ShowImageStatusView::Update(const entry_ref& ref, const BString& text) ShowImageStatusView::Update(const entry_ref& ref, const BString& text,
const BString& imageType, float zoom)
{ {
fText = text;
fRef = ref; fRef = ref;
_SetFrameText(text);
_SetZoomText(zoom);
_SetImageTypeText(imageType);
_ValidatePreferredSize();
Invalidate(); Invalidate();
} }
void
ShowImageStatusView::SetZoom(float zoom)
{
_SetZoomText(zoom);
_ValidatePreferredSize();
Invalidate();
}
void
ShowImageStatusView::_SetFrameText(const BString& text)
{
fCellText[0] = text;
}
void
ShowImageStatusView::_SetZoomText(float zoom)
{
fCellText[1].SetToFormat("%.0f%%", zoom * 100);
}
void
ShowImageStatusView::_SetImageTypeText(const BString& imageType)
{
fCellText[2] = imageType;
}
void
ShowImageStatusView::_ValidatePreferredSize()
{
float orgWidth = fPreferredSize.width;
// width
fPreferredSize.width = 0.f;
for (size_t i = 0; i < kStatusCellCount; i++) {
if (fCellText[i].Length() == 0) {
fCellWidth[i] = 0;
continue;
}
float width = ceilf(StringWidth(fCellText[i]));
if (width > 0)
width += kHorzSpacing * 2;
fCellWidth[i] = width;
fPreferredSize.width += fCellWidth[i];
}
// height
font_height fontHeight;
GetFontHeight(&fontHeight);
fPreferredSize.height = ceilf(fontHeight.ascent + fontHeight.descent
+ fontHeight.leading);
if (fPreferredSize.height < B_H_SCROLL_BAR_HEIGHT)
fPreferredSize.height = B_H_SCROLL_BAR_HEIGHT;
float delta = fPreferredSize.width - orgWidth;
ResizeBy(delta, 0);
BScrollBar* scrollBar = fScrollView->ScrollBar(B_HORIZONTAL);
scrollBar->ResizeBy(-delta, 0);
scrollBar->MoveBy(delta, 0);
}

View File

@ -15,20 +15,37 @@
#include <View.h> #include <View.h>
enum {
kFrameSizeCell,
kZoomCell,
kImageTypeCell,
kStatusCellCount
};
class ShowImageStatusView : public BView { class ShowImageStatusView : public BView {
public: public:
ShowImageStatusView(BRect rect, ShowImageStatusView(BScrollView* scrollView);
const char* name, uint32 resizingMode,
uint32 flags);
virtual void AttachedToWindow();
virtual void GetPreferredSize(float* _width, float* _height);
virtual void ResizeToPreferred();
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
void Update(const entry_ref& ref, void Update(const entry_ref& ref,
const BString& text); const BString& text, const BString& imageType,
float zoom);
private: void SetZoom(float zoom);
BString fText; private:
void _SetFrameText(const BString& text);
void _SetZoomText(float zoom);
void _SetImageTypeText(const BString& imageType);
void _ValidatePreferredSize();
BScrollView* fScrollView;
BSize fPreferredSize;
BString fCellText[kStatusCellCount];
float fCellWidth[kStatusCellCount];
entry_ref fRef; entry_ref fRef;
}; };

View File

@ -1587,6 +1587,10 @@ ShowImageView::SetZoom(float zoom, BPoint where)
offset.y = (int)(where.y * fZoom / oldZoom + 0.5) - offset.y; offset.y = (int)(where.y * fZoom / oldZoom + 0.5) - offset.y;
ScrollTo(offset); ScrollTo(offset);
} }
BMessage message(MSG_UPDATE_STATUS_ZOOM);
message.AddFloat("zoom", fZoom);
_SendMessageToWindow(&message);
} }

View File

@ -230,35 +230,11 @@ ShowImageWindow::ShowImageWindow(BRect frame, const entry_ref& ref,
| B_FRAME_EVENTS); | B_FRAME_EVENTS);
// wrap a scroll view around the view // wrap a scroll view around the view
fScrollView = new BScrollView("image_scroller", fImageView, fScrollView = new BScrollView("image_scroller", fImageView,
B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); B_FOLLOW_ALL, 0, true, true, B_PLAIN_BORDER);
contentView->AddChild(fScrollView); contentView->AddChild(fScrollView);
const int32 kstatusWidth = 190; fStatusView = new ShowImageStatusView(fScrollView);
BRect rect; fScrollView->AddChild(fStatusView);
rect = contentView->Bounds();
rect.top = viewFrame.bottom + 1;
rect.left = viewFrame.left + kstatusWidth;
rect.right = viewFrame.right + 1;
rect.bottom += 1;
BScrollBar* horizontalScrollBar = new BScrollBar(rect, "hscroll",
fImageView, 0, 150, B_HORIZONTAL);
contentView->AddChild(horizontalScrollBar);
rect.left = 0;
rect.right = kstatusWidth - 1;
rect.bottom -= 1;
fStatusView = new ShowImageStatusView(rect, "status_view", B_FOLLOW_BOTTOM,
B_WILL_DRAW);
contentView->AddChild(fStatusView);
rect = contentView->Bounds();
rect.top = viewFrame.top - 1;
rect.left = viewFrame.right + 1;
rect.bottom = viewFrame.bottom + 1;
rect.right += 1;
fVerticalScrollBar = new BScrollBar(rect, "vscroll", fImageView,
0, 150, B_VERTICAL);
contentView->AddChild(fVerticalScrollBar);
// Update minimum window size // Update minimum window size
float toolBarMinWidth = fToolBar->MinSize().width; float toolBarMinWidth = fToolBar->MinSize().width;
@ -973,6 +949,10 @@ ShowImageWindow::MessageReceived(BMessage* message)
fImageView->ZoomOut(); fImageView->ZoomOut();
break; break;
case MSG_UPDATE_STATUS_ZOOM:
fStatusView->SetZoom(fImageView->Zoom());
break;
case kMsgOriginalSize: case kMsgOriginalSize:
if (message->FindInt32("behavior") == BButton::B_TOGGLE_BEHAVIOR) { if (message->FindInt32("behavior") == BButton::B_TOGGLE_BEHAVIOR) {
bool force = (message->FindInt32("be:value") == B_CONTROL_ON); bool force = (message->FindInt32("be:value") == B_CONTROL_ON);
@ -1040,8 +1020,6 @@ ShowImageWindow::MessageReceived(BMessage* message)
fToolBar->MoveBy(0, offset); fToolBar->MoveBy(0, offset);
fScrollView->ResizeBy(0, -offset); fScrollView->ResizeBy(0, -offset);
fScrollView->MoveBy(0, offset); fScrollView->MoveBy(0, offset);
fVerticalScrollBar->ResizeBy(0, -offset);
fVerticalScrollBar->MoveBy(0, offset);
UpdateIfNeeded(); UpdateIfNeeded();
snooze(15000); snooze(15000);
} }
@ -1061,12 +1039,7 @@ ShowImageWindow::MessageReceived(BMessage* message)
frame.top = fToolBar->Frame().bottom + 1; frame.top = fToolBar->Frame().bottom + 1;
fScrollView->MoveTo(fScrollView->Frame().left, frame.top); fScrollView->MoveTo(fScrollView->Frame().left, frame.top);
fScrollView->ResizeTo(fScrollView->Bounds().Width(), fScrollView->ResizeTo(fScrollView->Bounds().Width(),
frame.Height() - B_H_SCROLL_BAR_HEIGHT + 1); frame.Height() + 1);
fVerticalScrollBar->MoveTo(
frame.right - B_V_SCROLL_BAR_WIDTH + 1, frame.top);
fVerticalScrollBar->ResizeTo(
fVerticalScrollBar->Bounds().Width(),
frame.Height() - B_H_SCROLL_BAR_HEIGHT + 1);
} }
break; break;
} }
@ -1085,16 +1058,11 @@ ShowImageWindow::_UpdateStatusText(const BMessage* message)
if (fImageView->Bitmap() != NULL) { if (fImageView->Bitmap() != NULL) {
BRect bounds = fImageView->Bitmap()->Bounds(); BRect bounds = fImageView->Bitmap()->Bounds();
status << bounds.IntegerWidth() + 1 status << bounds.IntegerWidth() + 1
<< "x" << bounds.IntegerHeight() + 1 << ", " << fImageType; << "x" << bounds.IntegerHeight() + 1;
} }
BString text; fStatusView->Update(fNavigator.CurrentRef(), status, fImageType,
if (message != NULL && message->FindString("status", &text) == B_OK fImageView->Zoom());
&& text.Length() > 0) {
status << ", " << text;
}
fStatusView->Update(fNavigator.CurrentRef(), status);
} }
@ -1546,8 +1514,6 @@ ShowImageWindow::_SetToolBarVisible(bool visible, bool animate)
} else { } else {
fScrollView->ResizeBy(0, -diff); fScrollView->ResizeBy(0, -diff);
fScrollView->MoveBy(0, diff); fScrollView->MoveBy(0, diff);
fVerticalScrollBar->ResizeBy(0, -diff);
fVerticalScrollBar->MoveBy(0, diff);
fToolBar->MoveBy(0, diff); fToolBar->MoveBy(0, diff);
if (!visible) if (!visible)
fToolBar->Hide(); fToolBar->Hide();

View File

@ -35,6 +35,7 @@ enum {
MSG_MODIFIED = 'mMOD', MSG_MODIFIED = 'mMOD',
MSG_UPDATE_STATUS = 'mUPS', MSG_UPDATE_STATUS = 'mUPS',
MSG_UPDATE_STATUS_TEXT = 'mUPT', MSG_UPDATE_STATUS_TEXT = 'mUPT',
MSG_UPDATE_STATUS_ZOOM = 'mUPZ',
MSG_SELECTION = 'mSEL', MSG_SELECTION = 'mSEL',
MSG_FILE_NEXT = 'mFLN', MSG_FILE_NEXT = 'mFLN',
MSG_FILE_PREV = 'mFLP', MSG_FILE_PREV = 'mFLP',
@ -118,7 +119,6 @@ private:
BToolBar* fToolBar; BToolBar* fToolBar;
bool fToolBarVisible; bool fToolBarVisible;
BScrollView* fScrollView; BScrollView* fScrollView;
BScrollBar* fVerticalScrollBar;
ShowImageView* fImageView; ShowImageView* fImageView;
ShowImageStatusView* fStatusView; ShowImageStatusView* fStatusView;
ProgressWindow* fProgressWindow; ProgressWindow* fProgressWindow;