- added printing support
- added zoom in and out - next/previous file sorts directory entries by itself; does not rely on file system - added shortcuts to the first 10 menu items of Go To sub menu git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5299 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
257e63ba7f
commit
780d8a62d7
265
src/apps/showimage/PrintOptionsWindow.cpp
Normal file
265
src/apps/showimage/PrintOptionsWindow.cpp
Normal file
@ -0,0 +1,265 @@
|
||||
/*****************************************************************************/
|
||||
// PrintOptionsWindow
|
||||
// Written by Fernando Francisco de Oliveira, Michael Wilber, Michael Pfeiffer
|
||||
//
|
||||
// PrintOptionsWindow.cpp
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2003 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <Box.h>
|
||||
#include <Button.h>
|
||||
#include <String.h>
|
||||
#include <stdio.h> // for sprintf
|
||||
#include <stdlib.h> // for atof
|
||||
|
||||
#include "PrintOptionsWindow.h"
|
||||
#include "ShowImageConstants.h"
|
||||
|
||||
PrintOptions::PrintOptions()
|
||||
: fOption(kFitToPage)
|
||||
, fZoomFactor(1.0)
|
||||
, fDPI(72.0)
|
||||
, fWidth(1024 / 72.0)
|
||||
, fHeight(768 / 72.0)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptions::SetBounds(BRect rect)
|
||||
{
|
||||
fBounds = rect;
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptions::SetZoomFactor(float f)
|
||||
{
|
||||
fZoomFactor = f;
|
||||
fDPI = 72.0 / fZoomFactor;
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptions::SetDPI(float dpi)
|
||||
{
|
||||
fDPI = dpi;
|
||||
fZoomFactor = 72.0 / dpi;
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptions::SetWidth(float w)
|
||||
{
|
||||
fWidth = w;
|
||||
fHeight = (fBounds.Height()+1) * w / (fBounds.Width()+1);
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptions::SetHeight(float h)
|
||||
{
|
||||
fWidth = (fBounds.Width()+1) * h / (fBounds.Height()+1);
|
||||
fHeight = h;
|
||||
}
|
||||
|
||||
PrintOptionsWindow::PrintOptionsWindow(BPoint at, PrintOptions *options, BWindow* listener)
|
||||
: BWindow(BRect(at.x, at.y, at.x+300, at.y+200), "Print Options",
|
||||
B_TITLED_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
|
||||
B_NOT_ZOOMABLE | B_NOT_RESIZABLE)
|
||||
, fPrintOptions(options)
|
||||
, fCurrentOptions(*options)
|
||||
, fListener(listener)
|
||||
, fStatus(B_ERROR)
|
||||
{
|
||||
AddToSubset(listener);
|
||||
Setup();
|
||||
Show();
|
||||
}
|
||||
|
||||
PrintOptionsWindow::~PrintOptionsWindow()
|
||||
{
|
||||
BMessage msg(MSG_PRINT);
|
||||
msg.AddInt32("status", fStatus);
|
||||
fListener.SendMessage(&msg);
|
||||
}
|
||||
|
||||
BRadioButton*
|
||||
PrintOptionsWindow::AddRadioButton(BView* view, BPoint& at, const char* name, const char* label, uint32 what, bool selected)
|
||||
{
|
||||
BRect rect(0, 0, 100, 20);
|
||||
BRadioButton* button;
|
||||
rect.OffsetBy(at);
|
||||
button = new BRadioButton(rect, name, label, new BMessage(what));
|
||||
view->AddChild(button);
|
||||
button->ResizeToPreferred();
|
||||
at.y += button->Bounds().Height() + kLineSkip;
|
||||
button->SetValue(selected ? B_CONTROL_ON : B_CONTROL_OFF);
|
||||
return button;
|
||||
}
|
||||
|
||||
BTextControl*
|
||||
PrintOptionsWindow::AddTextControl(BView* view, BPoint& at, const char* name, const char* label, float value, float divider, uint32 what)
|
||||
{
|
||||
BRect rect(0, 0, divider + 45, 20);
|
||||
BTextControl* text;
|
||||
rect.OffsetBy(at);
|
||||
text = new BTextControl(rect, name, label, "", new BMessage(what));
|
||||
view->AddChild(text);
|
||||
text->SetModificationMessage(new BMessage(what));
|
||||
text->SetDivider(divider);
|
||||
text->SetAlignment(B_ALIGN_LEFT, B_ALIGN_RIGHT);
|
||||
SetValue(text, value);
|
||||
at.y += text->Bounds().Height() + kLineSkip;
|
||||
return text;
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptionsWindow::Setup()
|
||||
{
|
||||
BRect rect(Bounds());
|
||||
BPoint at(kIndent, kIndent), textAt;
|
||||
BString value;
|
||||
enum PrintOptions::Option op = fCurrentOptions.Option();
|
||||
BRadioButton* rb;
|
||||
BBox* line;
|
||||
BButton* button;
|
||||
|
||||
BBox *panel = new BBox(rect, "top_panel", B_FOLLOW_ALL,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
|
||||
B_PLAIN_BORDER);
|
||||
AddChild(panel);
|
||||
|
||||
AddRadioButton(panel, at, "fit_to_page", "Fit Image to Page", kMsgFitToPageSelected, op == PrintOptions::kFitToPage);
|
||||
textAt = at;
|
||||
rb = AddRadioButton(panel, at, "zoom_factor", "Zoom Factor in %: ", kMsgZoomFactorSelected, op == PrintOptions::kZoomFactor);
|
||||
textAt.x = rb->Bounds().right + 5;
|
||||
fZoomFactor = AddTextControl(panel, textAt, "zoom_factor_text", "", fCurrentOptions.ZoomFactor()*100, 0, kMsgZoomFactorChanged);
|
||||
|
||||
textAt = at;
|
||||
rb = AddRadioButton(panel, at, "dpi", "DPI: ", kMsgDPISelected, op == PrintOptions::kDPI);
|
||||
textAt.x = rb->Bounds().right + 5;
|
||||
fDPI = AddTextControl(panel, textAt, "dpi_text", "", fCurrentOptions.DPI(), 0, kMsgDPIChanged);
|
||||
|
||||
rb = AddRadioButton(panel, at, "width_and_height", "Resize To (in 1/72 Inches):", kMsgWidthAndHeightSelected, op == PrintOptions::kWidth || op == PrintOptions::kHeight);
|
||||
at.x += 15;
|
||||
textAt = at;
|
||||
fWidth = AddTextControl(panel, textAt, "width", "Width: ", fCurrentOptions.Width(), 40, kMsgWidthChanged);
|
||||
textAt = at;
|
||||
textAt.x += fWidth->Bounds().Width() + 5;
|
||||
fHeight = AddTextControl(panel, textAt, "height", "Height: ", fCurrentOptions.Height(), 40, kMsgHeightChanged);
|
||||
|
||||
at.x = 0;
|
||||
at.y = textAt.y;
|
||||
line = new BBox(BRect(rect.left+3, at.y, rect.right-3, at.y + 1), NULL,
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP);
|
||||
panel->AddChild(line);
|
||||
|
||||
at.y += 10;
|
||||
rect.OffsetBy(at);
|
||||
button = new BButton(rect, "job setup", "Job Setup", new BMessage(kMsgJobSetup));
|
||||
panel->AddChild(button);
|
||||
button->ResizeToPreferred();
|
||||
|
||||
SetDefaultButton(button);
|
||||
|
||||
// resize window
|
||||
ResizeTo(fHeight->Frame().right + kIndent, button->Frame().bottom + kIndent);
|
||||
|
||||
// center button
|
||||
button->MoveTo((Bounds().Width()-button->Bounds().Width())/2, button->Frame().top);
|
||||
}
|
||||
|
||||
enum PrintOptions::Option
|
||||
PrintOptionsWindow::MsgToOption(uint32 what) {
|
||||
switch (what) {
|
||||
case kMsgFitToPageSelected: return PrintOptions::kFitToPage;
|
||||
case kMsgZoomFactorSelected: return PrintOptions::kZoomFactor;
|
||||
case kMsgDPISelected: return PrintOptions::kDPI;
|
||||
case kMsgWidthAndHeightSelected: return PrintOptions::kWidth;
|
||||
}
|
||||
return PrintOptions::kFitToPage;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintOptionsWindow::GetValue(BTextControl* text, float* value)
|
||||
{
|
||||
*value = atof(text->Text());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptionsWindow::SetValue(BTextControl* text, float value)
|
||||
{
|
||||
BMessage* msg;
|
||||
char s[80];
|
||||
sprintf(s, "%0.0f", value);
|
||||
// prevent sending a notification when text is set
|
||||
msg = new BMessage(*text->ModificationMessage());
|
||||
text->SetModificationMessage(NULL);
|
||||
text->SetText(s);
|
||||
text->SetModificationMessage(msg);
|
||||
}
|
||||
|
||||
void
|
||||
PrintOptionsWindow::MessageReceived(BMessage* msg)
|
||||
{
|
||||
float value;
|
||||
switch (msg->what) {
|
||||
case kMsgFitToPageSelected:
|
||||
case kMsgZoomFactorSelected:
|
||||
case kMsgDPISelected:
|
||||
case kMsgWidthAndHeightSelected:
|
||||
fCurrentOptions.SetOption(MsgToOption(msg->what));
|
||||
break;
|
||||
|
||||
case kMsgZoomFactorChanged:
|
||||
if (GetValue(fZoomFactor, &value) && fCurrentOptions.ZoomFactor() != value) {
|
||||
fCurrentOptions.SetZoomFactor(value/100);
|
||||
SetValue(fDPI, fCurrentOptions.DPI());
|
||||
}
|
||||
break;
|
||||
case kMsgDPIChanged:
|
||||
if (GetValue(fDPI, &value) && fCurrentOptions.DPI() != value) {
|
||||
fCurrentOptions.SetDPI(value);
|
||||
SetValue(fZoomFactor, 100*fCurrentOptions.ZoomFactor());
|
||||
}
|
||||
break;
|
||||
case kMsgWidthChanged:
|
||||
if (GetValue(fWidth, &value) && fCurrentOptions.Width() != value) {
|
||||
fCurrentOptions.SetWidth(value);
|
||||
SetValue(fHeight, fCurrentOptions.Height());
|
||||
}
|
||||
break;
|
||||
case kMsgHeightChanged:
|
||||
if (GetValue(fHeight, &value) && fCurrentOptions.Height() != value) {
|
||||
fCurrentOptions.SetHeight(value);
|
||||
SetValue(fWidth, fCurrentOptions.Width());
|
||||
}
|
||||
break;
|
||||
|
||||
case kMsgJobSetup:
|
||||
*fPrintOptions = fCurrentOptions;
|
||||
fStatus = B_OK;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
119
src/apps/showimage/PrintOptionsWindow.h
Normal file
119
src/apps/showimage/PrintOptionsWindow.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*****************************************************************************/
|
||||
// PrintOptionsWindow
|
||||
// Written by Fernando Francisco de Oliveira, Michael Wilber, Michael Pfeiffer
|
||||
//
|
||||
// PrintOptionsWindow.h
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2003 OpenBeOS Project
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included
|
||||
// in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef _PrintOptionsWindow_h
|
||||
#define _PrintOptionsWindow_h
|
||||
|
||||
#include <Window.h>
|
||||
#include <RadioButton.h>
|
||||
#include <TextControl.h>
|
||||
#include <Messenger.h>
|
||||
#include <Rect.h>
|
||||
|
||||
class PrintOptions {
|
||||
public:
|
||||
enum Option {
|
||||
kFitToPage,
|
||||
kZoomFactor,
|
||||
kDPI,
|
||||
kWidth,
|
||||
kHeight
|
||||
};
|
||||
|
||||
PrintOptions();
|
||||
|
||||
// bounds of the image
|
||||
BRect Bounds() const { return fBounds; }
|
||||
void SetBounds(BRect bounds);
|
||||
|
||||
Option Option() const { return fOption; }
|
||||
void SetOption(Option op) { fOption = op; }
|
||||
// zoomFactor = 72.0 / dpi
|
||||
float ZoomFactor() const { return fZoomFactor; }
|
||||
void SetZoomFactor(float z);
|
||||
float DPI() const { return fDPI; }
|
||||
void SetDPI(float dpi);
|
||||
// setting width/height updates height/width to keep aspect ratio
|
||||
float Width() const { return fWidth; }
|
||||
float Height() const { return fHeight; }
|
||||
void SetWidth(float width);
|
||||
void SetHeight(float height);
|
||||
|
||||
private:
|
||||
BRect fBounds;
|
||||
Option fOption;
|
||||
float fZoomFactor;
|
||||
float fDPI;
|
||||
float fWidth, fHeight; // 1/72 Inches
|
||||
};
|
||||
|
||||
class PrintOptionsWindow : public BWindow
|
||||
{
|
||||
public:
|
||||
PrintOptionsWindow(BPoint at, PrintOptions* options, BWindow* listener);
|
||||
~PrintOptionsWindow();
|
||||
|
||||
void MessageReceived(BMessage* msg);
|
||||
|
||||
private:
|
||||
BRadioButton* AddRadioButton(BView* view, BPoint& at, const char* name, const char* label, uint32 what, bool selected);
|
||||
BTextControl* AddTextControl(BView* view, BPoint& at, const char* name, const char* label, float value, float divider, uint32 what);
|
||||
void Setup();
|
||||
enum PrintOptions::Option MsgToOption(uint32 what);
|
||||
bool GetValue(BTextControl* text, float* value);
|
||||
void SetValue(BTextControl* text, float value);
|
||||
|
||||
enum {
|
||||
kMsgOK = 'mPOW',
|
||||
kMsgFitToPageSelected,
|
||||
kMsgZoomFactorSelected,
|
||||
kMsgDPISelected,
|
||||
kMsgWidthAndHeightSelected,
|
||||
|
||||
kMsgZoomFactorChanged,
|
||||
kMsgDPIChanged,
|
||||
kMsgWidthChanged,
|
||||
kMsgHeightChanged,
|
||||
|
||||
kMsgJobSetup,
|
||||
|
||||
kIndent = 5,
|
||||
kLineSkip = 5,
|
||||
};
|
||||
|
||||
PrintOptions* fPrintOptions;
|
||||
PrintOptions fCurrentOptions;
|
||||
BMessenger fListener;
|
||||
status_t fStatus;
|
||||
BTextControl* fZoomFactor;
|
||||
BTextControl* fDPI;
|
||||
BTextControl* fWidth;
|
||||
BTextControl* fHeight;
|
||||
};
|
||||
|
||||
#endif
|
@ -60,6 +60,12 @@ 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';
|
||||
const uint32 MSG_PAGE_SETUP = 'mPSU';
|
||||
const uint32 MSG_PREPARE_PRINT = 'mPPT';
|
||||
const uint32 MSG_PRINT = 'mPRT';
|
||||
const uint32 MSG_ZOOM_IN = 'mZIN';
|
||||
const uint32 MSG_ZOOM_OUT = 'mZOU';
|
||||
const uint32 MSG_ORIGINAL_SIZE = 'mOSZ';
|
||||
|
||||
extern const char *APP_SIG;
|
||||
|
||||
|
@ -160,6 +160,7 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
|
||||
SetSlideShowDelay(3); // 3 seconds
|
||||
fBeginDrag = false;
|
||||
fShowCaption = false;
|
||||
fZoom = 1.0;
|
||||
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
SetHighColor(kborderColor);
|
||||
@ -300,6 +301,19 @@ ShowImageView::GetBitmap()
|
||||
return fpBitmap;
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::GetName(BString *name)
|
||||
{
|
||||
*name = "";
|
||||
BEntry entry(&fCurrentRef);
|
||||
if (entry.InitCheck() == B_OK) {
|
||||
char n[B_FILE_NAME_LENGTH];
|
||||
if (entry.GetName(n) == B_OK) {
|
||||
name->SetTo(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::GetPath(BString *name)
|
||||
{
|
||||
@ -353,6 +367,7 @@ ShowImageView::AlignBitmap() const
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rect.right *= fZoom; rect.bottom *= fZoom;
|
||||
rect.OffsetBy(BORDER_WIDTH, BORDER_WIDTH);
|
||||
}
|
||||
rect.OffsetBy(PEN_SIZE, PEN_SIZE);
|
||||
@ -421,7 +436,7 @@ ShowImageView::DrawCaption()
|
||||
width = font.StringWidth(fCaption.String())+1; // 1 for text shadow
|
||||
font.GetHeight(&fontHeight);
|
||||
height = fontHeight.ascent + fontHeight.descent;
|
||||
// center text vertically
|
||||
// center text horizontally
|
||||
pos.x = (bounds.left + bounds.right - width)/2;
|
||||
// flush bottom
|
||||
pos.y = bounds.bottom - fontHeight.descent - 5;
|
||||
@ -456,6 +471,7 @@ void
|
||||
ShowImageView::Draw(BRect updateRect)
|
||||
{
|
||||
if (fpBitmap) {
|
||||
if (!IsPrinting()) {
|
||||
BRect rect = AlignBitmap();
|
||||
Setup(rect);
|
||||
|
||||
@ -477,6 +493,9 @@ ShowImageView::Draw(BRect updateRect)
|
||||
if (fbHasSelection) {
|
||||
DrawSelectionBox(fSelectionRect);
|
||||
}
|
||||
} else {
|
||||
DrawBitmap(fpBitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,6 +802,7 @@ void
|
||||
ShowImageView::FixupScrollBars()
|
||||
{
|
||||
BScrollBar *psb;
|
||||
|
||||
if (fResizeToViewBounds) {
|
||||
psb = ScrollBar(B_HORIZONTAL);
|
||||
if (psb) psb->SetRange(0, 0);
|
||||
@ -792,8 +812,10 @@ ShowImageView::FixupScrollBars()
|
||||
}
|
||||
|
||||
BRect rctview = Bounds(), rctbitmap(0, 0, 0, 0);
|
||||
if (fpBitmap)
|
||||
rctbitmap = fpBitmap->Bounds();
|
||||
if (fpBitmap) {
|
||||
BRect rect(AlignBitmap());
|
||||
rctbitmap.Set(0, 0, rect.Width(), rect.Height());
|
||||
}
|
||||
|
||||
float prop, range;
|
||||
psb = ScrollBar(B_HORIZONTAL);
|
||||
@ -914,6 +936,15 @@ ShowImageView::PrevPage()
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ShowImageView::CompareEntries(const void* a, const void* b)
|
||||
{
|
||||
entry_ref *r1, *r2;
|
||||
r1 = *(entry_ref**)a;
|
||||
r2 = *(entry_ref**)b;
|
||||
return strcasecmp(r1->name, r2->name);
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::GoToPage(int32 page)
|
||||
{
|
||||
@ -928,72 +959,76 @@ ShowImageView::FreeEntries(BList* entries)
|
||||
{
|
||||
const int32 n = entries->CountItems();
|
||||
for (int32 i = 0; i < n; i ++) {
|
||||
BEntry* entry = (BEntry*)entries->ItemAt(i);
|
||||
delete entry;
|
||||
entry_ref* ref = (entry_ref*)entries->ItemAt(i);
|
||||
delete ref;
|
||||
}
|
||||
entries->MakeEmpty();
|
||||
}
|
||||
|
||||
// Notes: BDirectory::GetNextEntry() must not necessary
|
||||
// return entries sorted by name, thou BFS does.
|
||||
bool
|
||||
ShowImageView::FindNextImage(BEntry* image, bool next, bool rewind)
|
||||
ShowImageView::FindNextImage(entry_ref* image, bool next, bool rewind)
|
||||
{
|
||||
ASSERT(next || !rewind);
|
||||
BEntry curImage(&fCurrentRef);
|
||||
BEntry entry;
|
||||
entry_ref entry, *ref;
|
||||
BDirectory parent;
|
||||
BList entries;
|
||||
bool found = false;
|
||||
int32 cur;
|
||||
|
||||
if (curImage.GetParent(&parent) != B_OK)
|
||||
return false;
|
||||
|
||||
while (parent.GetNextEntry(&entry) == B_OK) {
|
||||
if (rewind || entry == curImage) {
|
||||
// start with first entry or found current image
|
||||
if (next) {
|
||||
// start with next entry
|
||||
if (!rewind && parent.GetNextEntry(&entry) != B_OK) {
|
||||
break;
|
||||
}
|
||||
// find next image in directory
|
||||
do {
|
||||
entry_ref ref;
|
||||
if (entry.GetRef(&ref) == B_OK && IsImage(&ref)) {
|
||||
*image = entry;
|
||||
return true;
|
||||
}
|
||||
} while (parent.GetNextEntry(&entry) == B_OK);
|
||||
while (parent.GetNextRef(&entry) == B_OK) {
|
||||
if (entry != fCurrentRef) {
|
||||
entries.AddItem(new entry_ref(entry));
|
||||
} else {
|
||||
// find previous image in directory
|
||||
for (int32 i = entries.CountItems() - 1; i >= 0; i --) {
|
||||
BEntry* entry = (BEntry*)entries.ItemAt(i);
|
||||
entry_ref ref;
|
||||
if (entry->GetRef(&ref) == B_OK && IsImage(&ref)) {
|
||||
*image = *entry;
|
||||
FreeEntries(&entries);
|
||||
return true;
|
||||
}
|
||||
// insert current ref, so we can find it easily after sorting
|
||||
entries.AddItem(&fCurrentRef);
|
||||
}
|
||||
}
|
||||
|
||||
entries.SortItems(CompareEntries);
|
||||
|
||||
cur = entries.IndexOf(&fCurrentRef);
|
||||
ASSERT(cur >= 0);
|
||||
|
||||
// remove it so FreeEntries() does not delete it
|
||||
entries.RemoveItem(&fCurrentRef);
|
||||
|
||||
if (next) {
|
||||
// find the next image in the list
|
||||
if (rewind) cur = 0; // start with first
|
||||
for (; (ref = (entry_ref*)entries.ItemAt(cur)) != NULL; cur ++) {
|
||||
if (IsImage(ref)) {
|
||||
found = true;
|
||||
*image = (const entry_ref)*ref;
|
||||
break;
|
||||
}
|
||||
if (!next) {
|
||||
// record entries if we search for previous file
|
||||
entries.AddItem(new BEntry(entry));
|
||||
}
|
||||
} else {
|
||||
// find the previous image in the list
|
||||
cur --;
|
||||
for (; cur >= 0; cur --) {
|
||||
ref = (entry_ref*)entries.ItemAt(cur);
|
||||
if (IsImage(ref)) {
|
||||
found = true;
|
||||
*image = (const entry_ref)*ref;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FreeEntries(&entries);
|
||||
return false;
|
||||
return found;
|
||||
}
|
||||
|
||||
bool
|
||||
ShowImageView::ShowNextImage(bool next, bool rewind)
|
||||
{
|
||||
BEntry image;
|
||||
entry_ref ref;
|
||||
|
||||
if (FindNextImage(&image, next, rewind) && image.GetRef(&ref) == B_OK) {
|
||||
if (FindNextImage(&ref, next, rewind)) {
|
||||
SetImage(&ref);
|
||||
return true;
|
||||
}
|
||||
@ -1018,6 +1053,28 @@ ShowImageView::FirstFile()
|
||||
return ShowNextImage(true, true);
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::SetZoom(float zoom)
|
||||
{
|
||||
fZoom = zoom;
|
||||
FixupScrollBars();
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::ZoomIn()
|
||||
{
|
||||
SetZoom(fZoom + 0.25);
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::ZoomOut()
|
||||
{
|
||||
if (fZoom > 0.25) {
|
||||
SetZoom(fZoom - 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::SetSlideShowDelay(float seconds)
|
||||
{
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
void SetShowCaption(bool show);
|
||||
void ResizeToViewBounds(bool resize);
|
||||
BBitmap *GetBitmap();
|
||||
void GetName(BString *name);
|
||||
void GetPath(BString *name);
|
||||
void FlushToLeftTop();
|
||||
|
||||
@ -78,6 +79,9 @@ public:
|
||||
void SetSlideShowDelay(float seconds);
|
||||
void StartSlideShow();
|
||||
void StopSlideShow();
|
||||
void SetZoom(float zoom);
|
||||
void ZoomIn();
|
||||
void ZoomOut();
|
||||
|
||||
// Image manipulation
|
||||
void Rotate(int degree); // 90 and 270 only
|
||||
@ -107,8 +111,9 @@ private:
|
||||
BPoint ViewToImage(BPoint p) const;
|
||||
BRect ImageToView(BRect r) const;
|
||||
bool IsImage(const entry_ref* pref);
|
||||
static int CompareEntries(const void* a, const void* b);
|
||||
void FreeEntries(BList* entries);
|
||||
bool FindNextImage(BEntry* entry, bool next, bool rewind);
|
||||
bool FindNextImage(entry_ref* ref, bool next, bool rewind);
|
||||
bool ShowNextImage(bool next, bool rewind);
|
||||
bool FirstFile();
|
||||
void ConstrainToImage(BPoint &point);
|
||||
@ -128,6 +133,7 @@ private:
|
||||
int32 fDocumentIndex;
|
||||
int32 fDocumentCount;
|
||||
BBitmap *fpBitmap;
|
||||
float fZoom;
|
||||
bool fResizeToViewBounds;
|
||||
float fLeft; // the origin of the image in the view
|
||||
float fTop;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <SupportDefs.h>
|
||||
#include <Screen.h>
|
||||
#include <Roster.h>
|
||||
#include <PrintJob.h>
|
||||
|
||||
#include "ShowImageConstants.h"
|
||||
#include "ShowImageWindow.h"
|
||||
@ -56,6 +57,7 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
|
||||
fpSavePanel = NULL;
|
||||
fFullScreen = false;
|
||||
fShowCaption = true; // XXX what is best for default?
|
||||
fPrintSettings = NULL;
|
||||
|
||||
// create menu bar
|
||||
fpBar = new BMenuBar(BRect(0, 0, Bounds().right, 20), "menu_bar");
|
||||
@ -104,13 +106,13 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
|
||||
SetSizeLimits(250, 100000, 100, 100000);
|
||||
|
||||
// finish creating window
|
||||
UpdateTitle();
|
||||
|
||||
fpImageView->SetImage(pref);
|
||||
|
||||
if (InitCheck() == B_OK) {
|
||||
UpdateTitle();
|
||||
|
||||
SetPulseRate(100000); // every 1/10 second; ShowImageView needs it for marching ants
|
||||
|
||||
if (InitCheck() == B_OK) {
|
||||
fpImageView->FlushToLeftTop();
|
||||
WindowRedimension(fpImageView->GetBitmap());
|
||||
Show();
|
||||
@ -182,14 +184,17 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
||||
fpOpenMenu->Superitem()->SetTarget(be_app);
|
||||
fpOpenMenu->Superitem()->SetShortcut('O', 0);
|
||||
pmenu->AddSeparatorItem();
|
||||
BMenu *pmenuSaveAs = new BMenu("Save As...", B_ITEMS_IN_COLUMN);
|
||||
BMenu *pmenuSaveAs = new BMenu("Save As" B_UTF8_ELLIPSIS, B_ITEMS_IN_COLUMN);
|
||||
BTranslationUtils::AddTranslationItems(pmenuSaveAs, B_TRANSLATOR_BITMAP);
|
||||
// Fill Save As submenu with all types that can be converted
|
||||
// to from the Be bitmap image format
|
||||
pmenu->AddItem(pmenuSaveAs);
|
||||
AddItemMenu(pmenu, "Close", MSG_CLOSE, 'W', 0, 'W', true);
|
||||
pmenu->AddSeparatorItem();
|
||||
AddItemMenu(pmenu, "About ShowImage...", B_ABOUT_REQUESTED, 0, 0, 'A', true);
|
||||
AddItemMenu(pmenu, "Page Setup" B_UTF8_ELLIPSIS, MSG_PAGE_SETUP, 0, 0, 'W', true);
|
||||
AddItemMenu(pmenu, "Print" B_UTF8_ELLIPSIS, MSG_PREPARE_PRINT, 0, 0, 'W', true);
|
||||
pmenu->AddSeparatorItem();
|
||||
AddItemMenu(pmenu, "About ShowImage" B_UTF8_ELLIPSIS, B_ABOUT_REQUESTED, 0, 0, 'A', true);
|
||||
pmenu->AddSeparatorItem();
|
||||
AddItemMenu(pmenu, "Quit", B_QUIT_REQUESTED, 'Q', 0, 'A', true);
|
||||
pbar->AddItem(pmenu);
|
||||
@ -250,6 +255,10 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
||||
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);
|
||||
@ -406,15 +415,21 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
||||
// Remove all page numbers
|
||||
delete fpGoToPageMenu->RemoveItem(0L);
|
||||
|
||||
for (int32 i = 1; i > 0 && i <= pages; i++) {
|
||||
for (int32 i = 1; i <= pages; i++) {
|
||||
// Fill Go To page submenu with an entry for each page
|
||||
BMessage *pgomsg;
|
||||
char shortcut = 0;
|
||||
pgomsg = new BMessage(MSG_GOTO_PAGE);
|
||||
pgomsg->AddInt32("page", i);
|
||||
BString strCaption;
|
||||
strCaption << i;
|
||||
BMenuItem *pitem;
|
||||
pitem = new BMenuItem(strCaption.String(), pgomsg, 0);
|
||||
if (i < 10) {
|
||||
shortcut = '0' + i;
|
||||
} else if (i == 10) {
|
||||
shortcut = '0';
|
||||
}
|
||||
pitem = new BMenuItem(strCaption.String(), pgomsg, shortcut);
|
||||
if (curPage == i)
|
||||
pitem->SetMarked(true);
|
||||
fpGoToPageMenu->AddItem(pitem);
|
||||
@ -503,6 +518,9 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
||||
bool resize;
|
||||
resize = ToggleMenuItem(pmsg->what);
|
||||
fpImageView->ResizeToViewBounds(resize);
|
||||
EnableMenuItem(MSG_ORIGINAL_SIZE, !resize);
|
||||
EnableMenuItem(MSG_ZOOM_IN, !resize);
|
||||
EnableMenuItem(MSG_ZOOM_OUT, !resize);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -558,6 +576,26 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
||||
UpdateRecentDocumentsMenu();
|
||||
break;
|
||||
|
||||
case MSG_PAGE_SETUP:
|
||||
PageSetup();
|
||||
break;
|
||||
case MSG_PREPARE_PRINT:
|
||||
PrepareForPrint();
|
||||
break;
|
||||
case MSG_PRINT:
|
||||
Print(pmsg);
|
||||
break;
|
||||
|
||||
case MSG_ZOOM_IN:
|
||||
fpImageView->ZoomIn();
|
||||
break;
|
||||
case MSG_ZOOM_OUT:
|
||||
fpImageView->ZoomOut();
|
||||
break;
|
||||
case MSG_ORIGINAL_SIZE:
|
||||
fpImageView->SetZoom(1.0);
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(pmsg);
|
||||
break;
|
||||
@ -670,6 +708,106 @@ ShowImageWindow::ToggleFullScreen()
|
||||
ResizeTo(frame.Width(), frame.Height());
|
||||
}
|
||||
|
||||
bool
|
||||
ShowImageWindow::PageSetup()
|
||||
{
|
||||
status_t st;
|
||||
BString name;
|
||||
fpImageView->GetName(&name);
|
||||
BPrintJob printJob(name.String());
|
||||
if (fPrintSettings != NULL) {
|
||||
printJob.SetSettings(new BMessage(*fPrintSettings));
|
||||
}
|
||||
st = printJob.ConfigPage();
|
||||
if (st == B_OK) {
|
||||
delete fPrintSettings;
|
||||
fPrintSettings = printJob.Settings();
|
||||
}
|
||||
return st == B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageWindow::PrepareForPrint()
|
||||
{
|
||||
if (fPrintSettings == NULL && !PageSetup()) {
|
||||
return;
|
||||
}
|
||||
|
||||
fPrintOptions.SetBounds(fpImageView->GetBitmap()->Bounds());
|
||||
fPrintOptions.SetWidth(fpImageView->GetBitmap()->Bounds().Width()+1);
|
||||
|
||||
new PrintOptionsWindow(BPoint(Frame().left+30, Frame().top+50), &fPrintOptions, this);
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageWindow::Print(BMessage *msg)
|
||||
{
|
||||
status_t st;
|
||||
if (msg->FindInt32("status", &st) != B_OK || st != B_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
BString name;
|
||||
fPrintOptions.SetBounds(fpImageView->GetBitmap()->Bounds());
|
||||
fpImageView->GetName(&name);
|
||||
BPrintJob printJob(name.String());
|
||||
printJob.SetSettings(new BMessage(*fPrintSettings));
|
||||
if (printJob.ConfigJob() == B_OK) {
|
||||
int32 firstPage;
|
||||
int32 lastPage;
|
||||
BRect printableRect = printJob.PrintableRect();
|
||||
float width, imageWidth, imageHeight, w1, w2;
|
||||
BBitmap* bitmap;
|
||||
|
||||
// first/lastPage is unused for now
|
||||
firstPage = printJob.FirstPage();
|
||||
lastPage = printJob.LastPage();
|
||||
if (firstPage < 1) {
|
||||
firstPage = 1;
|
||||
}
|
||||
if (lastPage < firstPage) {
|
||||
lastPage = firstPage;
|
||||
}
|
||||
|
||||
bitmap = fpImageView->GetBitmap();
|
||||
imageWidth = bitmap->Bounds().Width() + 1.0;
|
||||
imageHeight = bitmap->Bounds().Height() + 1.0;
|
||||
|
||||
switch (fPrintOptions.Option()) {
|
||||
case PrintOptions::kFitToPage:
|
||||
w1 = printableRect.Width()+1;
|
||||
w2 = imageWidth * (printableRect.Height() + 1) / imageHeight;
|
||||
if (w2 < w1) {
|
||||
width = w2;
|
||||
} else {
|
||||
width = w1;
|
||||
}
|
||||
break;
|
||||
case PrintOptions::kZoomFactor:
|
||||
width = imageWidth * fPrintOptions.ZoomFactor();
|
||||
break;
|
||||
case PrintOptions::kDPI:
|
||||
width = imageWidth * 72.0 / fPrintOptions.DPI();
|
||||
break;
|
||||
case PrintOptions::kWidth:
|
||||
case PrintOptions::kHeight:
|
||||
width = fPrintOptions.Width();
|
||||
break;
|
||||
default:
|
||||
// keep compiler silent; should not reach here
|
||||
width = imageWidth;
|
||||
}
|
||||
|
||||
// XXX: eventually print large images on several pages
|
||||
printJob.BeginJob();
|
||||
fpImageView->SetScale(width / imageWidth);
|
||||
printJob.DrawView(fpImageView, bitmap->Bounds(), BPoint(printableRect.left, printableRect.top));
|
||||
fpImageView->SetScale(1.0);
|
||||
printJob.SpoolPage();
|
||||
printJob.CommitJob();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ShowImageWindow::QuitRequested()
|
||||
{
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <TranslationDefs.h>
|
||||
#include <String.h>
|
||||
|
||||
#include "PrintOptionsWindow.h"
|
||||
|
||||
class ShowImageView;
|
||||
class ShowImageStatusView;
|
||||
|
||||
@ -77,6 +79,9 @@ private:
|
||||
bool CanQuit();
|
||||
// returns true if the window can be closed safely, false if not
|
||||
void ToggleFullScreen();
|
||||
bool PageSetup();
|
||||
void PrepareForPrint();
|
||||
void Print(BMessage *msg);
|
||||
|
||||
BFilePanel *fpSavePanel;
|
||||
BMenuBar *fpBar;
|
||||
@ -88,6 +93,8 @@ private:
|
||||
bool fFullScreen;
|
||||
BRect fWindowFrame;
|
||||
bool fShowCaption;
|
||||
BMessage *fPrintSettings;
|
||||
PrintOptions fPrintOptions;
|
||||
};
|
||||
|
||||
#endif /* _ShowImageWindow_h */
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user