- renamed and restructured menu bar

- show dialog box when image can not be opened
- added optional caption in full screen mode
- moved/removed code from ShowImageApp to ShowImageView


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5289 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer 2003-11-09 09:54:46 +00:00
parent d10d59475c
commit e6a50d9c7b
5 changed files with 195 additions and 89 deletions

View File

@ -54,10 +54,11 @@ const uint32 MSG_ROTATE_ACLKWISE = 'mRAC';
const uint32 MSG_MIRROR_VERTICAL = 'mMIV';
const uint32 MSG_MIRROR_HORIZONTAL = 'mMIH';
const uint32 MSG_INVERT = 'mINV';
const uint32 MSG_DIA_SHOW = 'mDIA';
const uint32 MSG_DIA_SHOW_DELAY = 'mDSD';
const uint32 MSG_SLIDE_SHOW = 'mSSW';
const uint32 MSG_SLIDE_SHOW_DELAY = 'mSSD';
const uint32 MSG_FULL_SCREEN = 'mFSC';
const uint32 MSG_UPDATE_RECENT_DOCUMENTS = 'mURD';
const uint32 MSG_SHOW_CAPTION = 'mSCP';
extern const char *APP_SIG;

View File

@ -45,6 +45,7 @@
#include <Roster.h>
#include <NodeInfo.h>
#include <Clipboard.h>
#include <Path.h>
#include "ShowImageConstants.h"
#include "ShowImageView.h"
@ -132,10 +133,10 @@ ShowImageView::Pulse()
RotatePatterns();
DrawSelectionBox(fSelectionRect);
}
if (fDiaShow) {
fDiaShowCountDown --;
if (fDiaShowCountDown <= 0) {
fDiaShowCountDown = fDiaShowDelay;
if (fSlideShow) {
fSlideShowCountDown --;
if (fSlideShowCountDown <= 0) {
fSlideShowCountDown = fSlideShowDelay;
if (!NextFile()) {
FirstFile();
}
@ -155,9 +156,10 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
fAnimateSelection = true;
fbHasSelection = false;
fResizeToViewBounds = false;
fDiaShow = false;
SetDiaShowDelay(3); // 3 seconds
fSlideShow = false;
SetSlideShowDelay(3); // 3 seconds
fBeginDrag = false;
fShowCaption = false;
SetViewColor(B_TRANSPARENT_COLOR);
SetHighColor(kborderColor);
@ -201,7 +203,6 @@ ShowImageView::Notify(const char* status)
if (status != NULL) {
msg.AddString("status", status);
}
msg.AddRef("ref", &fCurrentRef);
BMessenger msgr(Window());
msgr.SendMessage(&msg);
@ -262,12 +263,27 @@ ShowImageView::SetImage(const entry_ref *pref)
fDocumentCount = documentCount;
else
fDocumentCount = 1;
GetPath(&fCaption);
if (fDocumentCount > 1) {
fCaption << ", " << fDocumentIndex << "/" << fDocumentCount;
}
fCaption << ", " << info.name;
AddToRecentDocuments();
Notify(info.name);
}
void
ShowImageView::SetShowCaption(bool show)
{
if (fShowCaption != show) {
fShowCaption = show;
Invalidate();
}
}
void
ShowImageView::ResizeToViewBounds(bool resize)
{
@ -284,6 +300,20 @@ ShowImageView::GetBitmap()
return fpBitmap;
}
void
ShowImageView::GetPath(BString *name)
{
*name = "";
BEntry entry(&fCurrentRef);
if (entry.InitCheck() == B_OK) {
BPath path;
entry.GetPath(&path);
if (path.InitCheck() == B_OK) {
name->SetTo(path.Path());
}
}
}
void
ShowImageView::FlushToLeftTop()
{
@ -379,6 +409,49 @@ ShowImageView::DrawBorder(BRect border)
FillRect(BRect(0, border.bottom+1, bounds.right, bounds.bottom), B_SOLID_LOW);
}
void
ShowImageView::DrawCaption()
{
font_height fontHeight;
float width, height;
BRect bounds(Bounds());
BFont font(be_plain_font);
BPoint pos;
BRect rect;
width = font.StringWidth(fCaption.String())+1; // 1 for text shadow
font.GetHeight(&fontHeight);
height = fontHeight.ascent + fontHeight.descent;
// center text vertically
pos.x = (bounds.left + bounds.right - width)/2;
// flush bottom
pos.y = bounds.bottom - fontHeight.descent - 5;
// background rectangle
rect.Set(0, 0, (width-1)+2, (height-1)+2+1); // 2 for border and 1 for text shadow
rect.OffsetTo(pos);
rect.OffsetBy(-1, -1-fontHeight.ascent); // -1 for border
PushState();
// draw background
SetDrawingMode(B_OP_ALPHA);
SetHighColor(0, 0, 255, 128);
FillRect(rect);
// draw text
SetDrawingMode(B_OP_OVER);
SetFont(&font);
SetLowColor(B_TRANSPARENT_COLOR);
// text shadow
pos += BPoint(1, 1);
SetHighColor(0, 0, 0);
SetPenSize(1);
DrawString(fCaption.String(), pos);
// text
pos -= BPoint(1, 1);
SetHighColor(255, 255, 0);
DrawString(fCaption.String(), pos);
PopState();
}
void
ShowImageView::Draw(BRect updateRect)
{
@ -397,8 +470,13 @@ ShowImageView::Draw(BRect updateRect)
// Draw image
DrawBitmap(fpBitmap, fpBitmap->Bounds(), rect);
if (fbHasSelection)
if (fShowCaption) {
DrawCaption();
}
if (fbHasSelection) {
DrawSelectionBox(fSelectionRect);
}
}
}
@ -780,7 +858,7 @@ ShowImageView::CopySelectionToClipboard()
BMessage data;
BBitmap* bitmap = CopySelection();
if (bitmap != NULL) {
#if 1
#if 0
// According to BeBook and Becasso, Gobe Productive do the following.
// Paste works in Productive, but not in Becasso and original ShowImage.
BMessage msg(B_OK); // Becasso uses B_TRANSLATOR_BITMAP, BeBook says its unused
@ -932,21 +1010,21 @@ ShowImageView::FirstFile()
}
void
ShowImageView::SetDiaShowDelay(float seconds)
ShowImageView::SetSlideShowDelay(float seconds)
{
fDiaShowDelay = (int)(seconds * 10.0);
fSlideShowDelay = (int)(seconds * 10.0);
}
void
ShowImageView::StartDiaShow()
ShowImageView::StartSlideShow()
{
fDiaShow = true; fDiaShowCountDown = fDiaShowDelay;
fSlideShow = true; fSlideShowCountDown = fSlideShowDelay;
}
void
ShowImageView::StopDiaShow()
ShowImageView::StopSlideShow()
{
fDiaShow = false;
fSlideShow = false;
}
int32

View File

@ -44,8 +44,10 @@ public:
void Pulse();
void SetImage(const entry_ref *pref);
void SetShowCaption(bool show);
void ResizeToViewBounds(bool resize);
BBitmap *GetBitmap();
void GetPath(BString *name);
void FlushToLeftTop();
virtual void AttachedToWindow();
@ -72,9 +74,9 @@ public:
void PrevPage();
bool NextFile();
bool PrevFile();
void SetDiaShowDelay(float seconds);
void StartDiaShow();
void StopDiaShow();
void SetSlideShowDelay(float seconds);
void StartSlideShow();
void StopSlideShow();
// Image manipulation
void Rotate(int degree); // 90 and 270 only
@ -118,6 +120,7 @@ private:
void HandleDrop(BMessage* msg);
void UpdateSelectionRect(BPoint point, bool final);
void DrawBorder(BRect border);
void DrawCaption();
void DrawSelectionBox(BRect &rect);
entry_ref fCurrentRef;
@ -137,9 +140,12 @@ private:
BRect fSelectionRect; // the selection in image space
pattern fPatternUp, fPatternDown, fPatternLeft, fPatternRight;
bool fDiaShow;
int fDiaShowDelay;
int fDiaShowCountDown;
bool fSlideShow;
int fSlideShowDelay;
int fSlideShowCountDown;
bool fShowCaption;
BString fCaption;
};
#endif /* _ShowImageView_h */

View File

@ -54,8 +54,8 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
: BWindow(BRect(50, 50, 350, 250), "", B_DOCUMENT_WINDOW, 0)
{
fpSavePanel = NULL;
fpRef = NULL;
fFullScreen = false;
fShowCaption = true; // XXX what is best for default?
// create menu bar
fpBar = new BMenuBar(BRect(0, 0, Bounds().right, 20), "menu_bar");
@ -104,7 +104,6 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
SetSizeLimits(250, 100000, 100, 100000);
// finish creating window
SetRef(pref);
UpdateTitle();
fpImageView->SetImage(pref);
@ -116,6 +115,12 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
WindowRedimension(fpImageView->GetBitmap());
Show();
} else {
BAlert* alert;
alert = new BAlert("ShowImage",
"Could not load image! Either the file or an image translator for it does not exist.",
"OK", NULL, NULL,
B_WIDTH_AS_USUAL, B_INFO_ALERT);
alert->Go();
// exit if file could not be opened
Quit();
}
@ -123,37 +128,23 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
ShowImageWindow::~ShowImageWindow()
{
delete fpRef;
}
status_t
ShowImageWindow::InitCheck()
{
if (!fpRef || !fpImageView || fpImageView->GetBitmap() == NULL)
if (!fpImageView || fpImageView->GetBitmap() == NULL)
return B_ERROR;
else
return B_OK;
}
void
ShowImageWindow::SetRef(const entry_ref *pref)
{
if (!fpRef)
fpRef = new entry_ref(*pref);
else
*fpRef = *pref;
}
void
ShowImageWindow::UpdateTitle()
{
BEntry entry(fpRef);
if (entry.InitCheck() == B_OK) {
BPath path;
entry.GetPath(&path);
if (path.InitCheck() == B_OK)
SetTitle(path.Path());
}
BString path;
fpImageView->GetPath(&path);
SetTitle(path.String());
}
void
@ -191,29 +182,6 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
fpOpenMenu->Superitem()->SetTarget(be_app);
fpOpenMenu->Superitem()->SetShortcut('O', 0);
pmenu->AddSeparatorItem();
AddItemMenu(pmenu, "Dia Show", MSG_DIA_SHOW, 0, 0, 'W', true);
BMenu* pDelay = new BMenu("Delay");
pDelay->SetRadioMode(true);
// Note: ShowImage loades images in window thread so it becomes unresponsive if
// dia show delay is too short! (Especially if loading the image takes as long as
// or longer than the dia 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, "Tweenty Seconds", 20, false);
pmenu->AddItem(pDelay);
pmenu->AddSeparatorItem();
AddItemMenu(pmenu, "Next", MSG_FILE_NEXT, B_DOWN_ARROW, 0, 'W', true);
AddItemMenu(pmenu, "Previous", MSG_FILE_PREV, B_UP_ARROW, 0, 'W', true);
pmenu->AddSeparatorItem();
BMenu *pmenuSaveAs = new BMenu("Save As...", B_ITEMS_IN_COLUMN);
BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
// Fill Save As submenu with all types that can be converted
@ -237,11 +205,14 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
pbar->AddItem(pmenu);
pmenu = fpPageMenu = new BMenu("Page");
AddItemMenu(pmenu, "First", MSG_PAGE_FIRST, 'F', 0, 'W', true);
AddItemMenu(pmenu, "Last", MSG_PAGE_LAST, 'L', 0, 'W', true);
AddItemMenu(pmenu, "Next", MSG_PAGE_NEXT, 'N', 0, 'W', true);
AddItemMenu(pmenu, "Previous", MSG_PAGE_PREV, 'P', 0, 'W', true);
pmenu = fpBrowseMenu = new BMenu("Browse");
AddItemMenu(pmenu, "First Page", MSG_PAGE_FIRST, 'F', 0, 'W', true);
AddItemMenu(pmenu, "Last Page", MSG_PAGE_LAST, 'L', 0, 'W', true);
AddItemMenu(pmenu, "Next Page", MSG_PAGE_NEXT, 'N', 0, 'W', true);
AddItemMenu(pmenu, "Previous Page", MSG_PAGE_PREV, 'P', 0, 'W', true);
pmenu->AddSeparatorItem();
AddItemMenu(pmenu, "Next File", MSG_FILE_NEXT, B_DOWN_ARROW, 0, 'W', true);
AddItemMenu(pmenu, "Previous File", MSG_FILE_PREV, B_UP_ARROW, 0, 'W', true);
pbar->AddItem(pmenu);
pmenu = new BMenu("Image");
@ -257,9 +228,31 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
pbar->AddItem(pmenu);
pmenu = new BMenu("View");
AddItemMenu(pmenu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
BMenu* pDelay = new BMenu("Slide Delay");
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, "Tweenty Seconds", 20, false);
pmenu->AddItem(pDelay);
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();
}
@ -285,7 +278,7 @@ ShowImageWindow::AddDelayItem(BMenu *pmenu, char *caption, float value, bool mar
{
BMenuItem* pitem;
BMessage* pmsg;
pmsg = new BMessage(MSG_DIA_SHOW_DELAY);
pmsg = new BMessage(MSG_SLIDE_SHOW_DELAY);
pmsg->AddFloat("value", value);
pitem = new BMenuItem(caption, pmsg, 0);
@ -341,6 +334,30 @@ ShowImageWindow::ToggleMenuItem(uint32 what)
return marked;
}
void
ShowImageWindow::EnableMenuItem(uint32 what, bool enable)
{
BMenuItem* item;
item = fpBar->FindItem(what);
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);
}
}
void
ShowImageWindow::MarkMenuItem(uint32 what, bool marked)
{
BMenuItem* item;
item = fpBar->FindItem(what);
if (item && item->IsMarked() != marked) {
item->SetMarked(marked);
}
}
void
ShowImageWindow::MessageReceived(BMessage *pmsg)
{
@ -370,20 +387,16 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
case MSG_UPDATE_STATUS:
{
bool benable = (fpImageView->PageCount() > 1) ? true : false;
if (fpPageMenu->IsEnabled() != benable)
// Only call this function if the state is changing
// to avoid flickering
fpPageMenu->SetEnabled(benable);
EnableMenuItem(MSG_PAGE_FIRST, benable);
EnableMenuItem(MSG_PAGE_LAST, benable);
EnableMenuItem(MSG_PAGE_NEXT, benable);
EnableMenuItem(MSG_PAGE_PREV, benable);
BString str;
if (pmsg->FindString("status", &str) == B_OK)
fpStatusView->SetText(str);
entry_ref ref;
if (pmsg->FindRef("ref", &ref) == B_OK) {
SetRef(&ref);
UpdateTitle();
}
UpdateTitle();
break;
}
@ -454,17 +467,17 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
case MSG_INVERT:
fpImageView->Invert();
break;
case MSG_DIA_SHOW:
case MSG_SLIDE_SHOW:
if (ToggleMenuItem(pmsg->what)) {
fpImageView->StartDiaShow();
fpImageView->StartSlideShow();
} else {
fpImageView->StopDiaShow();
fpImageView->StopSlideShow();
}
case MSG_DIA_SHOW_DELAY:
case MSG_SLIDE_SHOW_DELAY:
{
float value;
if (pmsg->FindFloat("value", &value) == B_OK) {
fpImageView->SetDiaShowDelay(value);
fpImageView->SetSlideShowDelay(value);
}
}
break;
@ -472,6 +485,12 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
case MSG_FULL_SCREEN:
ToggleFullScreen();
break;
case MSG_SHOW_CAPTION:
fShowCaption = ToggleMenuItem(pmsg->what);
if (fFullScreen) {
fpImageView->SetShowCaption(fShowCaption);
}
break;
case MSG_UPDATE_RECENT_DOCUMENTS:
UpdateRecentDocumentsMenu();
@ -584,6 +603,7 @@ ShowImageWindow::ToggleFullScreen()
SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
}
fpImageView->SetShowCaption(fFullScreen && fShowCaption);
MoveTo(frame.left, frame.top);
ResizeTo(frame.Width(), frame.Height());
}

View File

@ -54,7 +54,6 @@ public:
status_t InitCheck();
ShowImageView *GetShowImageView() const { return fpImageView; }
void SetRef(const entry_ref *pref);
void UpdateTitle();
void LoadMenus(BMenuBar *pbar);
void WindowRedimension(BBitmap *pbitmap);
@ -68,6 +67,8 @@ private:
void UpdateRecentDocumentsMenu();
bool ToggleMenuItem(uint32 what);
void EnableMenuItem(uint32 what, bool enable);
void MarkMenuItem(uint32 what, bool marked);
void SaveAs(BMessage *pmsg);
// Handle Save As submenu choice
@ -80,12 +81,12 @@ private:
BFilePanel *fpSavePanel;
BMenuBar *fpBar;
BMenu *fpOpenMenu;
BMenu *fpPageMenu;
entry_ref *fpRef;
BMenu *fpBrowseMenu;
ShowImageView *fpImageView;
ShowImageStatusView *fpStatusView;
bool fFullScreen;
BRect fWindowFrame;
bool fShowCaption;
};
#endif /* _ShowImageWindow_h */