Integrated "resize" feature from Zetas version of ShowImage, however used our bilinear scaler instead of Zetas implementation and made ResizerWindow font sensitive and removed the radio buttons with predefined sizes. Kudos to Bernd Korz for providing the ShowImage Zeta source code under MIT license.

Moved menu item "As Desktop Background" into "Image" menu from "View" menu. 
Removed unused metod ShowImageWindow::Zoom(...).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19540 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Pfeiffer 2006-12-17 15:18:32 +00:00
parent 35346d06a7
commit d9f6762d46
9 changed files with 501 additions and 68 deletions

View File

@ -1,30 +1,14 @@
/*****************************************************************************/
// Filter
// Written by Michael Pfeiffer
//
// Filter.cpp
//
//
// Copyright (c) 2003-2005 Haiku 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.
/*****************************************************************************/
/*
* Copyright 2003-2006, Haiku.
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
* Copyright 2006 Bernd Korz. All Rights Reserved
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Pfeiffer, laplace@haiku-os.org
* yellowTAB GmbH
* Bernd Korz
*/
#include <scheduler.h>
#include <Debug.h>
@ -275,13 +259,14 @@ Scaler::~Scaler()
{
if (GetDestImage() != fScaledImage) {
delete fScaledImage;
fScaledImage = NULL;
}
}
BBitmap*
Scaler::CreateDestImage(BBitmap* srcImage)
{
if (srcImage == NULL || srcImage->ColorSpace() != B_RGB32 && srcImage->ColorSpace() !=B_RGBA32) return NULL;
if (srcImage == NULL || srcImage->ColorSpace() != B_RGB32 && srcImage->ColorSpace() != B_RGBA32) return NULL;
BRect dest(0, 0, fRect.IntegerWidth(), fRect.IntegerHeight());
BBitmap* destImage = new BBitmap(dest, fDither ? B_CMAP8 : srcImage->ColorSpace());
@ -291,9 +276,10 @@ Scaler::CreateDestImage(BBitmap* srcImage)
return NULL;
}
if (fDither) {
BRect dest(0, 0, fRect.IntegerWidth(), fRect.IntegerHeight());
fScaledImage = new BBitmap(dest, srcImage->ColorSpace());
if (fDither)
{
BRect dest_rect(0, 0, fRect.IntegerWidth(), fRect.IntegerHeight());
fScaledImage = new BBitmap(dest_rect, srcImage->ColorSpace());
if (!IsBitmapValid(fScaledImage)) {
delete destImage;
delete fScaledImage;
@ -404,6 +390,9 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
destData[2] = static_cast<uchar>(
(a[2] * a0 + b[2] * a1) * alpha0 +
(c[2] * a0 + d[2] * a1) * alpha1);
destData[3] = static_cast<uchar>(
(a[3] * a0 + b[3] * a1) * alpha0 +
(c[3] * a0 + d[3] * a1) * alpha1);
}
// right column
@ -413,6 +402,7 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
destData[0] = static_cast<uchar>(a[0] * alpha0 + c[0] * alpha1);
destData[1] = static_cast<uchar>(a[1] * alpha0 + c[1] * alpha1);
destData[2] = static_cast<uchar>(a[2] * alpha0 + c[2] * alpha1);
destData[3] = static_cast<uchar>(a[3] * alpha0 + c[3] * alpha1);
} else {
float a0, a1;
const uchar *a, *b;
@ -426,6 +416,7 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
destData[0] = static_cast<uchar>(a[0] * a0 + b[0] * a1);
destData[1] = static_cast<uchar>(a[1] * a0 + b[1] * a1);
destData[2] = static_cast<uchar>(a[2] * a0 + b[2] * a1);
destData[3] = static_cast<uchar>(a[3] * a0 + b[3] * a1);
}
// bottom, right pixel
@ -434,6 +425,7 @@ Scaler::ScaleBilinear(intType fromRow, int32 toRow)
destData[0] = a[0];
destData[1] = a[1];
destData[2] = a[2];
destData[3] = a[3];
}
}
@ -538,6 +530,7 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
destData[0] = I4(0);
destData[1] = I4(1);
destData[2] = I4(2);
destData[3] = I4(3);
}
// right column
@ -547,6 +540,7 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
destData[0] = V2(0);
destData[1] = V2(1);
destData[2] = V2(2);
destData[3] = V2(3);
} else {
fixed_point a0, a1;
const uchar *a, *b;
@ -560,6 +554,7 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
destData[0] = H2(0);
destData[1] = H2(1);
destData[2] = H2(2);
destData[3] = H2(3);
}
// bottom, right pixel
@ -568,6 +563,7 @@ Scaler::ScaleBilinearFP(intType fromRow, int32 toRow)
destData[0] = a[0];
destData[1] = a[1];
destData[2] = a[2];
destData[3] = a[3];
}
}
@ -915,8 +911,9 @@ void
Scaler::Completed()
{
if (GetDestImage() != fScaledImage) {
delete fScaledImage; fScaledImage = NULL;
delete fScaledImage;
}
fScaledImage = NULL;
}
// Implementation of ImageProcessor
@ -927,7 +924,7 @@ ImageProcessor::ImageProcessor(enum operation op, BBitmap* image, BMessenger lis
}
BBitmap*
ImageProcessor::CreateDestImage(BBitmap* srcImage)
ImageProcessor::CreateDestImage(BBitmap* /* srcImage */)
{
color_space cs;
BBitmap* bm;

View File

@ -0,0 +1,234 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
* Copyright 2006 Bernd Korz. All Rights Reserved
* Distributed under the terms of the MIT License.
*
* Authors:
* yellowTAB GmbH
* Bernd Korz
* Michael Pfeiffer
*
* 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 <CheckBox.h>
#include <RadioButton.h>
#include <Rect.h>
#include <String.h>
#include <TextControl.h>
#include <stdlib.h>
#include "ResizerWindow.h"
#include "ShowImageConstants.h"
static const char* kWidthLabel = "Width:";
static const char* kHeightLabel = "Height:";
static const char* kKeepAspectRatioLabel = "Keep Aspect Ratio";
static const char* kApplyLabel = "Apply";
static const float kLineDistance = 5;
static const float kHorizontalIndent = 10;
static const float kVerticalIndent = 10;
ResizerWindow::ResizerWindow(BMessenger target, float width, float height)
: BWindow(BRect(100, 100, 300, 300), "Resize", B_FLOATING_WINDOW, B_NOT_ZOOMABLE | B_NOT_RESIZABLE)
, fRatio(width / height)
, fTarget(target)
{
BView* back_view = new BBox(Bounds(), "", B_FOLLOW_ALL);
AddChild(back_view);
const float widthLabelWidth = back_view->StringWidth(kWidthLabel);
const float heightLabelWidth = back_view->StringWidth(kHeightLabel);
const float column2 = max_c(widthLabelWidth, heightLabelWidth);
const float textControlWidth = column2 + back_view->StringWidth("999999");
const float keepAspectRatioLabelWidth = back_view->StringWidth(kKeepAspectRatioLabel);
const float width = 2 * kHorizontalIndent + max_c(textControlWidth, keepAspectRatioLabelWidth);
ResizeTo(width+1, Bounds().Height()+1);
const float top = kVerticalIndent;
const float left = kHorizontalIndent;
BRect rect(left, top, width - kHorizontalIndent, top + 10);
BString widthValue;
widthValue << (int)width;
fWidth = new BTextControl(rect, "width", kWidthLabel, widthValue.String(), NULL);
fWidth->SetModificationMessage(new BMessage(kWidthModifiedMsg));
AddControl(back_view, fWidth, column2, rect);
BString heightValue;
heightValue << (int)height;
fHeight = new BTextControl(rect, "height", kHeightLabel, heightValue.String(), NULL);
fHeight->SetModificationMessage(new BMessage(kHeightModifiedMsg));
AddControl(back_view, fHeight, column2, rect);
fAspectRatio = new BCheckBox(rect, "Ratio", kKeepAspectRatioLabel, new BMessage(kWidthModifiedMsg));
fAspectRatio->SetValue(B_CONTROL_ON);
AddControl(back_view, fAspectRatio, column2, rect);
AddSeparatorLine(back_view, rect);
fApply = new BButton(rect, "apply", kApplyLabel, new BMessage(kApplyMsg));
fApply->MakeDefault(true);
AddControl(back_view, fApply, column2, rect);
LeftAlign(fApply);
fWidth->MakeFocus();
ResizeTo(width, rect.top);
}
void
ResizerWindow::AddControl(BView* view, BControl* control, float column2, BRect& rect)
{
float width, height;
view->AddChild(control);
control->GetPreferredSize(&width, &height);
if (dynamic_cast<BButton*>(control) != NULL) {
control->ResizeTo(width, height);
} else {
control->ResizeTo(control->Bounds().Width(), height);
}
float top = control->Frame().bottom + kLineDistance;
rect.OffsetTo(rect.left, top);
if (dynamic_cast<BTextControl*>(control) != NULL) {
((BTextControl*)control)->SetDivider(column2);
}
}
void
ResizerWindow::AddSeparatorLine(BView* view, BRect& rect)
{
const float lineWidth = 3;
BRect line(Bounds());
line.left += 3;
line.right -= 3;
line.top = rect.top;
line.bottom = line.top + lineWidth - 1;
BBox* separatorLine = new BBox(line, "", B_FOLLOW_LEFT_RIGHT, B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
view->AddChild(separatorLine);
rect.OffsetBy(0, kLineDistance + lineWidth);
}
void
ResizerWindow::LeftAlign(BControl* control)
{
BRect frame = control->Frame();
float left = Bounds().Width() - frame.Width() - kHorizontalIndent;
control->MoveTo(left, frame.top);
}
void
ResizerWindow::MessageReceived(BMessage* message)
{
switch (message->what)
{
// public actions
case kActivateMsg:
Activate();
break;
case kUpdateMsg:
{
// update aspect ratio, width and height
float width, height;
if (message->FindFloat("width", &width) == B_OK &&
message->FindFloat("height", &height) == B_OK) {
fRatio = width / height;
BString widthText, heightText;
widthText << (int)width;
heightText << (int)height;
// here the statement order is important:
// in case keep aspect ratio is enabled,
// the width should determine the height
fHeight->SetText(heightText.String());
fWidth->SetText(widthText.String());
}
break;
}
// private actions
case kResolutionMsg:
{ fAspectRatio->SetValue(B_CONTROL_OFF);
BString width, height;
width << message->FindInt32("w");
height << message->FindInt32("h");
fWidth->SetText(width.String());
fHeight->SetText(height.String());
break;
}
case kWidthModifiedMsg:
if (fAspectRatio->Value() == B_CONTROL_ON)
{
int w = atoi(fWidth->Text());
int h = (int)(w / fRatio);
BString height;
height << h;
BMessage* msg = new BMessage(*fHeight->ModificationMessage());
fHeight->SetModificationMessage(NULL);
fHeight->SetText(height.String());
fHeight->SetModificationMessage(msg);
}
break;
case kHeightModifiedMsg:
if (fAspectRatio->Value() == B_CONTROL_ON)
{
int h = atoi(fHeight->Text());
int w = (int)(h * fRatio);
BString width;
width << w;
BMessage* msg = new BMessage(*fWidth->ModificationMessage());
fWidth->SetModificationMessage(NULL);
fWidth->SetText(width.String());
fWidth->SetModificationMessage(msg);
}
break;
case kApplyMsg:
{
BMessage resizeRequest(MSG_RESIZE);
resizeRequest.AddInt32("h", atoi(fHeight->Text()));
resizeRequest.AddInt32("w", atoi(fWidth->Text()));
fTarget.SendMessage(&resizeRequest);
PostMessage(B_QUIT_REQUESTED);
break;
}
default:
BWindow::MessageReceived(message);
}
}
ResizerWindow::~ResizerWindow()
{
}
bool
ResizerWindow::QuitRequested()
{
fTarget.SendMessage(MSG_RESIZER_WINDOW_QUITED);
return true;
}

View File

@ -0,0 +1,78 @@
/*
* Copyright 2006, Haiku, Inc. All Rights Reserved.
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
* Copyright 2006 Bernd Korz. All Rights Reserved
* Distributed under the terms of the MIT License.
*
* Authors:
* yellowTAB GmbH
* Bernd Korz
* Michael Pfeiffer
*
* 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 _resizer_window_h
#define _resizer_window_h
#include <Window.h>
#include <View.h>
class BTextControl;
class BCheckBox;
class ResizerWindow : public BWindow
{
public:
ResizerWindow(BMessenger target, float width, float height );
virtual void MessageReceived(BMessage* msg);
virtual bool QuitRequested();
virtual ~ResizerWindow();
// the public message command constants ('what')
enum {
kActivateMsg = 'RSRa',
// activates the window
kUpdateMsg,
// provides the new size of the image in two float fields "width" and "height"
};
private:
enum {
kResolutionMsg = 'Rszr',
kWidthModifiedMsg,
kHeightModifiedMsg,
kApplyMsg,
};
void AddControl(BView* parent, BControl* control, float column2, BRect& rect);
void AddSeparatorLine(BView* parent, BRect& rect);
void LeftAlign(BControl* control);
BTextControl* fWidth;
BTextControl* fHeight;
BCheckBox* fAspectRatio;
BButton* fApply;
float fRatio;
BMessenger fTarget;
};
#endif

View File

@ -57,5 +57,8 @@ const uint32 MSG_ORIGINAL_SIZE = 'mOSZ';
const uint32 MSG_INVALIDATE = 'mIVD';
const uint32 MSG_SCALE_BILINEAR = 'mSBL';
const uint32 MSG_DESKTOP_BACKGROUND = 'mDBG';
const uint32 MSG_OPEN_RESIZER_WINDOW = 'mORS';
const uint32 MSG_RESIZER_WINDOW_QUITED = 'mRSQ';
const uint32 MSG_RESIZE = 'mRSZ';
#endif // SHOW_IMAGE_CONSTANTS_H

View File

@ -28,6 +28,8 @@
#include "ShowImageUndo.h"
#include <stdio.h>
ShowImageUndo::ShowImageUndo()
{
fWindow = NULL;
@ -62,10 +64,13 @@ void
ShowImageUndo::SendUndoStateMessage(bool bCanUndo)
{
if (fWindow) {
if (!fWindow->IsLocked()) {
fprintf(stderr, "ShowImageUndo::SendUndoStateMessage: window must be locked!");
exit(-1);
}
BMessage msg(MSG_UNDO_STATE);
msg.AddBool("can_undo", bCanUndo);
BMessenger msgr(fWindow);
msgr.SendMessage(&msg);
fWindow->PostMessage(&msg);
}
}

View File

@ -1,11 +1,15 @@
/*
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
* Copyright 2006 Bernd Korz. All Rights Reserved
* Distributed under the terms of the MIT License.
*
* Authors:
* Fernando Francisco de Oliveira
* Michael Wilber
* Michael Pfeiffer
* yellowTAB GmbH
* Bernd Korz
*/
@ -188,7 +192,7 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
fScaleBilinear = false;
fScaler = NULL;
#if DELAYED_SCALING
fScalingCountDown = 10;
fScalingCountDown = SCALING_DELAY_TIME;
#endif
if (settings->Lock()) {
@ -303,9 +307,11 @@ ShowImageView::Pulse()
#if DELAYED_SCALING
if (fBitmap && (fScaleBilinear || fDither) && fScalingCountDown > 0) {
fScalingCountDown --;
if (fScalingCountDown == 0) {
if (fScalingCountDown == 1) {
fScalingCountDown = 0;
GetScaler(AlignBitmap());
} else {
fScalingCountDown --;
}
}
#endif
@ -383,7 +389,7 @@ ShowImageView::DeleteScaler()
fScaler = NULL;
}
#if DELAYED_SCALING
fScalingCountDown = 3; // delay for 3/10 seconds
fScalingCountDown = SCALING_DELAY_TIME;
#endif
}
@ -1634,7 +1640,7 @@ ShowImageView::ShowPopUpMenu(BPoint screen)
ShowImageWindow* showImage = dynamic_cast<ShowImageWindow*>(Window());
if (showImage)
showImage->BuildViewMenu(menu);
showImage->BuildContextMenu(menu);
screen -= BPoint(10, 10);
menu->Go(screen, true, false, true);
@ -2427,6 +2433,31 @@ ShowImageView::Invert()
}
}
void
ShowImageView::ResizeImage(int w, int h)
{
if (fBitmap == NULL || w < 1 || h < 1)
return;
Scaler scaler(fBitmap, BRect(0, 0, w-1, h-1), BMessenger(), 0, false);
scaler.Start(false);
BBitmap* scaled = scaler.DetachBitmap();
if (scaled == NULL) {
// operation failed
return;
}
// remove selection
SetHasSelection(false);
fUndo.Clear();
DeleteBitmap();
fBitmap = scaled;
BMessenger msgr(Window());
msgr.SendMessage(MSG_MODIFIED);
Notify(NULL);
}
void
ShowImageView::SetIcon(bool clear, icon_size which)

View File

@ -1,11 +1,15 @@
/*
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
* Copyright 2006 Bernd Korz. All Rights Reserved
* Distributed under the terms of the MIT License.
*
* Authors:
* Fernando Francisco de Oliveira
* Michael Wilber
* Michael Pfeiffer
* yellowTAB GmbH
* Bernd Korz
*/
#ifndef SHOW_IMAGE_VIEW_H
#define SHOW_IMAGE_VIEW_H
@ -24,6 +28,8 @@
// delay scaling operation, so that a sequence of zoom in/out operations works smoother
#define DELAYED_SCALING 1
// the delay time in 1/10 seconds
#define SCALING_DELAY_TIME 3
// width of the black border stroked arround the bitmap
#define PEN_SIZE 1.0f
@ -100,6 +106,7 @@ class ShowImageView : public BView {
void Rotate(int degree); // 90 and 270 only
void Flip(bool vertical);
void Invert();
void ResizeImage(int w, int h);
void SetIcon(bool clear);

View File

@ -1,16 +1,21 @@
/*
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
* Copyright 2004-2005 yellowTAB GmbH. All Rights Reserverd.
* Copyright 2006 Bernd Korz. All Rights Reserved
* Distributed under the terms of the MIT License.
*
* Authors:
* Fernando Francisco de Oliveira
* Michael Wilber
* Michael Pfeiffer
* yellowTAB GmbH
* Bernd Korz
*/
#include "BackgroundImage.h"
#include "EntryMenuItem.h"
#include "ResizerWindow.h"
#include "ShowImageApp.h"
#include "ShowImageConstants.h"
#include "ShowImageStatusView.h"
@ -91,7 +96,8 @@ ShowImageWindow::ShowImageWindow(const entry_ref *ref,
fPrintSettings = NULL;
fImageView = NULL;
fSlideShowDelay = NULL;
fResizerWindowMessenger = NULL;
LoadSettings();
// create menu bar
@ -145,21 +151,7 @@ ShowImageWindow::ShowImageWindow(const entry_ref *ref,
fImageView->SetImage(ref);
fImageView->SetTrackerMessenger(trackerMessenger);
if (InitCheck() == B_OK) {
// add View menu here so it can access ShowImageView methods
BMenu* menu = new BMenu("View");
BuildViewMenu(menu);
fBar->AddItem(menu);
MarkMenuItem(fBar, MSG_DITHER_IMAGE, fImageView->GetDither());
UpdateTitle();
SetPulseRate(100000);
// every 1/10 second; ShowImageView needs it for marching ants
WindowRedimension(fImageView->GetBitmap());
fImageView->MakeFocus(true); // to receive KeyDown messages
Show();
} else {
if (InitCheck() != B_OK) {
BAlert* alert;
alert = new BAlert("ShowImage",
"Could not load image! Either the file or an image translator for it does not exist.",
@ -172,6 +164,20 @@ ShowImageWindow::ShowImageWindow(const entry_ref *ref,
return;
}
// add View menu here so it can access ShowImageView methods
BMenu* menu = new BMenu("View");
BuildViewMenu(menu, false);
fBar->AddItem(menu);
MarkMenuItem(fBar, MSG_DITHER_IMAGE, fImageView->GetDither());
UpdateTitle();
SetPulseRate(100000);
// every 1/10 second; ShowImageView needs it for marching ants
WindowRedimension(fImageView->GetBitmap());
fImageView->MakeFocus(true); // to receive KeyDown messages
Show();
// Tell application object to query the clipboard
// and tell this window if it contains interesting data or not
be_app_messenger.SendMessage(B_CLIPBOARD_CHANGED);
@ -201,9 +207,14 @@ ShowImageWindow::UpdateTitle()
SetTitle(path.String());
}
void
ShowImageWindow::BuildContextMenu(BMenu *menu)
{
BuildViewMenu(menu, true);
}
void
ShowImageWindow::BuildViewMenu(BMenu *menu)
ShowImageWindow::BuildViewMenu(BMenu *menu, bool popupMenu)
{
AddItemMenu(menu, "Slide Show", MSG_SLIDE_SHOW, 0, 0, 'W', true);
MarkMenuItem(menu, MSG_SLIDE_SHOW, fImageView->SlideShowStarted());
@ -265,10 +276,11 @@ ShowImageWindow::BuildViewMenu(BMenu *menu)
EnableMenuItem(menu, MSG_ZOOM_IN, enabled);
EnableMenuItem(menu, MSG_ZOOM_OUT, enabled);
menu->AddSeparatorItem();
if (popupMenu) {
menu->AddSeparatorItem();
AddItemMenu(menu, "As Desktop Background", MSG_DESKTOP_BACKGROUND, 0, 0, 'W',
true);
AddItemMenu(menu, "As Desktop Background", MSG_DESKTOP_BACKGROUND, 0, 0, 'W', true);
}
}
@ -332,7 +344,11 @@ ShowImageWindow::AddMenus(BMenuBar *bar)
AddItemMenu(menu, "Flip Top To Bottom", MSG_FLIP_TOP_TO_BOTTOM, 0, 0, 'W', true);
menu->AddSeparatorItem();
AddItemMenu(menu, "Invert", MSG_INVERT, 0, 0, 'W', true);
menu->AddSeparatorItem();
AddItemMenu(menu, "Resize " B_UTF8_ELLIPSIS, MSG_OPEN_RESIZER_WINDOW, 0, 0, 'W', true);
bar->AddItem(menu);
menu->AddSeparatorItem();
AddItemMenu(menu, "As Desktop Background", MSG_DESKTOP_BACKGROUND, 0, 0, 'W', true);
}
@ -576,10 +592,12 @@ ShowImageWindow::MessageReceived(BMessage *message)
EnableMenuItem(fBar, MSG_INVERT, (colors != B_CMAP8));
BString status;
bool messageProvidesSize = false;
int32 width, height;
if (message->FindInt32("width", &width) >= B_OK
&& message->FindInt32("height", &height) >= B_OK) {
status << width << "x" << height << ", ";
messageProvidesSize = true;
}
BString str;
@ -587,6 +605,10 @@ ShowImageWindow::MessageReceived(BMessage *message)
status << str;
}
if (messageProvidesSize) {
UpdateResizerWindow(width, height);
}
fStatusView->SetText(status);
UpdateTitle();
@ -796,6 +818,24 @@ ShowImageWindow::MessageReceived(BMessage *message)
fImageView->SetScaleBilinear(ToggleMenuItem(message->what));
break;
case MSG_OPEN_RESIZER_WINDOW:
if (fImageView->GetBitmap() != NULL)
{
BRect rect = fImageView->GetBitmap()->Bounds();
OpenResizerWindow(rect.Width(), rect.Height());
}
break;
case MSG_RESIZE:
{
int w = message->FindInt32("w");
int h = message->FindInt32("h");
fImageView->ResizeImage(w, h);
break;
}
case MSG_RESIZER_WINDOW_QUITED:
fResizerWindowMessenger = NULL;
break;
case MSG_DESKTOP_BACKGROUND:
{
BPath path;
@ -1098,7 +1138,43 @@ ShowImageWindow::Print(BMessage *msg)
}
}
void
ShowImageWindow::OpenResizerWindow(float width, float height)
{
if (fResizerWindowMessenger == NULL) {
// open window if it is not already opened
BWindow* window = new ResizerWindow(this, width, height);
fResizerWindowMessenger = new BMessenger(window);
window->Show();
} else
fResizerWindowMessenger->SendMessage(ResizerWindow::kActivateMsg);
}
void
ShowImageWindow::UpdateResizerWindow(float width, float height)
{
if (fResizerWindowMessenger == NULL) {
// window not opened
return;
}
BMessage updateMsg(ResizerWindow::kUpdateMsg);
updateMsg.AddFloat("width", width);
updateMsg.AddFloat("height", height);
fResizerWindowMessenger->SendMessage(&updateMsg);
}
void
ShowImageWindow::CloseResizerWindow()
{
if (fResizerWindowMessenger == NULL) {
// window not opened
return;
}
fResizerWindowMessenger->SendMessage(B_QUIT_REQUESTED);
fResizerWindowMessenger = NULL;
}
bool
ShowImageWindow::QuitRequested()
{
@ -1110,6 +1186,8 @@ ShowImageWindow::QuitRequested()
bool quit = ClosePrompt();
if (quit) {
CloseResizerWindow();
// tell the app to forget about this window
be_app->PostMessage(MSG_WINDOW_QUIT);
}
@ -1118,10 +1196,4 @@ ShowImageWindow::QuitRequested()
}
void
ShowImageWindow::Zoom(BPoint origin, float width, float height)
{
// just go into fullscreen
ToggleFullScreen();
}

View File

@ -43,17 +43,18 @@ class ShowImageWindow : public BWindow {
virtual void FrameResized(float width, float height);
virtual void MessageReceived(BMessage *message);
virtual bool QuitRequested();
virtual void Zoom(BPoint origin, float width, float height);
// virtual void Zoom(BPoint origin, float width, float height);
status_t InitCheck();
ShowImageView *GetShowImageView() const { return fImageView; }
void UpdateTitle();
void BuildViewMenu(BMenu *menu);
void AddMenus(BMenuBar *bar);
void BuildContextMenu(BMenu *menu);
void WindowRedimension(BBitmap *bitmap);
private:
void BuildViewMenu(BMenu *menu, bool popupMenu);
BMenuItem *AddItemMenu(BMenu *menu, char *caption,
uint32 command, char shortcut, uint32 modifier,
char target, bool enabled);
@ -76,6 +77,10 @@ class ShowImageWindow : public BWindow {
bool PageSetup();
void PrepareForPrint();
void Print(BMessage *msg);
void OpenResizerWindow(float width, float height);
void UpdateResizerWindow(float width, float height);
void CloseResizerWindow();
BFilePanel *fSavePanel;
BMenuBar *fBar;
@ -91,6 +96,7 @@ class ShowImageWindow : public BWindow {
bool fShowCaption;
BMessage *fPrintSettings;
PrintOptions fPrintOptions;
BMessenger* fResizerWindowMessenger;
};
#endif // SHOW_IMAGE_WINDOW_H