- Scrolling with mouse wheel
- Moving image with third mouse button pressed - Added pop up menu with contents of View menu of menu bar - Center image in full screen mode - Added Select None menu item - To avoid flickering, disabled caption during moving image with mouse- Added key bindings: - Cursor keys: moves image - Enter or space bar: next file - Backspace: previous file - Escape: Stops slide show - SHIFT + first mouse button: simulate third mouse button - CONTROL + first mouse button: simulates second mouse button git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5322 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -40,6 +40,7 @@ const uint32 MSG_OUTPUT_TYPE = 'BTMN';
|
|||||||
const uint32 MSG_SAVE_PANEL = 'mFSP';
|
const uint32 MSG_SAVE_PANEL = 'mFSP';
|
||||||
const uint32 MSG_CLEAR_SELECT = 'mCSL';
|
const uint32 MSG_CLEAR_SELECT = 'mCSL';
|
||||||
const uint32 MSG_SELECT_ALL = 'mSAL';
|
const uint32 MSG_SELECT_ALL = 'mSAL';
|
||||||
|
const uint32 MSG_SELECT_NONE = 'mSNO';
|
||||||
const uint32 MSG_DITHER_IMAGE = 'mDIM';
|
const uint32 MSG_DITHER_IMAGE = 'mDIM';
|
||||||
const uint32 MSG_UPDATE_STATUS = 'mUPS';
|
const uint32 MSG_UPDATE_STATUS = 'mUPS';
|
||||||
const uint32 MSG_PAGE_FIRST = 'mPGF';
|
const uint32 MSG_PAGE_FIRST = 'mPGF';
|
||||||
|
|||||||
@@ -46,9 +46,12 @@
|
|||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
#include <Clipboard.h>
|
#include <Clipboard.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
|
||||||
|
|
||||||
#include "ShowImageConstants.h"
|
#include "ShowImageConstants.h"
|
||||||
#include "ShowImageView.h"
|
#include "ShowImageView.h"
|
||||||
|
#include "ShowImageWindow.h"
|
||||||
|
|
||||||
#ifndef min
|
#ifndef min
|
||||||
#define min(a,b) ((a)>(b)?(b):(a))
|
#define min(a,b) ((a)>(b)?(b):(a))
|
||||||
@@ -156,11 +159,14 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
|
|||||||
fAnimateSelection = true;
|
fAnimateSelection = true;
|
||||||
fbHasSelection = false;
|
fbHasSelection = false;
|
||||||
fResizeToViewBounds = false;
|
fResizeToViewBounds = false;
|
||||||
|
fHAlignment = B_ALIGN_LEFT;
|
||||||
|
fVAlignment = B_ALIGN_TOP;
|
||||||
fSlideShow = false;
|
fSlideShow = false;
|
||||||
SetSlideShowDelay(3); // 3 seconds
|
SetSlideShowDelay(3); // 3 seconds
|
||||||
fBeginDrag = false;
|
fBeginDrag = false;
|
||||||
fShowCaption = false;
|
fShowCaption = false;
|
||||||
fZoom = 1.0;
|
fZoom = 1.0;
|
||||||
|
fMovesImage = false;
|
||||||
|
|
||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
SetHighColor(kborderColor);
|
SetHighColor(kborderColor);
|
||||||
@@ -295,6 +301,19 @@ ShowImageView::ResizeToViewBounds(bool resize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::SetAlignment(alignment horizontal, vertical_alignment vertical)
|
||||||
|
{
|
||||||
|
bool hasChanged;
|
||||||
|
hasChanged = fHAlignment != horizontal || fVAlignment != vertical;
|
||||||
|
if (hasChanged) {
|
||||||
|
fHAlignment = horizontal;
|
||||||
|
fVAlignment = vertical;
|
||||||
|
FixupScrollBars();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BBitmap *
|
BBitmap *
|
||||||
ShowImageView::GetBitmap()
|
ShowImageView::GetBitmap()
|
||||||
{
|
{
|
||||||
@@ -346,29 +365,54 @@ BRect
|
|||||||
ShowImageView::AlignBitmap() const
|
ShowImageView::AlignBitmap() const
|
||||||
{
|
{
|
||||||
BRect rect(fpBitmap->Bounds());
|
BRect rect(fpBitmap->Bounds());
|
||||||
|
float width, height;
|
||||||
|
width = Bounds().Width()-2*PEN_SIZE;
|
||||||
|
height = Bounds().Height()-2*PEN_SIZE;
|
||||||
|
if (width == 0 || height == 0) return rect;
|
||||||
if (fResizeToViewBounds) {
|
if (fResizeToViewBounds) {
|
||||||
float width, height;
|
float s;
|
||||||
width = Bounds().Width()-2*PEN_SIZE;
|
s = width / rect.Width();
|
||||||
height = Bounds().Height()-2*PEN_SIZE;
|
|
||||||
if (width > 0 && height > 0) {
|
|
||||||
float s;
|
|
||||||
s = width / rect.Width();
|
|
||||||
|
|
||||||
if (s * rect.Height() <= height) {
|
if (s * rect.Height() <= height) {
|
||||||
rect.right = width;
|
rect.right = width;
|
||||||
rect.bottom = s * rect.Height();
|
rect.bottom = s * rect.Height();
|
||||||
// center horizontally
|
// center vertically
|
||||||
rect.OffsetBy(0, (height - rect.Height()) / 2);
|
rect.OffsetBy(0, (height - rect.Height()) / 2);
|
||||||
} else {
|
} else {
|
||||||
rect.right = height / rect.Height() * rect.Width();
|
rect.right = height / rect.Height() * rect.Width();
|
||||||
rect.bottom = height;
|
rect.bottom = height;
|
||||||
// center vertically
|
// center horizontally
|
||||||
rect.OffsetBy((width - rect.Width()) / 2, 0);
|
rect.OffsetBy((width - rect.Width()) / 2, 0);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rect.right *= fZoom; rect.bottom *= fZoom;
|
// zoom image
|
||||||
rect.OffsetBy(BORDER_WIDTH, BORDER_WIDTH);
|
rect.right = (rect.right+1)*fZoom-1;
|
||||||
|
rect.bottom = (rect.bottom+1)*fZoom-1;
|
||||||
|
// align
|
||||||
|
switch (fHAlignment) {
|
||||||
|
case B_ALIGN_CENTER:
|
||||||
|
if (width > rect.Width()) {
|
||||||
|
rect.OffsetBy((width - rect.Width()) / 2.0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
case B_ALIGN_LEFT:
|
||||||
|
rect.OffsetBy(BORDER_WIDTH, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (fVAlignment) {
|
||||||
|
case B_ALIGN_MIDDLE:
|
||||||
|
if (height > rect.Height()) {
|
||||||
|
rect.OffsetBy(0, (height - rect.Height()) / 2.0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// fall through
|
||||||
|
default:
|
||||||
|
case B_ALIGN_TOP:
|
||||||
|
rect.OffsetBy(0, BORDER_WIDTH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rect.OffsetBy(PEN_SIZE, PEN_SIZE);
|
rect.OffsetBy(PEN_SIZE, PEN_SIZE);
|
||||||
return rect;
|
return rect;
|
||||||
@@ -486,7 +530,8 @@ ShowImageView::Draw(BRect updateRect)
|
|||||||
// Draw image
|
// Draw image
|
||||||
DrawBitmap(fpBitmap, fpBitmap->Bounds(), rect);
|
DrawBitmap(fpBitmap, fpBitmap->Bounds(), rect);
|
||||||
|
|
||||||
if (fShowCaption) {
|
if (fShowCaption && !fMovesImage) {
|
||||||
|
// to avoid flickering, disabled during moving with mouse
|
||||||
DrawCaption();
|
DrawCaption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,14 +764,54 @@ ShowImageView::HandleDrop(BMessage* msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::MouseDown(BPoint point)
|
ShowImageView::MoveImage()
|
||||||
{
|
{
|
||||||
point = ViewToImage(point);
|
BPoint point, delta;
|
||||||
|
uint32 buttons;
|
||||||
|
// get CURRENT position
|
||||||
|
GetMouse(&point, &buttons);
|
||||||
|
point = ConvertToScreen(point);
|
||||||
|
delta = fFirstPoint - point;
|
||||||
|
fFirstPoint = point;
|
||||||
|
ScrollRestrictedBy(delta.x, delta.y);
|
||||||
|
// in case we miss MouseUp
|
||||||
|
if ((GetMouseButtons() & B_TERTIARY_MOUSE_BUTTON) == 0) {
|
||||||
|
fMovesImage = false;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32
|
||||||
|
ShowImageView::GetMouseButtons()
|
||||||
|
{
|
||||||
|
uint32 buttons;
|
||||||
|
BPoint point;
|
||||||
|
GetMouse(&point, &buttons);
|
||||||
|
if (buttons == B_PRIMARY_MOUSE_BUTTON) {
|
||||||
|
if ((modifiers() & B_CONTROL_KEY) != 0) {
|
||||||
|
buttons = B_SECONDARY_MOUSE_BUTTON; // simulate second button
|
||||||
|
} else if ((modifiers() & B_SHIFT_KEY) != 0) {
|
||||||
|
buttons = B_TERTIARY_MOUSE_BUTTON; // simulate third button
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buttons;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::MouseDown(BPoint position)
|
||||||
|
{
|
||||||
|
BPoint point;
|
||||||
|
uint32 buttons;
|
||||||
|
MakeFocus(true);
|
||||||
|
|
||||||
|
point = ViewToImage(position);
|
||||||
|
buttons = GetMouseButtons();
|
||||||
|
|
||||||
if (fbHasSelection && fSelectionRect.Contains(point)) {
|
if (fbHasSelection && fSelectionRect.Contains(point) &&
|
||||||
|
(buttons & (B_PRIMARY_MOUSE_BUTTON | B_SECONDARY_MOUSE_BUTTON))) {
|
||||||
// delay drag until mouse is moved
|
// delay drag until mouse is moved
|
||||||
fBeginDrag = true; fFirstPoint = point;
|
fBeginDrag = true; fFirstPoint = point;
|
||||||
} else {
|
} else if (buttons == B_PRIMARY_MOUSE_BUTTON) {
|
||||||
// begin new selection
|
// begin new selection
|
||||||
fMakesSelection = true;
|
fMakesSelection = true;
|
||||||
fbHasSelection = true;
|
fbHasSelection = true;
|
||||||
@@ -735,6 +820,14 @@ ShowImageView::MouseDown(BPoint point)
|
|||||||
fFirstPoint = point;
|
fFirstPoint = point;
|
||||||
fSelectionRect.Set(point.x, point.y, point.x, point.y);
|
fSelectionRect.Set(point.x, point.y, point.x, point.y);
|
||||||
Invalidate();
|
Invalidate();
|
||||||
|
} else if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||||
|
ShowPopUpMenu(ConvertToScreen(position));
|
||||||
|
} else if (buttons == B_TERTIARY_MOUSE_BUTTON) {
|
||||||
|
// move image in window
|
||||||
|
SetMouseEventMask(B_POINTER_EVENTS);
|
||||||
|
fMovesImage = true;
|
||||||
|
fFirstPoint = ConvertToScreen(position);
|
||||||
|
Invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,6 +860,8 @@ ShowImageView::MouseMoved(BPoint point, uint32 state, const BMessage *pmsg)
|
|||||||
{
|
{
|
||||||
if (fMakesSelection) {
|
if (fMakesSelection) {
|
||||||
UpdateSelectionRect(point, false);
|
UpdateSelectionRect(point, false);
|
||||||
|
} else if (fMovesImage) {
|
||||||
|
MoveImage();
|
||||||
} else {
|
} else {
|
||||||
BeginDrag(point);
|
BeginDrag(point);
|
||||||
}
|
}
|
||||||
@@ -778,13 +873,143 @@ ShowImageView::MouseUp(BPoint point)
|
|||||||
if (fMakesSelection) {
|
if (fMakesSelection) {
|
||||||
UpdateSelectionRect(point, true);
|
UpdateSelectionRect(point, true);
|
||||||
fMakesSelection = false;
|
fMakesSelection = false;
|
||||||
|
} else if (fMovesImage) {
|
||||||
|
MoveImage();
|
||||||
|
if (fMovesImage) {
|
||||||
|
fMovesImage = false;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
BeginDrag(point);
|
BeginDrag(point);
|
||||||
|
fBeginDrag = false;
|
||||||
}
|
}
|
||||||
//fBeginDrag = false;
|
|
||||||
AnimateSelection(true);
|
AnimateSelection(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
ShowImageView::LimitToRange(float v, orientation o, bool absolute)
|
||||||
|
{
|
||||||
|
BScrollBar* psb = ScrollBar(o);
|
||||||
|
if (psb) {
|
||||||
|
float min, max, pos;
|
||||||
|
pos = v;
|
||||||
|
if (!absolute) {
|
||||||
|
pos += psb->Value();
|
||||||
|
}
|
||||||
|
psb->GetRange(&min, &max);
|
||||||
|
if (pos < min) {
|
||||||
|
pos = min;
|
||||||
|
} else if (pos > max) {
|
||||||
|
pos = max;
|
||||||
|
}
|
||||||
|
v = pos;
|
||||||
|
if (!absolute) {
|
||||||
|
v -= psb->Value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::ScrollRestricted(float x, float y, bool absolute)
|
||||||
|
{
|
||||||
|
if (fResizeToViewBounds) return;
|
||||||
|
|
||||||
|
if (x != 0) {
|
||||||
|
x = LimitToRange(x, B_HORIZONTAL, absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y != 0) {
|
||||||
|
y = LimitToRange(y, B_VERTICAL, absolute);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScrollBy(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX method is not unused
|
||||||
|
void
|
||||||
|
ShowImageView::ScrollRestrictedTo(float x, float y)
|
||||||
|
{
|
||||||
|
ScrollRestricted(x, y, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::ScrollRestrictedBy(float x, float y)
|
||||||
|
{
|
||||||
|
ScrollRestricted(x, y, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::KeyDown (const char * bytes, int32 numBytes)
|
||||||
|
{
|
||||||
|
if (numBytes == 1) {
|
||||||
|
switch (*bytes) {
|
||||||
|
case B_DOWN_ARROW:
|
||||||
|
ScrollRestrictedBy(0, 10); Invalidate();
|
||||||
|
break;
|
||||||
|
case B_UP_ARROW:
|
||||||
|
ScrollRestrictedBy(0, -10); Invalidate();
|
||||||
|
break;
|
||||||
|
case B_LEFT_ARROW:
|
||||||
|
ScrollRestrictedBy(-10, 0); Invalidate();
|
||||||
|
break;
|
||||||
|
case B_RIGHT_ARROW:
|
||||||
|
ScrollRestrictedBy(10, 0); Invalidate();
|
||||||
|
break;
|
||||||
|
case B_SPACE:
|
||||||
|
case B_ENTER:
|
||||||
|
NextFile();
|
||||||
|
break;
|
||||||
|
case B_BACKSPACE:
|
||||||
|
PrevFile();
|
||||||
|
break;
|
||||||
|
case B_HOME:
|
||||||
|
break;
|
||||||
|
case B_END:
|
||||||
|
break;
|
||||||
|
case B_ESCAPE:
|
||||||
|
if (fSlideShow) {
|
||||||
|
BMessenger msgr(Window());
|
||||||
|
msgr.SendMessage(MSG_SLIDE_SHOW);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::MouseWheelChanged(BMessage *msg)
|
||||||
|
{
|
||||||
|
float dy, dx;
|
||||||
|
float x, y;
|
||||||
|
x = 0; y = 0;
|
||||||
|
if (msg->FindFloat("be:wheel_delta_x", &dx) == B_OK) {
|
||||||
|
x = dx > 0 ? 20 : -20;
|
||||||
|
}
|
||||||
|
if (msg->FindFloat("be:wheel_delta_y", &dy) == B_OK) {
|
||||||
|
y = dy > 0 ? 20 : -20;
|
||||||
|
}
|
||||||
|
ScrollRestrictedBy(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::ShowPopUpMenu(BPoint screen)
|
||||||
|
{
|
||||||
|
BPopUpMenu* menu = new BPopUpMenu("PopUpMenu");
|
||||||
|
menu->SetAsyncAutoDestruct(true);
|
||||||
|
menu->SetRadioMode(false);
|
||||||
|
|
||||||
|
ShowImageWindow* showImage = dynamic_cast<ShowImageWindow*>(Window());
|
||||||
|
if (showImage) {
|
||||||
|
showImage->BuildViewMenu(menu);
|
||||||
|
}
|
||||||
|
menu->AddSeparatorItem();
|
||||||
|
menu->AddItem(new BMenuItem("Cancel", 0, 0));
|
||||||
|
|
||||||
|
screen -= BPoint(10, 10);
|
||||||
|
menu->Go(screen, true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::MessageReceived(BMessage *pmsg)
|
ShowImageView::MessageReceived(BMessage *pmsg)
|
||||||
{
|
{
|
||||||
@@ -792,6 +1017,9 @@ ShowImageView::MessageReceived(BMessage *pmsg)
|
|||||||
case B_COPY_TARGET:
|
case B_COPY_TARGET:
|
||||||
HandleDrop(pmsg);
|
HandleDrop(pmsg);
|
||||||
break;
|
break;
|
||||||
|
case B_MOUSE_WHEEL_CHANGED:
|
||||||
|
MouseWheelChanged(pmsg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BView::MessageReceived(pmsg);
|
BView::MessageReceived(pmsg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ public:
|
|||||||
void SetImage(const entry_ref *pref);
|
void SetImage(const entry_ref *pref);
|
||||||
void SetShowCaption(bool show);
|
void SetShowCaption(bool show);
|
||||||
void ResizeToViewBounds(bool resize);
|
void ResizeToViewBounds(bool resize);
|
||||||
|
bool GetResizeToViewBounds() const { return fResizeToViewBounds; }
|
||||||
|
void SetAlignment(alignment horizontal, vertical_alignment vertical);
|
||||||
BBitmap *GetBitmap();
|
BBitmap *GetBitmap();
|
||||||
void GetName(BString *name);
|
void GetName(BString *name);
|
||||||
void GetPath(BString *name);
|
void GetPath(BString *name);
|
||||||
@@ -57,6 +59,8 @@ public:
|
|||||||
virtual void MouseDown(BPoint point);
|
virtual void MouseDown(BPoint point);
|
||||||
virtual void MouseMoved(BPoint point, uint32 state, const BMessage *pmsg);
|
virtual void MouseMoved(BPoint point, uint32 state, const BMessage *pmsg);
|
||||||
virtual void MouseUp(BPoint point);
|
virtual void MouseUp(BPoint point);
|
||||||
|
virtual void KeyDown(const char *bytes, int32 numBytes);
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *pmsg);
|
virtual void MessageReceived(BMessage *pmsg);
|
||||||
|
|
||||||
void FixupScrollBars();
|
void FixupScrollBars();
|
||||||
@@ -77,6 +81,7 @@ public:
|
|||||||
bool NextFile();
|
bool NextFile();
|
||||||
bool PrevFile();
|
bool PrevFile();
|
||||||
void SetSlideShowDelay(float seconds);
|
void SetSlideShowDelay(float seconds);
|
||||||
|
bool SlideShowStarted() const { return fSlideShow; }
|
||||||
void StartSlideShow();
|
void StartSlideShow();
|
||||||
void StopSlideShow();
|
void StopSlideShow();
|
||||||
void SetZoom(float zoom);
|
void SetZoom(float zoom);
|
||||||
@@ -124,10 +129,18 @@ private:
|
|||||||
void SendInMessage(BMessage* msg, BBitmap* bitmap, translation_format* format);
|
void SendInMessage(BMessage* msg, BBitmap* bitmap, translation_format* format);
|
||||||
bool OutputFormatForType(BBitmap* bitmap, const char* type, translation_format* format);
|
bool OutputFormatForType(BBitmap* bitmap, const char* type, translation_format* format);
|
||||||
void HandleDrop(BMessage* msg);
|
void HandleDrop(BMessage* msg);
|
||||||
|
void MoveImage();
|
||||||
|
uint32 GetMouseButtons();
|
||||||
void UpdateSelectionRect(BPoint point, bool final);
|
void UpdateSelectionRect(BPoint point, bool final);
|
||||||
void DrawBorder(BRect border);
|
void DrawBorder(BRect border);
|
||||||
void DrawCaption();
|
void DrawCaption();
|
||||||
void DrawSelectionBox(BRect &rect);
|
void DrawSelectionBox(BRect &rect);
|
||||||
|
float LimitToRange(float v, orientation o, bool absolute);
|
||||||
|
void ScrollRestricted(float x, float y, bool absolute);
|
||||||
|
void ScrollRestrictedTo(float x, float y);
|
||||||
|
void ScrollRestrictedBy(float x, float y);
|
||||||
|
void MouseWheelChanged(BMessage* msg);
|
||||||
|
void ShowPopUpMenu(BPoint screen);
|
||||||
|
|
||||||
entry_ref fCurrentRef;
|
entry_ref fCurrentRef;
|
||||||
int32 fDocumentIndex;
|
int32 fDocumentIndex;
|
||||||
@@ -135,10 +148,13 @@ private:
|
|||||||
BBitmap *fpBitmap;
|
BBitmap *fpBitmap;
|
||||||
float fZoom;
|
float fZoom;
|
||||||
bool fResizeToViewBounds;
|
bool fResizeToViewBounds;
|
||||||
|
alignment fHAlignment;
|
||||||
|
vertical_alignment fVAlignment;
|
||||||
float fLeft; // the origin of the image in the view
|
float fLeft; // the origin of the image in the view
|
||||||
float fTop;
|
float fTop;
|
||||||
float fScaleX;
|
float fScaleX;
|
||||||
float fScaleY;
|
float fScaleY;
|
||||||
|
bool fMovesImage;
|
||||||
bool fBeginDrag;
|
bool fBeginDrag;
|
||||||
bool fMakesSelection; // is a selection being made
|
bool fMakesSelection; // is a selection being made
|
||||||
BPoint fFirstPoint; // first point in image space of selection
|
BPoint fFirstPoint; // first point in image space of selection
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
|
|||||||
fFullScreen = false;
|
fFullScreen = false;
|
||||||
fShowCaption = true; // XXX what is best for default?
|
fShowCaption = true; // XXX what is best for default?
|
||||||
fPrintSettings = NULL;
|
fPrintSettings = NULL;
|
||||||
|
fpImageView = NULL;
|
||||||
|
|
||||||
// create menu bar
|
// create menu bar
|
||||||
fpBar = new BMenuBar(BRect(0, 0, Bounds().right, 20), "menu_bar");
|
fpBar = new BMenuBar(BRect(0, 0, Bounds().right, 20), "menu_bar");
|
||||||
@@ -115,6 +116,7 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
|
|||||||
|
|
||||||
fpImageView->FlushToLeftTop();
|
fpImageView->FlushToLeftTop();
|
||||||
WindowRedimension(fpImageView->GetBitmap());
|
WindowRedimension(fpImageView->GetBitmap());
|
||||||
|
fpImageView->MakeFocus(true); // to receive KeyDown messages
|
||||||
Show();
|
Show();
|
||||||
} else {
|
} else {
|
||||||
BAlert* alert;
|
BAlert* alert;
|
||||||
@@ -173,6 +175,55 @@ ShowImageWindow::UpdateRecentDocumentsMenu()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageWindow::BuildViewMenu(BMenu *pmenu)
|
||||||
|
{
|
||||||
|
AddItemMenu(pmenu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
|
||||||
|
if (fpImageView) {
|
||||||
|
// when invoked from SlideShowView
|
||||||
|
MarkMenuItem(pmenu, MSG_SLIDE_SHOW, fpImageView->SlideShowStarted());
|
||||||
|
}
|
||||||
|
BMenu* pDelay = new BMenu("Slide Delay");
|
||||||
|
if (fpImageView == NULL) {
|
||||||
|
// when invoked from this window
|
||||||
|
fpSlideShowDelay = pDelay;
|
||||||
|
}
|
||||||
|
pDelay->SetRadioMode(true);
|
||||||
|
// Note: ShowImage loades images in window thread so it becomes unresponsive if
|
||||||
|
// slide show delay is too short! (Especially if loading the image takes as long as
|
||||||
|
// or longer than the slide show delay). Should load in background thread!
|
||||||
|
// AddDelayItem(pDelay, "Half a Second", 0.5, false);
|
||||||
|
// AddDelayItem(pDelay, "One Second", 1, false);
|
||||||
|
// AddDelayItem(pDelay, "Two Second", 2, false);
|
||||||
|
AddDelayItem(pDelay, "Three Seconds", 3, true);
|
||||||
|
AddDelayItem(pDelay, "Four Second", 4, false);
|
||||||
|
AddDelayItem(pDelay, "Five Seconds", 5, false);
|
||||||
|
AddDelayItem(pDelay, "Six Seconds", 6, false);
|
||||||
|
AddDelayItem(pDelay, "Seven Seconds", 7, false);
|
||||||
|
AddDelayItem(pDelay, "Eight Seconds", 8, false);
|
||||||
|
AddDelayItem(pDelay, "Nine Seconds", 9, false);
|
||||||
|
AddDelayItem(pDelay, "Ten Seconds", 10, false);
|
||||||
|
AddDelayItem(pDelay, "Twenty Seconds", 20, false);
|
||||||
|
pmenu->AddItem(pDelay);
|
||||||
|
pmenu->AddSeparatorItem();
|
||||||
|
AddItemMenu(pmenu, "Original Size", MSG_ORIGINAL_SIZE, 0, 0, 'W', true);
|
||||||
|
AddItemMenu(pmenu, "Zoom In", MSG_ZOOM_IN, '+', 0, 'W', true);
|
||||||
|
AddItemMenu(pmenu, "Zoom Out", MSG_ZOOM_OUT, '-', 0, 'W', true);
|
||||||
|
pmenu->AddSeparatorItem();
|
||||||
|
AddItemMenu(pmenu, "Fit To Window Size", MSG_FIT_TO_WINDOW_SIZE, 0, 0, 'W', true);
|
||||||
|
AddItemMenu(pmenu, "Full Screen", MSG_FULL_SCREEN, B_ENTER, 0, 'W', true);
|
||||||
|
AddItemMenu(pmenu, "Show Caption in Full Screen Mode", MSG_SHOW_CAPTION, 0, 0, 'W', true);
|
||||||
|
MarkMenuItem(pmenu, MSG_SHOW_CAPTION, fShowCaption);
|
||||||
|
|
||||||
|
if (fpImageView) {
|
||||||
|
bool resize = fpImageView->GetResizeToViewBounds();
|
||||||
|
MarkMenuItem(pmenu, MSG_FIT_TO_WINDOW_SIZE, resize);
|
||||||
|
EnableMenuItem(pmenu, MSG_ORIGINAL_SIZE, !resize);
|
||||||
|
EnableMenuItem(pmenu, MSG_ZOOM_IN, !resize);
|
||||||
|
EnableMenuItem(pmenu, MSG_ZOOM_OUT, !resize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
||||||
{
|
{
|
||||||
@@ -205,9 +256,10 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
|||||||
AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false);
|
AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false);
|
||||||
AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', true);
|
AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', true);
|
||||||
AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false);
|
AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false);
|
||||||
AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', true);
|
AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false);
|
||||||
pmenu->AddSeparatorItem();
|
pmenu->AddSeparatorItem();
|
||||||
AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
|
AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
|
||||||
|
AddItemMenu(pmenu, "Select None", MSG_SELECT_NONE, 0, 0, 'W', true);
|
||||||
pbar->AddItem(pmenu);
|
pbar->AddItem(pmenu);
|
||||||
|
|
||||||
pmenu = fpBrowseMenu = new BMenu("Browse");
|
pmenu = fpBrowseMenu = new BMenu("Browse");
|
||||||
@@ -235,35 +287,8 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
|||||||
pbar->AddItem(pmenu);
|
pbar->AddItem(pmenu);
|
||||||
|
|
||||||
pmenu = new BMenu("View");
|
pmenu = new BMenu("View");
|
||||||
AddItemMenu(pmenu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
|
BuildViewMenu(pmenu);
|
||||||
BMenu* pDelay = new BMenu("Slide Delay");
|
pbar->AddItem(pmenu);
|
||||||
pDelay->SetRadioMode(true);
|
|
||||||
// Note: ShowImage loades images in window thread so it becomes unresponsive if
|
|
||||||
// slide show delay is too short! (Especially if loading the image takes as long as
|
|
||||||
// or longer than the slide show delay). Should load in background thread!
|
|
||||||
// AddDelayItem(pDelay, "Half a Second", 0.5, false);
|
|
||||||
// AddDelayItem(pDelay, "One Second", 1, false);
|
|
||||||
// AddDelayItem(pDelay, "Two Second", 2, false);
|
|
||||||
AddDelayItem(pDelay, "Three Seconds", 3, true);
|
|
||||||
AddDelayItem(pDelay, "Four Second", 4, false);
|
|
||||||
AddDelayItem(pDelay, "Five Seconds", 5, false);
|
|
||||||
AddDelayItem(pDelay, "Six Seconds", 6, false);
|
|
||||||
AddDelayItem(pDelay, "Seven Seconds", 7, false);
|
|
||||||
AddDelayItem(pDelay, "Eight Seconds", 8, false);
|
|
||||||
AddDelayItem(pDelay, "Nine Seconds", 9, false);
|
|
||||||
AddDelayItem(pDelay, "Ten Seconds", 10, false);
|
|
||||||
AddDelayItem(pDelay, "Twenty Seconds", 20, false);
|
|
||||||
pmenu->AddItem(pDelay);
|
|
||||||
pmenu->AddSeparatorItem();
|
|
||||||
AddItemMenu(pmenu, "Original Size", MSG_ORIGINAL_SIZE, 0, 0, 'W', true);
|
|
||||||
AddItemMenu(pmenu, "Zoom In", MSG_ZOOM_IN, '+', 0, 'W', true);
|
|
||||||
AddItemMenu(pmenu, "Zoom Out", MSG_ZOOM_OUT, '-', 0, 'W', true);
|
|
||||||
pmenu->AddSeparatorItem();
|
|
||||||
AddItemMenu(pmenu, "Fit To Window Size", MSG_FIT_TO_WINDOW_SIZE, 0, 0, 'W', true);
|
|
||||||
AddItemMenu(pmenu, "Full Screen", MSG_FULL_SCREEN, B_ENTER, 0, 'W', true);
|
|
||||||
AddItemMenu(pmenu, "Show Caption in Full Screen Mode", MSG_SHOW_CAPTION, 0, 0, 'W', true);
|
|
||||||
pbar->AddItem(pmenu);
|
|
||||||
MarkMenuItem(MSG_SHOW_CAPTION, fShowCaption);
|
|
||||||
|
|
||||||
UpdateRecentDocumentsMenu();
|
UpdateRecentDocumentsMenu();
|
||||||
}
|
}
|
||||||
@@ -276,8 +301,9 @@ ShowImageWindow::AddItemMenu(BMenu *pmenu, char *caption, long unsigned int msg,
|
|||||||
pitem = new BMenuItem(caption, new BMessage(msg), shortcut);
|
pitem = new BMenuItem(caption, new BMessage(msg), shortcut);
|
||||||
|
|
||||||
if (target == 'A')
|
if (target == 'A')
|
||||||
pitem->SetTarget(be_app);
|
pitem->SetTarget(be_app);
|
||||||
|
else
|
||||||
|
pitem->SetTarget(this);
|
||||||
pitem->SetEnabled(benabled);
|
pitem->SetEnabled(benabled);
|
||||||
pmenu->AddItem(pitem);
|
pmenu->AddItem(pitem);
|
||||||
|
|
||||||
@@ -293,6 +319,7 @@ ShowImageWindow::AddDelayItem(BMenu *pmenu, char *caption, float value, bool mar
|
|||||||
pmsg->AddFloat("value", value);
|
pmsg->AddFloat("value", value);
|
||||||
|
|
||||||
pitem = new BMenuItem(caption, pmsg, 0);
|
pitem = new BMenuItem(caption, pmsg, 0);
|
||||||
|
pitem->SetTarget(this);
|
||||||
|
|
||||||
if (marked) pitem->SetMarked(true);
|
if (marked) pitem->SetMarked(true);
|
||||||
pmenu->AddItem(pitem);
|
pmenu->AddItem(pitem);
|
||||||
@@ -346,28 +373,42 @@ ShowImageWindow::ToggleMenuItem(uint32 what)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageWindow::EnableMenuItem(uint32 what, bool enable)
|
ShowImageWindow::EnableMenuItem(BMenu *menu, uint32 what, bool enable)
|
||||||
{
|
{
|
||||||
BMenuItem* item;
|
BMenuItem* item;
|
||||||
item = fpBar->FindItem(what);
|
item = menu->FindItem(what);
|
||||||
if (item && item->IsEnabled() != enable) {
|
if (item && item->IsEnabled() != enable) {
|
||||||
// XXX: Does this apply to menu items too?
|
|
||||||
// Only call this function if the state is changing
|
|
||||||
// to avoid flickering
|
|
||||||
item->SetEnabled(enable);
|
item->SetEnabled(enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageWindow::MarkMenuItem(uint32 what, bool marked)
|
ShowImageWindow::MarkMenuItem(BMenu *menu, uint32 what, bool marked)
|
||||||
{
|
{
|
||||||
BMenuItem* item;
|
BMenuItem* item;
|
||||||
item = fpBar->FindItem(what);
|
item = menu->FindItem(what);
|
||||||
if (item && item->IsMarked() != marked) {
|
if (item && item->IsMarked() != marked) {
|
||||||
item->SetMarked(marked);
|
item->SetMarked(marked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageWindow::MarkSlideShowDelay(float value)
|
||||||
|
{
|
||||||
|
const int32 n = fpSlideShowDelay->CountItems();
|
||||||
|
float v;
|
||||||
|
for (int32 i = 0; i < n; i ++) {
|
||||||
|
BMenuItem* item = fpSlideShowDelay->ItemAt(i);
|
||||||
|
if (item) {
|
||||||
|
if (item->Message()->FindFloat("value", &v) == B_OK && v == value) {
|
||||||
|
if (!item->IsMarked()) {
|
||||||
|
item->SetMarked(true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageWindow::MessageReceived(BMessage *pmsg)
|
ShowImageWindow::MessageReceived(BMessage *pmsg)
|
||||||
@@ -402,10 +443,10 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
|||||||
curPage = fpImageView->CurrentPage();
|
curPage = fpImageView->CurrentPage();
|
||||||
|
|
||||||
bool benable = (pages > 1) ? true : false;
|
bool benable = (pages > 1) ? true : false;
|
||||||
EnableMenuItem(MSG_PAGE_FIRST, benable);
|
EnableMenuItem(fpBar, MSG_PAGE_FIRST, benable);
|
||||||
EnableMenuItem(MSG_PAGE_LAST, benable);
|
EnableMenuItem(fpBar, MSG_PAGE_LAST, benable);
|
||||||
EnableMenuItem(MSG_PAGE_NEXT, benable);
|
EnableMenuItem(fpBar, MSG_PAGE_NEXT, benable);
|
||||||
EnableMenuItem(MSG_PAGE_PREV, benable);
|
EnableMenuItem(fpBar, MSG_PAGE_PREV, benable);
|
||||||
|
|
||||||
if (fpGoToPageMenu->CountItems() != pages) {
|
if (fpGoToPageMenu->CountItems() != pages) {
|
||||||
// Only rebuild the submenu if the number of
|
// Only rebuild the submenu if the number of
|
||||||
@@ -466,11 +507,13 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
|||||||
case B_PASTE:
|
case B_PASTE:
|
||||||
break;
|
break;
|
||||||
case MSG_CLEAR_SELECT:
|
case MSG_CLEAR_SELECT:
|
||||||
fpImageView->Unselect();
|
|
||||||
break;
|
break;
|
||||||
case MSG_SELECT_ALL:
|
case MSG_SELECT_ALL:
|
||||||
fpImageView->SelectAll();
|
fpImageView->SelectAll();
|
||||||
break;
|
break;
|
||||||
|
case MSG_SELECT_NONE:
|
||||||
|
fpImageView->Unselect();
|
||||||
|
break;
|
||||||
|
|
||||||
case MSG_PAGE_FIRST:
|
case MSG_PAGE_FIRST:
|
||||||
fpImageView->FirstPage();
|
fpImageView->FirstPage();
|
||||||
@@ -518,9 +561,9 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
|||||||
bool resize;
|
bool resize;
|
||||||
resize = ToggleMenuItem(pmsg->what);
|
resize = ToggleMenuItem(pmsg->what);
|
||||||
fpImageView->ResizeToViewBounds(resize);
|
fpImageView->ResizeToViewBounds(resize);
|
||||||
EnableMenuItem(MSG_ORIGINAL_SIZE, !resize);
|
EnableMenuItem(fpBar, MSG_ORIGINAL_SIZE, !resize);
|
||||||
EnableMenuItem(MSG_ZOOM_IN, !resize);
|
EnableMenuItem(fpBar, MSG_ZOOM_IN, !resize);
|
||||||
EnableMenuItem(MSG_ZOOM_OUT, !resize);
|
EnableMenuItem(fpBar, MSG_ZOOM_OUT, !resize);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -558,6 +601,8 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
|||||||
float value;
|
float value;
|
||||||
if (pmsg->FindFloat("value", &value) == B_OK) {
|
if (pmsg->FindFloat("value", &value) == B_OK) {
|
||||||
fpImageView->SetSlideShowDelay(value);
|
fpImageView->SetSlideShowDelay(value);
|
||||||
|
// in case message is sent from popup menu
|
||||||
|
MarkSlideShowDelay(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -698,10 +743,12 @@ ShowImageWindow::ToggleFullScreen()
|
|||||||
frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
|
frame.InsetBy(-1, -1); // PEN_SIZE in ShowImageView
|
||||||
|
|
||||||
SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
|
SetFlags(Flags() | B_NOT_RESIZABLE | B_NOT_MOVABLE);
|
||||||
|
fpImageView->SetAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE);
|
||||||
} else {
|
} else {
|
||||||
frame = fWindowFrame;
|
frame = fWindowFrame;
|
||||||
|
|
||||||
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
|
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
|
||||||
|
fpImageView->SetAlignment(B_ALIGN_LEFT, B_ALIGN_TOP);
|
||||||
}
|
}
|
||||||
fpImageView->SetShowCaption(fFullScreen && fShowCaption);
|
fpImageView->SetShowCaption(fFullScreen && fShowCaption);
|
||||||
MoveTo(frame.left, frame.top);
|
MoveTo(frame.left, frame.top);
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public:
|
|||||||
ShowImageView *GetShowImageView() const { return fpImageView; }
|
ShowImageView *GetShowImageView() const { return fpImageView; }
|
||||||
|
|
||||||
void UpdateTitle();
|
void UpdateTitle();
|
||||||
|
void BuildViewMenu(BMenu *menu);
|
||||||
void LoadMenus(BMenuBar *pbar);
|
void LoadMenus(BMenuBar *pbar);
|
||||||
void WindowRedimension(BBitmap *pbitmap);
|
void WindowRedimension(BBitmap *pbitmap);
|
||||||
|
|
||||||
@@ -69,8 +70,9 @@ private:
|
|||||||
void UpdateRecentDocumentsMenu();
|
void UpdateRecentDocumentsMenu();
|
||||||
|
|
||||||
bool ToggleMenuItem(uint32 what);
|
bool ToggleMenuItem(uint32 what);
|
||||||
void EnableMenuItem(uint32 what, bool enable);
|
void EnableMenuItem(BMenu *menu, uint32 what, bool enable);
|
||||||
void MarkMenuItem(uint32 what, bool marked);
|
void MarkMenuItem(BMenu *menu, uint32 what, bool marked);
|
||||||
|
void MarkSlideShowDelay(float value);
|
||||||
|
|
||||||
void SaveAs(BMessage *pmsg);
|
void SaveAs(BMessage *pmsg);
|
||||||
// Handle Save As submenu choice
|
// Handle Save As submenu choice
|
||||||
@@ -88,6 +90,7 @@ private:
|
|||||||
BMenu *fpOpenMenu;
|
BMenu *fpOpenMenu;
|
||||||
BMenu *fpBrowseMenu;
|
BMenu *fpBrowseMenu;
|
||||||
BMenu *fpGoToPageMenu;
|
BMenu *fpGoToPageMenu;
|
||||||
|
BMenu *fpSlideShowDelay;
|
||||||
ShowImageView *fpImageView;
|
ShowImageView *fpImageView;
|
||||||
ShowImageStatusView *fpStatusView;
|
ShowImageStatusView *fpStatusView;
|
||||||
bool fFullScreen;
|
bool fFullScreen;
|
||||||
|
|||||||
Reference in New Issue
Block a user