* Removed the "shrink to window" option. Instead, there is now a "Fit to window"

menu item that just does that. Additionally, the image is always fit to the
  window size when first shown, or if the full screen mode switches.
  That also fixes #6765, and #6810.
* The ImageCache now also passes a referenced BitmapOwner object, and bitmaps
  are now actually freed when it's allowed to.
* Pressing the zoom button will cause ShowImage to enter full screen again. For
  some reason this has been removed as part of r19540.
* The progress window is now visible again, although not that often, as you will
  only see it for images that were not in the queue already. The window is now
  known to the ShowImageWindow instead of the ShowImageView.
* Moved most constants out of ShowImageConstants.h to where they belong.
* Dropping an image now opens it in another window.
* Removed EntryMenuItem as it's no longer used anywhere.
* Minor other cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39431 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2010-11-14 23:45:15 +00:00
parent cb49ed72a6
commit e206972309
14 changed files with 291 additions and 414 deletions
-108
View File
@@ -1,108 +0,0 @@
/*
* Copyright 2003-2009 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Pfeiffer, [email protected]
*/
#include "EntryMenuItem.h"
#include <Node.h>
#include <NodeInfo.h>
EntryMenuItem::EntryMenuItem(entry_ref* ref, const char* label,
BMessage* message, char shortcut, uint32 modifiers)
:
BMenuItem(label, message, shortcut, modifiers),
fEntry(*ref),
fSmallIcon(NULL)
{
}
EntryMenuItem::~EntryMenuItem()
{
delete fSmallIcon;
}
void
EntryMenuItem::GetContentSize(float* width, float* height)
{
BMenuItem::GetContentSize(width, height);
*width += kTextIndent;
if (*height < kIconSize) {
*height = kIconSize;
}
}
void
EntryMenuItem::DrawContent()
{
BView* view = Menu();
BPoint pos(view->PenLocation());
if (fSmallIcon == NULL) {
fSmallIcon = LoadIcon(); // Load on demand
}
view->MovePenBy(kTextIndent, 0);
BMenuItem::DrawContent();
if (fSmallIcon) {
view->SetDrawingMode(B_OP_OVER);
view->DrawBitmap(fSmallIcon, pos);
}
}
BBitmap*
EntryMenuItem::GetIcon(BMimeType* mimeType)
{
BBitmap* icon;
icon = new BBitmap(BRect(0, 0, kIconSize - 1, kIconSize - 1), B_CMAP8);
if (mimeType->GetIcon(icon, B_MINI_ICON) != B_OK) {
delete icon;
icon = NULL;
}
return icon;
}
BBitmap*
EntryMenuItem::LoadIcon()
{
BBitmap* icon = NULL;
BNode node(&fEntry);
BNodeInfo info(&node);
char type[B_MIME_TYPE_LENGTH+1];
// Note: BNodeInfo::GetTrackerIcon does not work as expected!
// Try to get the icon stored in file attribute
icon = new BBitmap(BRect(0, 0, kIconSize-1, kIconSize-1), B_CMAP8);
if (info.GetIcon(icon, B_MINI_ICON) == B_OK) {
return icon;
}
delete icon;
icon = NULL;
// Get the icon from type
if (info.GetType(type) == B_OK) {
BMimeType mimeType(type);
BMimeType superType;
if (mimeType.InitCheck() == B_OK) {
icon = GetIcon(&mimeType);
// Or super type
if (icon == NULL && mimeType.GetSupertype(&superType) == B_OK) {
icon = GetIcon(&superType);
}
}
}
return icon;
}
-42
View File
@@ -1,42 +0,0 @@
/*
* Copyright 2003-2009 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Pfeiffer, [email protected]
*/
#ifndef ENTRY_MENU_ITEM_H
#define ENTRY_MENU_ITEM_H
#include <Bitmap.h>
#include <Entry.h>
#include <MenuItem.h>
#include <Mime.h>
class EntryMenuItem : public BMenuItem {
public:
EntryMenuItem(entry_ref* entry, const char* label,
BMessage* message, char shortcut = 0, uint32 modifiers = 0);
~EntryMenuItem();
void GetContentSize(float* width, float* height);
void DrawContent();
private:
BBitmap* GetIcon(BMimeType* mimeType);
BBitmap* LoadIcon();
entry_ref fEntry;
BBitmap* fSmallIcon;
enum {
kIconSize = 16,
kTextIndent = kIconSize + 4,
};
};
#endif // ENTRY_MENU_ITEM_H
+37 -17
View File
@@ -35,6 +35,22 @@ struct QueueEntry {
// #pragma mark - // #pragma mark -
BitmapOwner::BitmapOwner(BBitmap* bitmap)
:
fBitmap(bitmap)
{
}
BitmapOwner::~BitmapOwner()
{
delete fBitmap;
}
// #pragma mark -
ImageCache::ImageCache() ImageCache::ImageCache()
: :
fLocker("image cache"), fLocker("image cache"),
@@ -177,16 +193,14 @@ ImageCache::_RetrieveImage(QueueEntry* queueEntry, CacheEntry** _entry)
&& ioExtension.AddInt32("/documentIndex", queueEntry->page) != B_OK) && ioExtension.AddInt32("/documentIndex", queueEntry->page) != B_OK)
return B_NO_MEMORY; return B_NO_MEMORY;
// TODO: rethink this! // TODO: this doesn't work for images that already are in the queue...
#if 0 if (!queueEntry->listeners.empty()) {
if (fProgressWindow != NULL) { BMessage progress(kMsgImageCacheProgressUpdate);
BMessage progress(kMsgProgressStatusUpdate); progress.AddRef("ref", &queueEntry->ref);
if (ioExtension.AddMessenger("/progressMonitor", ioExtension.AddMessenger("/progressMonitor",
fProgressWindow) == B_OK *queueEntry->listeners.begin());
&& ioExtension.AddMessage("/progressMessage", &progress) == B_OK) ioExtension.AddMessage("/progressMessage", &progress);
fProgressWindow->Start();
} }
#endif
// Translate image data and create a new ShowImage window // Translate image data and create a new ShowImage window
@@ -198,12 +212,6 @@ ImageCache::_RetrieveImage(QueueEntry* queueEntry, CacheEntry** _entry)
status = roster->Translate(&file, &info, &ioExtension, &outstream, status = roster->Translate(&file, &info, &ioExtension, &outstream,
B_TRANSLATOR_BITMAP); B_TRANSLATOR_BITMAP);
} }
#if 0
if (fProgressWindow != NULL)
fProgressWindow->Stop();
#endif
if (status != B_OK) if (status != B_OK)
return status; return status;
@@ -211,6 +219,12 @@ ImageCache::_RetrieveImage(QueueEntry* queueEntry, CacheEntry** _entry)
if (outstream.DetachBitmap(&bitmap) != B_OK) if (outstream.DetachBitmap(&bitmap) != B_OK)
return B_ERROR; return B_ERROR;
entry->bitmapOwner = new(std::nothrow) BitmapOwner(bitmap);
if (entry->bitmapOwner == NULL) {
delete bitmap;
return B_NO_MEMORY;
}
entry->ref = queueEntry->ref; entry->ref = queueEntry->ref;
entry->page = queueEntry->page; entry->page = queueEntry->page;
entry->bitmap = bitmap; entry->bitmap = bitmap;
@@ -244,6 +258,8 @@ ImageCache::_RetrieveImage(QueueEntry* queueEntry, CacheEntry** _entry)
entry = fCacheEntriesByAge.RemoveHead(); entry = fCacheEntriesByAge.RemoveHead();
fBytes -= entry->bitmap->BitsLength(); fBytes -= entry->bitmap->BitsLength();
fCacheMap.erase(std::make_pair(entry->ref, entry->page)); fCacheMap.erase(std::make_pair(entry->ref, entry->page));
entry->bitmapOwner->ReleaseReference();
delete entry; delete entry;
} }
@@ -259,7 +275,7 @@ ImageCache::_NotifyListeners(CacheEntry* entry, QueueEntry* queueEntry)
if (queueEntry->listeners.empty()) if (queueEntry->listeners.empty())
return; return;
BMessage notification(kMsgImageLoaded); BMessage notification(kMsgImageCacheImageLoaded);
_BuildNotification(entry, notification); _BuildNotification(entry, notification);
if (queueEntry->status != B_OK) if (queueEntry->status != B_OK)
@@ -278,7 +294,7 @@ ImageCache::_NotifyTarget(CacheEntry* entry, const BMessenger* target)
if (target == NULL) if (target == NULL)
return; return;
BMessage notification(kMsgImageLoaded); BMessage notification(kMsgImageCacheImageLoaded);
_BuildNotification(entry, notification); _BuildNotification(entry, notification);
target->SendMessage(&notification); target->SendMessage(&notification);
@@ -291,10 +307,14 @@ ImageCache::_BuildNotification(CacheEntry* entry, BMessage& message)
if (entry == NULL) if (entry == NULL)
return; return;
entry->bitmapOwner->AcquireReference();
// this is the reference owned by the target
message.AddString("type", entry->type); message.AddString("type", entry->type);
message.AddString("mime", entry->mimeType); message.AddString("mime", entry->mimeType);
message.AddRef("ref", &entry->ref); message.AddRef("ref", &entry->ref);
message.AddInt32("page", entry->page); message.AddInt32("page", entry->page);
message.AddInt32("pageCount", entry->pageCount); message.AddInt32("pageCount", entry->pageCount);
message.AddPointer("bitmap", (void*)entry->bitmap); message.AddPointer("bitmap", (void*)entry->bitmap);
message.AddPointer("bitmapOwner", (void*)entry->bitmapOwner);
} }
+14 -1
View File
@@ -15,6 +15,7 @@
#include <String.h> #include <String.h>
#include <kernel/util/DoublyLinkedList.h> #include <kernel/util/DoublyLinkedList.h>
#include <Referenceable.h>
class BBitmap; class BBitmap;
@@ -24,7 +25,18 @@ struct QueueEntry;
enum { enum {
kMsgImageLoaded = 'ifnL' kMsgImageCacheImageLoaded = 'icIL',
kMsgImageCacheProgressUpdate = 'icPU'
};
class BitmapOwner : public Referenceable {
public:
BitmapOwner(BBitmap* bitmap);
virtual ~BitmapOwner();
private:
BBitmap* fBitmap;
}; };
@@ -33,6 +45,7 @@ struct CacheEntry : DoublyLinkedListLinkImpl<CacheEntry> {
int32 page; int32 page;
int32 pageCount; int32 pageCount;
BBitmap* bitmap; BBitmap* bitmap;
BitmapOwner* bitmapOwner;
BString type; BString type;
BString mimeType; BString mimeType;
}; };
+3 -5
View File
@@ -6,7 +6,6 @@ UsePublicHeaders [ FDirName be_apps Tracker ] ;
SubDirHdrs $(HAIKU_TOP) src kits tracker ; SubDirHdrs $(HAIKU_TOP) src kits tracker ;
Application ShowImage : Application ShowImage :
EntryMenuItem.cpp
Filter.cpp Filter.cpp
ImageCache.cpp ImageCache.cpp
ImageFileNavigator.cpp ImageFileNavigator.cpp
@@ -19,11 +18,10 @@ Application ShowImage :
ShowImageUndo.cpp ShowImageUndo.cpp
ShowImageView.cpp ShowImageView.cpp
ShowImageWindow.cpp ShowImageWindow.cpp
: libshared.a : libshared.a be tracker translation $(HAIKU_LOCALE_LIBS)
be tracker translation $(HAIKU_LOCALE_LIBS) $(TARGET_LIBSTDC++) $(TARGET_LIBSTDC++) $(TARGET_LIBSUPC++)
$(TARGET_LIBSUPC++)
: ShowImage.rdef : ShowImage.rdef
; ;
DoCatalogs ShowImage : DoCatalogs ShowImage :
x-vnd.Haiku-ShowImage x-vnd.Haiku-ShowImage
+26 -12
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007-2009, Axel Dörfler, [email protected]. * Copyright 2007-2010, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -7,6 +7,7 @@
#include "ProgressWindow.h" #include "ProgressWindow.h"
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <Autolock.h> #include <Autolock.h>
#include <Catalog.h> #include <Catalog.h>
@@ -24,10 +25,13 @@ static const uint32 kMsgShow = 'show';
#define B_TRANSLATE_CONTEXT "ProgressWindow" #define B_TRANSLATE_CONTEXT "ProgressWindow"
ProgressWindow::ProgressWindow(BWindow* referenceWindow, bool center) ProgressWindow::ProgressWindow()
: :
BWindow(BRect(0, 0, 250, 100), B_TRANSLATE("Progress monitor"), BWindow(BRect(0, 0, 250, 100), B_TRANSLATE("Progress monitor"),
B_MODAL_WINDOW_LOOK, B_FLOATING_APP_WINDOW_FEEL, B_MODAL_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,// B_FLOATING_APP_WINDOW_FEEL,
// TODO: a bug in the app_server prevents an initial floating-app feel
// to work correctly; the window will then not be visible for the first
// image, even though it's later set to normal feel in that case.
B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS), B_NOT_ZOOMABLE | B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS),
fRunner(NULL) fRunner(NULL)
{ {
@@ -45,14 +49,7 @@ ProgressWindow::ProgressWindow(BWindow* referenceWindow, bool center)
fStatusBar->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT); fStatusBar->SetResizingMode(B_FOLLOW_TOP | B_FOLLOW_LEFT_RIGHT);
view->AddChild(fStatusBar); view->AddChild(fStatusBar);
BScreen screen(referenceWindow);
if (!center) {
ResizeTo(Bounds().Width(), height + 9); ResizeTo(Bounds().Width(), height + 9);
// TODO: frame width!
MoveTo(screen.Frame().left + 5,
screen.Frame().bottom - Bounds().Height() - 5);
} else
CenterIn(screen.Frame());
Run(); Run();
} }
@@ -65,10 +62,27 @@ ProgressWindow::~ProgressWindow()
void void
ProgressWindow::Start() ProgressWindow::Start(BWindow* referenceWindow, bool center)
{ {
BAutolock _(this); BAutolock _(this);
BScreen screen(referenceWindow);
if (!center) {
BMessage settings;
GetDecoratorSettings(&settings);
int32 borderWidth;
if (settings.FindInt32("border", &borderWidth) != B_OK)
borderWidth = 5;
MoveTo(screen.Frame().left + borderWidth,
screen.Frame().bottom - Bounds().Height() - borderWidth);
} else
CenterIn(screen.Frame());
SetFeel(referenceWindow->IsHidden()
? B_NORMAL_WINDOW_FEEL : B_FLOATING_APP_WINDOW_FEEL);
fRetrievedUpdate = false; fRetrievedUpdate = false;
fRetrievedShow = false; fRetrievedShow = false;
delete fRunner; delete fRunner;
@@ -104,7 +118,7 @@ ProgressWindow::MessageReceived(BMessage *message)
fRetrievedShow = true; fRetrievedShow = true;
break; break;
case kMsgProgressStatusUpdate: case kMsgProgressUpdate:
float percent; float percent;
if (message->FindFloat("percent", &percent) == B_OK) if (message->FindFloat("percent", &percent) == B_OK)
fStatusBar->Update(percent - fStatusBar->CurrentValue()); fStatusBar->Update(percent - fStatusBar->CurrentValue());
+10 -4
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007-2009, Axel Dörfler, [email protected]. * Copyright 2007-2010, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef PROGRESS_WINDOW_H #ifndef PROGRESS_WINDOW_H
@@ -13,15 +13,21 @@ class BMessageRunner;
class BStatusBar; class BStatusBar;
// public message constants
enum {
kMsgProgressUpdate = 'pwPU'
};
class ProgressWindow : public BWindow { class ProgressWindow : public BWindow {
public: public:
ProgressWindow(BWindow* referenceWindow, ProgressWindow();
bool center = false);
virtual ~ProgressWindow(); virtual ~ProgressWindow();
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
void Start(); void Start(BWindow* referenceWindow,
bool center = false);
void Stop(); void Stop();
private: private:
+10 -10
View File
@@ -9,6 +9,7 @@
* Ryan Leavengood * Ryan Leavengood
*/ */
#include "ShowImageApp.h" #include "ShowImageApp.h"
#include <stdio.h> #include <stdio.h>
@@ -26,12 +27,13 @@
#include "ShowImageWindow.h" #include "ShowImageWindow.h"
#define WINDOWS_TO_IGNORE 1
#undef B_TRANSLATE_CONTEXT #undef B_TRANSLATE_CONTEXT
#define B_TRANSLATE_CONTEXT "AboutWindow" #define B_TRANSLATE_CONTEXT "AboutWindow"
const char* kApplicationSignature = "application/x-vnd.Haiku-ShowImage"; const char* kApplicationSignature = "application/x-vnd.Haiku-ShowImage";
const int32 kWindowsToIgnore = 1;
// ignore the always open file panel
ShowImageApp::ShowImageApp() ShowImageApp::ShowImageApp()
@@ -87,7 +89,7 @@ ShowImageApp::ArgvReceived(int32 argc, char **argv)
void void
ShowImageApp::ReadyToRun() ShowImageApp::ReadyToRun()
{ {
if (CountWindows() == WINDOWS_TO_IGNORE) if (CountWindows() == kWindowsToIgnore)
fOpenPanel->Show(); fOpenPanel->Show();
else { else {
// If image windows are already open // If image windows are already open
@@ -109,9 +111,6 @@ ShowImageApp::MessageReceived(BMessage* message)
fOpenPanel->Show(); fOpenPanel->Show();
break; break;
case MSG_WINDOW_QUIT:
break;
case B_CANCEL: case B_CANCEL:
// File open panel was closed, // File open panel was closed,
// start checking count of open windows // start checking count of open windows
@@ -137,6 +136,7 @@ ShowImageApp::AboutRequested()
"Michael Wilber", "Michael Wilber",
"Michael Pfeiffer", "Michael Pfeiffer",
"Ryan Leavengood", "Ryan Leavengood",
"Axel Dörfler",
NULL NULL
}; };
BAboutWindow about(B_TRANSLATE("ShowImage"), 2003, authors); BAboutWindow about(B_TRANSLATE("ShowImage"), 2003, authors);
@@ -149,7 +149,7 @@ ShowImageApp::Pulse()
{ {
// Bug: The BFilePanel is automatically closed if the volume that // Bug: The BFilePanel is automatically closed if the volume that
// is displayed is unmounted. // is displayed is unmounted.
if (!IsLaunching() && CountWindows() <= WINDOWS_TO_IGNORE) { if (!IsLaunching() && CountWindows() <= kWindowsToIgnore) {
// If the application is not launching and // If the application is not launching and
// all windows are closed except for the file open panel, // all windows are closed except for the file open panel,
// quit the application // quit the application
@@ -212,8 +212,8 @@ ShowImageApp::_BroadcastToWindows(BMessage* message)
const int32 count = CountWindows(); const int32 count = CountWindows();
for (int32 i = 0; i < count; i ++) { for (int32 i = 0; i < count; i ++) {
// BMessenger checks for us if BWindow is still a valid object // BMessenger checks for us if BWindow is still a valid object
BMessenger msgr(WindowAt(i)); BMessenger messenger(WindowAt(i));
msgr.SendMessage(message); messenger.SendMessage(message);
} }
} }
@@ -238,7 +238,7 @@ ShowImageApp::_CheckClipboard()
be_clipboard->Unlock(); be_clipboard->Unlock();
} }
BMessage msg(MSG_CLIPBOARD_CHANGED); BMessage msg(B_CLIPBOARD_CHANGED);
msg.AddBool("data_available", dataAvailable); msg.AddBool("data_available", dataAvailable);
_BroadcastToWindows(&msg); _BroadcastToWindows(&msg);
} }
+5
View File
@@ -18,6 +18,11 @@
#include <FilePanel.h> #include <FilePanel.h>
enum {
MSG_FILE_OPEN = 'mFOP',
};
class ShowImageApp : public BApplication { class ShowImageApp : public BApplication {
public: public:
ShowImageApp(); ShowImageApp();
+1 -42
View File
@@ -16,49 +16,8 @@
enum { enum {
MSG_CAPTURE_MOUSE = 'mCPM',
MSG_CHANGE_FOCUS = 'mCFS',
MSG_FILE_OPEN = 'mFOP',
MSG_WINDOW_QUIT = 'mWQT',
MSG_OUTPUT_TYPE = 'BTMN',
MSG_SAVE_PANEL = 'mFSP',
MSG_CLEAR_SELECT = 'mCSL',
MSG_SELECT_ALL = 'mSAL',
MSG_CLIPBOARD_CHANGED = 'mCLP',
MSG_MODIFIED = 'mMOD',
MSG_UPDATE_STATUS = 'mUPS',
MSG_UPDATE_STATUS_TEXT = 'mUPT',
MSG_UNDO_STATE = 'mUNS', MSG_UNDO_STATE = 'mUNS',
MSG_SELECTION_MODE = 'mSLM', MSG_PRINT = 'mPRT'
MSG_SELECTION = 'mSEL',
MSG_PAGE_FIRST = 'mPGF',
MSG_PAGE_LAST = 'mPGL',
MSG_PAGE_NEXT = 'mPGN',
MSG_PAGE_PREV = 'mPGP',
MSG_GOTO_PAGE = 'mGTP',
MSG_FILE_NEXT = 'mFLN',
MSG_FILE_PREV = 'mFLP',
kMsgDeleteCurrentFile = 'mDcF',
MSG_SHRINK_TO_WINDOW = 'mSTW',
MSG_STRETCH_TO_WINDOW = 'mZTW',
MSG_ROTATE_90 = 'mR90',
MSG_ROTATE_270 = 'mR27',
MSG_FLIP_LEFT_TO_RIGHT = 'mFLR',
MSG_FLIP_TOP_TO_BOTTOM = 'mFTB',
MSG_SLIDE_SHOW = 'mSSW',
MSG_SLIDE_SHOW_DELAY = 'mSSD',
MSG_FULL_SCREEN = 'mFSC',
MSG_EXIT_FULL_SCREEN = 'mEFS',
MSG_SHOW_CAPTION = 'mSCP',
MSG_PAGE_SETUP = 'mPSU',
MSG_PREPARE_PRINT = 'mPPT',
MSG_PRINT = 'mPRT',
MSG_ZOOM_IN = 'mZIN',
MSG_ZOOM_OUT = 'mZOU',
MSG_ORIGINAL_SIZE = 'mOSZ',
MSG_SCALE_BILINEAR = 'mSBL',
MSG_DESKTOP_BACKGROUND = 'mDBG',
kMsgProgressStatusUpdate = 'SIup'
}; };
+59 -99
View File
@@ -12,6 +12,7 @@
* yellowTAB GmbH * yellowTAB GmbH
* Bernd Korz * Bernd Korz
* Stephan Aßmus <[email protected]> * Stephan Aßmus <[email protected]>
* Axel Dörfler, [email protected]
*/ */
@@ -49,9 +50,8 @@
#include <tracker_private.h> #include <tracker_private.h>
#include "ProgressWindow.h" #include "ImageCache.h"
#include "ShowImageApp.h" #include "ShowImageApp.h"
#include "ShowImageConstants.h"
#include "ShowImageWindow.h" #include "ShowImageWindow.h"
@@ -68,11 +68,16 @@ class PopUpMenu : public BPopUpMenu {
}; };
// the delay time for hiding the cursor in 1/10 seconds (the pulse rate)
#define HIDE_CURSOR_DELAY_TIME 20
#define SHOW_IMAGE_ORIENTATION_ATTRIBUTE "ShowImage:orientation" #define SHOW_IMAGE_ORIENTATION_ATTRIBUTE "ShowImage:orientation"
const rgb_color kBorderColor = { 0, 0, 0, 255 }; const rgb_color kBorderColor = { 0, 0, 0, 255 };
enum ShowImageView::image_orientation enum ShowImageView::image_orientation
ShowImageView::fTransformation[ImageProcessor::kNumberOfAffineTransformations][kNumberOfOrientations] = { ShowImageView::fTransformation[ImageProcessor::kNumberOfAffineTransformations]
[kNumberOfOrientations] = {
// rotate 90° // rotate 90°
{k90, k180, k270, k0, k270V, k0V, k90V, k0H}, {k90, k180, k270, k0, k270V, k0V, k90V, k0H},
// rotate -90° // rotate -90°
@@ -168,6 +173,7 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
uint32 flags) uint32 flags)
: :
BView(rect, name, resizingMode, flags), BView(rect, name, resizingMode, flags),
fBitmapOwner(NULL),
fBitmap(NULL), fBitmap(NULL),
fDisplayBitmap(NULL), fDisplayBitmap(NULL),
fSelectionBitmap(NULL), fSelectionBitmap(NULL),
@@ -178,10 +184,8 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
fBitmapLocationInView(0.0, 0.0), fBitmapLocationInView(0.0, 0.0),
fShrinkToBounds(true),
fStretchToBounds(false), fStretchToBounds(false),
fFitToBoundsZoom(1.0), fHideCursor(false),
fFullScreen(false),
fScrollingBitmap(false), fScrollingBitmap(false),
fCreatingSelection(false), fCreatingSelection(false),
fFirstPoint(0.0, 0.0), fFirstPoint(0.0, 0.0),
@@ -194,14 +198,13 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
fShowCaption(false), fShowCaption(false),
fShowingPopUpMenu(false), fShowingPopUpMenu(false),
fHideCursorCountDown(HIDE_CURSOR_DELAY_TIME), fHideCursorCountDown(HIDE_CURSOR_DELAY_TIME),
fIsActiveWin(true), fIsActiveWin(true)
fProgressWindow(NULL)
{ {
ShowImageSettings* settings; ShowImageSettings* settings;
settings = my_app->Settings(); settings = my_app->Settings();
if (settings->Lock()) { if (settings->Lock()) {
fShrinkToBounds = settings->GetBool("ShrinksToBounds", fShrinkToBounds); fStretchToBounds = settings->GetBool("StretchToBounds",
fStretchToBounds = settings->GetBool("ZoomToBounds", fStretchToBounds); fStretchToBounds);
fSlideShowDelay = settings->GetInt32("SlideShowDelay", fSlideShowDelay); fSlideShowDelay = settings->GetInt32("SlideShowDelay", fSlideShowDelay);
fScaleBilinear = settings->GetBool("ScaleBilinear", fScaleBilinear); fScaleBilinear = settings->GetBool("ScaleBilinear", fScaleBilinear);
settings->Unlock(); settings->Unlock();
@@ -246,8 +249,7 @@ ShowImageView::Pulse()
} }
#endif #endif
// Hide cursor in full screen mode if (fHideCursor && !fHasSelection && !fShowingPopUpMenu && fIsActiveWin) {
if (fFullScreen && !fHasSelection && !fShowingPopUpMenu && fIsActiveWin) {
if (fHideCursorCountDown <= 0) if (fHideCursorCountDown <= 0)
be_app->ObscureCursor(); be_app->ObscureCursor();
else else
@@ -316,7 +318,12 @@ ShowImageView::_DeleteBitmap()
delete fDisplayBitmap; delete fDisplayBitmap;
fDisplayBitmap = NULL; fDisplayBitmap = NULL;
// TODO: the bitmap is currently only owned by the cache!!! if (fBitmapOwner != NULL)
fBitmapOwner->ReleaseReference();
else
delete fBitmap;
fBitmapOwner = NULL;
fBitmap = NULL; fBitmap = NULL;
} }
@@ -342,6 +349,8 @@ ShowImageView::SetImage(const BMessage* message)
if (status == B_OK) { if (status == B_OK) {
fFormatDescription = message->FindString("type"); fFormatDescription = message->FindString("type");
fMimeType = message->FindString("mime"); fMimeType = message->FindString("mime");
message->FindPointer("bitmapOwner", (void**)&fBitmapOwner);
} }
return status; return status;
@@ -417,9 +426,7 @@ ShowImageView::SetImage(const entry_ref* ref, BBitmap* bitmap)
be_roster->AddToRecentDocuments(ref, kApplicationSignature); be_roster->AddToRecentDocuments(ref, kApplicationSignature);
fFitToBoundsZoom = _FitToBoundsZoom(); FitToBounds();
ResetZoom();
Invalidate();
_Notify(); _Notify();
return B_OK; return B_OK;
} }
@@ -479,34 +486,23 @@ ShowImageView::SetShowCaption(bool show)
} }
void
ShowImageView::SetShrinkToBounds(bool enable)
{
if (fShrinkToBounds != enable) {
_SettingsSetBool("ShrinksToBounds", enable);
fShrinkToBounds = enable;
if (enable)
SetZoom(fFitToBoundsZoom);
}
}
void void
ShowImageView::SetStretchToBounds(bool enable) ShowImageView::SetStretchToBounds(bool enable)
{ {
if (fStretchToBounds != enable) { if (fStretchToBounds != enable) {
_SettingsSetBool("ZoomToBounds", enable); _SettingsSetBool("StretchToBounds", enable);
fStretchToBounds = enable; fStretchToBounds = enable;
if (enable) if (enable)
SetZoom(fFitToBoundsZoom); FitToBounds();
} }
} }
void void
ShowImageView::SetFullScreen(bool fullScreen) ShowImageView::SetHideIdlingCursor(bool hide)
{ {
fFullScreen = fullScreen; fHideCursor = hide;
FitToBounds();
} }
@@ -531,35 +527,16 @@ ShowImageView::SetScaleBilinear(bool enabled)
void void
ShowImageView::AttachedToWindow() ShowImageView::AttachedToWindow()
{ {
ResetZoom(); FitToBounds();
fUndo.SetWindow(Window()); fUndo.SetWindow(Window());
FixupScrollBars(); FixupScrollBars();
fProgressWindow = new ProgressWindow(Window());
} }
void void
ShowImageView::DetachedFromWindow() ShowImageView::FrameResized(float width, float height)
{ {
fProgressWindow->Lock(); FixupScrollBars();
fProgressWindow->Quit();
}
bool
ShowImageView::_ShouldShrink() const
{
return fShrinkToBounds && fBitmap->Bounds().Width() > Bounds().Width()
&& fBitmap->Bounds().Height() > Bounds().Height();
}
bool
ShowImageView::_ShouldStretch() const
{
return fStretchToBounds && fBitmap->Bounds().Width() < Bounds().Width()
&& fBitmap->Bounds().Height() < Bounds().Height();
} }
@@ -748,17 +725,6 @@ ShowImageView::Draw(BRect updateRect)
} }
void
ShowImageView::FrameResized(float /*width*/, float /*height*/)
{
if (fBitmap == NULL)
return;
fFitToBoundsZoom = _FitToBoundsZoom();
SetZoom(_ShouldStretch() ? fFitToBoundsZoom : fZoom);
}
BBitmap* BBitmap*
ShowImageView::_CopySelection(uchar alpha, bool imageSize) ShowImageView::_CopySelection(uchar alpha, bool imageSize)
{ {
@@ -1336,6 +1302,12 @@ ShowImageView::KeyDown(const char* bytes, int32 numBytes)
case B_DELETE: case B_DELETE:
_SendMessageToWindow(kMsgDeleteCurrentFile); _SendMessageToWindow(kMsgDeleteCurrentFile);
break; break;
case '0':
FitToBounds();
break;
case '1':
SetZoom(1.0f);
break;
case '+': case '+':
case '=': case '=':
ZoomIn(); ZoomIn();
@@ -1394,9 +1366,9 @@ ShowImageView::_ShowPopUpMenu(BPoint screen)
if (!fShowingPopUpMenu) { if (!fShowingPopUpMenu) {
PopUpMenu* menu = new PopUpMenu("PopUpMenu", this); PopUpMenu* menu = new PopUpMenu("PopUpMenu", this);
ShowImageWindow* showImage = dynamic_cast<ShowImageWindow*>(Window()); ShowImageWindow* window = dynamic_cast<ShowImageWindow*>(Window());
if (showImage) if (window != NULL)
showImage->BuildContextMenu(menu); window->BuildContextMenu(menu);
screen += BPoint(2, 2); screen += BPoint(2, 2);
menu->Go(screen, true, true, true); menu->Go(screen, true, true, true);
@@ -1421,22 +1393,6 @@ void
ShowImageView::MessageReceived(BMessage* message) ShowImageView::MessageReceived(BMessage* message)
{ {
switch (message->what) { switch (message->what) {
// TODO!
#if 0
case B_SIMPLE_DATA:
if (message->WasDropped()) {
uint32 type;
int32 count;
status_t ret = message->GetInfo("refs", &type, &count);
if (ret == B_OK && type == B_REF_TYPE) {
// If file was dropped, open it as the selection
entry_ref ref;
if (message->FindRef("refs", 0, &ref) == B_OK)
SetImage(&ref);
}
}
break;
#endif
case B_COPY_TARGET: case B_COPY_TARGET:
_HandleDrop(message); _HandleDrop(message);
break; break;
@@ -1456,7 +1412,8 @@ ShowImageView::MessageReceived(BMessage* message)
void void
ShowImageView::FixupScrollBar(orientation o, float bitmapLength, float viewLength) ShowImageView::FixupScrollBar(orientation o, float bitmapLength,
float viewLength)
{ {
float prop, range; float prop, range;
BScrollBar *psb; BScrollBar *psb;
@@ -1609,10 +1566,11 @@ ShowImageView::CopySelectionToClipboard()
void void
ShowImageView::SetZoom(float zoom, BPoint where) ShowImageView::SetZoom(float zoom, BPoint where)
{ {
float fitToBoundsZoom = _FitToBoundsZoom();
if (zoom > 32) if (zoom > 32)
zoom = 32; zoom = 32;
if (zoom < fFitToBoundsZoom / 2) if (zoom < fitToBoundsZoom / 2)
zoom = fFitToBoundsZoom / 2; zoom = fitToBoundsZoom / 2;
if (zoom == fZoom) { if (zoom == fZoom) {
// window size might have changed // window size might have changed
@@ -1652,8 +1610,9 @@ ShowImageView::ZoomIn(BPoint where)
// snap zoom to "fit to bounds", and "original size" // snap zoom to "fit to bounds", and "original size"
float zoom = fZoom * 1.2; float zoom = fZoom * 1.2;
float zoomSnap = fZoom * 1.25; float zoomSnap = fZoom * 1.25;
if (fZoom < fFitToBoundsZoom && zoomSnap > fFitToBoundsZoom) float fitToBoundsZoom = _FitToBoundsZoom();
zoom = fFitToBoundsZoom; if (fZoom < fitToBoundsZoom - 0.001 && zoomSnap > fitToBoundsZoom)
zoom = fitToBoundsZoom;
if (fZoom < 1.0 && zoomSnap > 1.0) if (fZoom < 1.0 && zoomSnap > 1.0)
zoom = 1.0; zoom = 1.0;
@@ -1667,8 +1626,9 @@ ShowImageView::ZoomOut(BPoint where)
// snap zoom to "fit to bounds", and "original size" // snap zoom to "fit to bounds", and "original size"
float zoom = fZoom / 1.2; float zoom = fZoom / 1.2;
float zoomSnap = fZoom / 1.25; float zoomSnap = fZoom / 1.25;
if (fZoom > fFitToBoundsZoom && zoomSnap < fFitToBoundsZoom) float fitToBoundsZoom = _FitToBoundsZoom();
zoom = fFitToBoundsZoom; if (fZoom > fitToBoundsZoom + 0.001 && zoomSnap < fitToBoundsZoom)
zoom = fitToBoundsZoom;
if (fZoom > 1.0 && zoomSnap < 1.0) if (fZoom > 1.0 && zoomSnap < 1.0)
zoom = 1.0; zoom = 1.0;
@@ -1676,21 +1636,21 @@ ShowImageView::ZoomOut(BPoint where)
} }
/*! Resets the zoom to what it should be when opening an image, depending /*! Fits to image to the view bounds.
on the current settings.
*/ */
void void
ShowImageView::ResetZoom() ShowImageView::FitToBounds()
{ {
if (fBitmap == NULL) if (fBitmap == NULL)
return; return;
fFitToBoundsZoom = _FitToBoundsZoom(); float fitToBoundsZoom = _FitToBoundsZoom();
if (!fStretchToBounds && fitToBoundsZoom > 1.0f)
if (_ShouldShrink() || _ShouldStretch()) SetZoom(1.0f);
SetZoom(fFitToBoundsZoom);
else else
SetZoom(1.0); SetZoom(fitToBoundsZoom);
FixupScrollBars();
} }
+14 -21
View File
@@ -15,10 +15,6 @@
#define SHOW_IMAGE_VIEW_H #define SHOW_IMAGE_VIEW_H
#include "Filter.h"
#include "SelectionBox.h"
#include "ShowImageUndo.h"
#include <Bitmap.h> #include <Bitmap.h>
#include <Entry.h> #include <Entry.h>
#include <NodeInfo.h> #include <NodeInfo.h>
@@ -26,11 +22,13 @@
#include <TranslatorRoster.h> #include <TranslatorRoster.h>
#include <View.h> #include <View.h>
#include "Filter.h"
#include "SelectionBox.h"
#include "ShowImageUndo.h"
// the delay time for hiding the cursor in 1/10 seconds (the pulse rate)
#define HIDE_CURSOR_DELAY_TIME 20
class ProgressWindow; class BitmapOwner;
class ShowImageView : public BView { class ShowImageView : public BView {
public: public:
@@ -39,9 +37,8 @@ public:
virtual ~ShowImageView(); virtual ~ShowImageView();
virtual void AttachedToWindow(); virtual void AttachedToWindow();
virtual void DetachedFromWindow();
virtual void Draw(BRect updateRect);
virtual void FrameResized(float width, float height); virtual void FrameResized(float width, float height);
virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint point); virtual void MouseDown(BPoint point);
virtual void MouseMoved(BPoint point, uint32 state, virtual void MouseMoved(BPoint point, uint32 state,
const BMessage* dragMessage); const BMessage* dragMessage);
@@ -68,16 +65,14 @@ public:
void SaveToFile(BDirectory* dir, const char* name, void SaveToFile(BDirectory* dir, const char* name,
BBitmap* bitmap, BBitmap* bitmap,
const translation_format* format); const translation_format* format);
void SetScaleBilinear(bool b); void SetScaleBilinear(bool b);
bool GetScaleBilinear() { return fScaleBilinear; } bool ScaleBilinear() { return fScaleBilinear; }
void SetShowCaption(bool show); void SetShowCaption(bool show);
void SetShrinkToBounds(bool enable);
bool ShrinksToBounds() const
{ return fShrinkToBounds; }
void SetStretchToBounds(bool enable); void SetStretchToBounds(bool enable);
bool StretchesToBounds() const bool StretchesToBounds() const
{ return fStretchToBounds; } { return fStretchToBounds; }
void SetFullScreen(bool fullScreen); void SetHideIdlingCursor(bool hide);
void FixupScrollBar(enum orientation orientation, void FixupScrollBar(enum orientation orientation,
float bitmapLength, float viewLength); float bitmapLength, float viewLength);
@@ -99,11 +94,13 @@ public:
void StartSlideShow(); void StartSlideShow();
void StopSlideShow(); void StopSlideShow();
void FitToBounds();
void SetZoom(float zoom, void SetZoom(float zoom,
BPoint where = BPoint(-1, -1)); BPoint where = BPoint(-1, -1));
float Zoom() const
{ return fZoom; }
void ZoomIn(BPoint where = BPoint(-1, -1)); void ZoomIn(BPoint where = BPoint(-1, -1));
void ZoomOut(BPoint where = BPoint(-1, -1)); void ZoomOut(BPoint where = BPoint(-1, -1));
void ResetZoom();
// Image manipulation // Image manipulation
void Rotate(int degree); // 90 and 270 only void Rotate(int degree); // 90 and 270 only
@@ -151,7 +148,6 @@ private:
void _UserDoImageOperation( void _UserDoImageOperation(
enum ImageProcessor::operation op, enum ImageProcessor::operation op,
bool quiet = false); bool quiet = false);
bool _ShouldShrink() const;
bool _ShouldStretch() const; bool _ShouldStretch() const;
float _FitToBoundsZoom() const; float _FitToBoundsZoom() const;
BRect _AlignBitmap(); BRect _AlignBitmap();
@@ -193,6 +189,7 @@ private:
ShowImageUndo fUndo; ShowImageUndo fUndo;
entry_ref fCurrentRef; entry_ref fCurrentRef;
BitmapOwner* fBitmapOwner;
BBitmap* fBitmap; BBitmap* fBitmap;
BBitmap* fDisplayBitmap; BBitmap* fDisplayBitmap;
BBitmap* fSelectionBitmap; BBitmap* fSelectionBitmap;
@@ -203,10 +200,8 @@ private:
BPoint fBitmapLocationInView; BPoint fBitmapLocationInView;
bool fShrinkToBounds;
bool fStretchToBounds; bool fStretchToBounds;
float fFitToBoundsZoom; bool fHideCursor;
bool fFullScreen;
bool fScrollingBitmap; bool fScrollingBitmap;
bool fCreatingSelection; bool fCreatingSelection;
BPoint fFirstPoint; BPoint fFirstPoint;
@@ -238,8 +233,6 @@ private:
bool fIsActiveWin; bool fIsActiveWin;
// Is the parent window the active window? // Is the parent window the active window?
ProgressWindow* fProgressWindow;
image_orientation fImageOrientation; image_orientation fImageOrientation;
static image_orientation fTransformation[ static image_orientation fTransformation[
ImageProcessor ImageProcessor
+93 -49
View File
@@ -10,6 +10,7 @@
* Michael Pfeiffer * Michael Pfeiffer
* yellowTAB GmbH * yellowTAB GmbH
* Bernd Korz * Bernd Korz
* Axel Dörfler, axeld@pinc-software.de
*/ */
@@ -45,6 +46,7 @@
#include <TranslatorRoster.h> #include <TranslatorRoster.h>
#include "ImageCache.h" #include "ImageCache.h"
#include "ProgressWindow.h"
#include "ShowImageApp.h" #include "ShowImageApp.h"
#include "ShowImageConstants.h" #include "ShowImageConstants.h"
#include "ShowImageStatusView.h" #include "ShowImageStatusView.h"
@@ -56,6 +58,40 @@ const char* kTypeField = "be:type";
const char* kTranslatorField = "be:translator"; const char* kTranslatorField = "be:translator";
// message constants
enum {
MSG_CAPTURE_MOUSE = 'mCPM',
MSG_CHANGE_FOCUS = 'mCFS',
MSG_WINDOW_QUIT = 'mWQT',
MSG_OUTPUT_TYPE = 'BTMN',
MSG_SAVE_PANEL = 'mFSP',
MSG_CLEAR_SELECT = 'mCSL',
MSG_SELECT_ALL = 'mSAL',
MSG_SELECTION_MODE = 'mSLM',
MSG_PAGE_FIRST = 'mPGF',
MSG_PAGE_LAST = 'mPGL',
MSG_PAGE_NEXT = 'mPGN',
MSG_PAGE_PREV = 'mPGP',
MSG_GOTO_PAGE = 'mGTP',
MSG_ZOOM_IN = 'mZIN',
MSG_ZOOM_OUT = 'mZOU',
MSG_SCALE_BILINEAR = 'mSBL',
MSG_DESKTOP_BACKGROUND = 'mDBG',
MSG_ROTATE_90 = 'mR90',
MSG_ROTATE_270 = 'mR27',
MSG_FLIP_LEFT_TO_RIGHT = 'mFLR',
MSG_FLIP_TOP_TO_BOTTOM = 'mFTB',
MSG_SLIDE_SHOW_DELAY = 'mSSD',
MSG_FULL_SCREEN = 'mFSC',
MSG_SHOW_CAPTION = 'mSCP',
MSG_PAGE_SETUP = 'mPSU',
MSG_PREPARE_PRINT = 'mPPT',
kMsgFitToWindow = 'mFtW',
kMsgOriginalSize = 'mOSZ',
kMsgStretchToWindow = 'mStW'
};
// This is temporary solution for building BString with printf like format. // This is temporary solution for building BString with printf like format.
// will be removed in the future. // will be removed in the future.
static void static void
@@ -87,6 +123,7 @@ ShowImageWindow::ShowImageWindow(const entry_ref& ref,
fSlideShowDelay(NULL), fSlideShowDelay(NULL),
fImageView(NULL), fImageView(NULL),
fStatusView(NULL), fStatusView(NULL),
fProgressWindow(new ProgressWindow()),
fModified(false), fModified(false),
fFullScreen(false), fFullScreen(false),
fShowCaption(true), fShowCaption(true),
@@ -106,7 +143,8 @@ ShowImageWindow::ShowImageWindow(const entry_ref& ref,
// create the image view // create the image view
fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL, fImageView = new ShowImageView(viewFrame, "image_view", B_FOLLOW_ALL,
B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED); B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE | B_PULSE_NEEDED
| B_FRAME_EVENTS);
// wrap a scroll view around the view // wrap a scroll view around the view
BScrollView* scrollView = new BScrollView("image_scroller", fImageView, BScrollView* scrollView = new BScrollView("image_scroller", fImageView,
B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER); B_FOLLOW_ALL, 0, false, false, B_PLAIN_BORDER);
@@ -170,6 +208,8 @@ ShowImageWindow::ShowImageWindow(const entry_ref& ref,
ShowImageWindow::~ShowImageWindow() ShowImageWindow::~ShowImageWindow()
{ {
fProgressWindow->Lock();
fProgressWindow->Quit();
} }
@@ -212,7 +252,9 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
menu->AddSeparatorItem(); menu->AddSeparatorItem();
_AddItemMenu(menu, B_TRANSLATE("Original size"), _AddItemMenu(menu, B_TRANSLATE("Original size"),
MSG_ORIGINAL_SIZE, '1', 0, this); kMsgOriginalSize, '1', 0, this);
_AddItemMenu(menu, B_TRANSLATE("Fit to window"),
kMsgFitToWindow, '0', 0, this);
_AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this); _AddItemMenu(menu, B_TRANSLATE("Zoom in"), MSG_ZOOM_IN, '+', 0, this);
_AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this); _AddItemMenu(menu, B_TRANSLATE("Zoom out"), MSG_ZOOM_OUT, '-', 0, this);
@@ -221,13 +263,8 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
if (!popupMenu || fFullScreen) { if (!popupMenu || fFullScreen) {
_AddItemMenu(menu, B_TRANSLATE("High-quality zooming"), _AddItemMenu(menu, B_TRANSLATE("High-quality zooming"),
MSG_SCALE_BILINEAR, 0, 0, this); MSG_SCALE_BILINEAR, 0, 0, this);
menu->AddSeparatorItem();
_AddItemMenu(menu, B_TRANSLATE("Shrink to window"),
MSG_SHRINK_TO_WINDOW, 0, 0, this);
_AddItemMenu(menu, B_TRANSLATE("Stretch to window"), _AddItemMenu(menu, B_TRANSLATE("Stretch to window"),
MSG_STRETCH_TO_WINDOW, 0, 0, this); kMsgStretchToWindow, 0, 0, this);
menu->AddSeparatorItem(); menu->AddSeparatorItem();
} }
@@ -240,9 +277,8 @@ ShowImageWindow::_BuildViewMenu(BMenu* menu, bool popupMenu)
MSG_SHOW_CAPTION, 0, 0, this); MSG_SHOW_CAPTION, 0, 0, this);
_MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption); _MarkMenuItem(menu, MSG_SHOW_CAPTION, fShowCaption);
_MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->GetScaleBilinear()); _MarkMenuItem(menu, MSG_SCALE_BILINEAR, fImageView->ScaleBilinear());
_MarkMenuItem(menu, MSG_SHRINK_TO_WINDOW, fImageView->ShrinksToBounds()); _MarkMenuItem(menu, kMsgStretchToWindow, fImageView->StretchesToBounds());
_MarkMenuItem(menu, MSG_STRETCH_TO_WINDOW, fImageView->StretchesToBounds());
if (popupMenu) { if (popupMenu) {
menu->AddSeparatorItem(); menu->AddSeparatorItem();
@@ -369,10 +405,11 @@ ShowImageWindow::_AddDelayItem(BMenu* menu, const char* label, float value)
void void
ShowImageWindow::_WindowRedimension(BBitmap* bitmap) ShowImageWindow::_ResizeWindowToImage()
{ {
BBitmap* bitmap = fImageView->Bitmap();
BScreen screen; BScreen screen;
if (!screen.IsValid()) if (bitmap == NULL || !screen.IsValid())
return; return;
// TODO: use View::GetPreferredSize() instead? // TODO: use View::GetPreferredSize() instead?
@@ -410,13 +447,6 @@ ShowImageWindow::_WindowRedimension(BBitmap* bitmap)
} }
void
ShowImageWindow::FrameResized(float width, float height)
{
BWindow::FrameResized(width, height);
}
bool bool
ShowImageWindow::_ToggleMenuItem(uint32 what) ShowImageWindow::_ToggleMenuItem(uint32 what)
{ {
@@ -467,22 +497,30 @@ ShowImageWindow::_MarkSlideShowDelay(float value)
void void
ShowImageWindow::_ResizeToWindow(bool shrink, uint32 what) ShowImageWindow::Zoom(BPoint origin, float width, float height)
{ {
bool enabled = _ToggleMenuItem(what); _ToggleFullScreen();
if (shrink)
fImageView->SetShrinkToBounds(enabled);
else
fImageView->SetStretchToBounds(enabled);
} }
void void
ShowImageWindow::MessageReceived(BMessage* message) ShowImageWindow::MessageReceived(BMessage* message)
{ {
if (message->WasDropped()) {
uint32 type;
int32 count;
status_t status = message->GetInfo("refs", &type, &count);
if (status == B_OK && type == B_REF_TYPE) {
message->what = B_REFS_RECEIVED;
be_app->PostMessage(message);
}
}
switch (message->what) { switch (message->what) {
case kMsgImageLoaded: case kMsgImageCacheImageLoaded:
{ {
fProgressWindow->Stop();
bool first = fImageView->Bitmap() == NULL; bool first = fImageView->Bitmap() == NULL;
entry_ref ref; entry_ref ref;
message->FindRef("ref", &ref); message->FindRef("ref", &ref);
@@ -505,18 +543,25 @@ ShowImageWindow::MessageReceived(BMessage* message)
fNavigator.SetTo(ref, message->FindInt32("page"), fNavigator.SetTo(ref, message->FindInt32("page"),
message->FindInt32("pageCount")); message->FindInt32("pageCount"));
if (first || (!fImageView->StretchesToBounds() && !fFullScreen)) {
_ResizeWindowToImage();
fImageView->FitToBounds();
}
if (first) { if (first) {
_WindowRedimension(fImageView->Bitmap());
fImageView->ResetZoom();
fImageView->MakeFocus(true); fImageView->MakeFocus(true);
// to receive key messages // to receive key messages
Show(); Show();
} else { }
if (!fImageView->StretchesToBounds() break;
&& !fImageView->ShrinksToBounds() }
&& !fFullScreen)
_WindowRedimension(fImageView->Bitmap()); case kMsgImageCacheProgressUpdate:
{
entry_ref ref;
if (message->FindRef("ref", &ref) == B_OK
&& ref == fNavigator.CurrentRef()) {
message->what = kMsgProgressUpdate;
fProgressWindow->PostMessage(message);
} }
break; break;
} }
@@ -692,12 +737,13 @@ ShowImageWindow::MessageReceived(BMessage* message)
break; break;
} }
case MSG_SHRINK_TO_WINDOW: case kMsgFitToWindow:
_ResizeToWindow(true, message->what); fImageView->FitToBounds();
break; break;
case MSG_STRETCH_TO_WINDOW: case kMsgStretchToWindow:
_ResizeToWindow(false, message->what); fImageView->SetStretchToBounds(
_ToggleMenuItem(kMsgStretchToWindow));
break; break;
case MSG_FILE_PREV: case MSG_FILE_PREV:
@@ -802,7 +848,7 @@ ShowImageWindow::MessageReceived(BMessage* message)
fImageView->ZoomOut(); fImageView->ZoomOut();
break; break;
case MSG_ORIGINAL_SIZE: case kMsgOriginalSize:
fImageView->SetZoom(1.0); fImageView->SetZoom(1.0);
break; break;
@@ -984,6 +1030,8 @@ ShowImageWindow::_LoadImage(bool forward)
if (status != B_OK) if (status != B_OK)
return status; return status;
fProgressWindow->Start(this);
// Preload previous/next images - two in the navigation direction, one // Preload previous/next images - two in the navigation direction, one
// in the opposite direction. // in the opposite direction.
@@ -1034,10 +1082,12 @@ ShowImageWindow::_ToggleFullScreen()
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE)); SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
} }
fImageView->SetFullScreen(fFullScreen);
fImageView->SetShowCaption(fFullScreen && fShowCaption);
MoveTo(frame.left, frame.top); MoveTo(frame.left, frame.top);
ResizeTo(frame.Width(), frame.Height()); ResizeTo(frame.Width(), frame.Height());
fImageView->SetHideIdlingCursor(fFullScreen);
fImageView->SetShowCaption(fFullScreen && fShowCaption);
fImageView->FitToBounds();
} }
@@ -1199,11 +1249,5 @@ ShowImageWindow::QuitRequested()
return false; return false;
} }
bool quit = _ClosePrompt(); return _ClosePrompt();
if (quit) {
// tell the app to forget about this window
be_app->PostMessage(MSG_WINDOW_QUIT);
}
return quit;
} }
+18 -3
View File
@@ -21,10 +21,25 @@ class BFilePanel;
class BMenu; class BMenu;
class BMenuBar; class BMenuBar;
class BMenuItem; class BMenuItem;
class ProgressWindow;
class ShowImageView; class ShowImageView;
class ShowImageStatusView; class ShowImageStatusView;
// public message constants
enum {
MSG_MODIFIED = 'mMOD',
MSG_UPDATE_STATUS = 'mUPS',
MSG_UPDATE_STATUS_TEXT = 'mUPT',
MSG_SELECTION = 'mSEL',
MSG_FILE_NEXT = 'mFLN',
MSG_FILE_PREV = 'mFLP',
kMsgDeleteCurrentFile = 'mDcF',
MSG_SLIDE_SHOW = 'mSSW',
MSG_EXIT_FULL_SCREEN = 'mEFS'
};
class ShowImageWindow : public BWindow { class ShowImageWindow : public BWindow {
public: public:
ShowImageWindow(const entry_ref& ref, ShowImageWindow(const entry_ref& ref,
@@ -34,13 +49,13 @@ public:
void BuildContextMenu(BMenu* menu); void BuildContextMenu(BMenu* menu);
protected: protected:
virtual void FrameResized(float width, float height); virtual void Zoom(BPoint origin, float width, float height);
virtual void MessageReceived(BMessage* message); virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested(); virtual bool QuitRequested();
private: private:
void _AddMenus(BMenuBar* bar); void _AddMenus(BMenuBar* bar);
void _WindowRedimension(BBitmap* bitmap); void _ResizeWindowToImage();
void _BuildViewMenu(BMenu* menu, bool popupMenu); void _BuildViewMenu(BMenu* menu, bool popupMenu);
BMenuItem* _AddItemMenu(BMenu* menu, const char* label, BMenuItem* _AddItemMenu(BMenu* menu, const char* label,
uint32 what, char shortcut, uint32 modifier, uint32 what, char shortcut, uint32 modifier,
@@ -55,7 +70,6 @@ private:
void _MarkMenuItem(BMenu* menu, uint32 what, void _MarkMenuItem(BMenu* menu, uint32 what,
bool marked); bool marked);
void _MarkSlideShowDelay(float value); void _MarkSlideShowDelay(float value);
void _ResizeToWindow(bool shrink, uint32 what);
void _UpdateStatusText(const BMessage* message); void _UpdateStatusText(const BMessage* message);
void _LoadError(const entry_ref& ref); void _LoadError(const entry_ref& ref);
@@ -82,6 +96,7 @@ private:
BMenu* fSlideShowDelay; BMenu* fSlideShowDelay;
ShowImageView* fImageView; ShowImageView* fImageView;
ShowImageStatusView* fStatusView; ShowImageStatusView* fStatusView;
ProgressWindow* fProgressWindow;
bool fModified; bool fModified;
bool fFullScreen; bool fFullScreen;
bool fShowCaption; bool fShowCaption;