- added recent documents sub menu
- added resize window to image size when file is opened - added drag and drop selection - added copy selection to clipboard git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5288 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
ccd79dfdce
commit
d10d59475c
@ -128,6 +128,10 @@ ShowImageApp::MessageReceived(BMessage *pmsg)
|
|||||||
StartPulse();
|
StartPulse();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_UPDATE_RECENT_DOCUMENTS:
|
||||||
|
BroadcastToWindows(MSG_UPDATE_RECENT_DOCUMENTS);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BApplication::MessageReceived(pmsg);
|
BApplication::MessageReceived(pmsg);
|
||||||
break;
|
break;
|
||||||
@ -155,3 +159,14 @@ ShowImageApp::Open(const entry_ref *pref)
|
|||||||
{
|
{
|
||||||
new ShowImageWindow(pref);
|
new ShowImageWindow(pref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageApp::BroadcastToWindows(uint32 what)
|
||||||
|
{
|
||||||
|
const int32 n = CountWindows();
|
||||||
|
for (int32 i = 0; i < n ; i ++) {
|
||||||
|
// BMessenger checks for us if BWindow is still a valid object
|
||||||
|
BMessenger msgr(WindowAt(i));
|
||||||
|
msgr.SendMessage(what);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void StartPulse();
|
void StartPulse();
|
||||||
void Open(const entry_ref *pref);
|
void Open(const entry_ref *pref);
|
||||||
|
void BroadcastToWindows(uint32 what);
|
||||||
|
|
||||||
BFilePanel *fpOpenPanel;
|
BFilePanel *fpOpenPanel;
|
||||||
bool fbPulseStarted;
|
bool fbPulseStarted;
|
||||||
|
@ -57,6 +57,7 @@ const uint32 MSG_INVERT = 'mINV';
|
|||||||
const uint32 MSG_DIA_SHOW = 'mDIA';
|
const uint32 MSG_DIA_SHOW = 'mDIA';
|
||||||
const uint32 MSG_DIA_SHOW_DELAY = 'mDSD';
|
const uint32 MSG_DIA_SHOW_DELAY = 'mDSD';
|
||||||
const uint32 MSG_FULL_SCREEN = 'mFSC';
|
const uint32 MSG_FULL_SCREEN = 'mFSC';
|
||||||
|
const uint32 MSG_UPDATE_RECENT_DOCUMENTS = 'mURD';
|
||||||
|
|
||||||
extern const char *APP_SIG;
|
extern const char *APP_SIG;
|
||||||
|
|
||||||
|
@ -41,6 +41,10 @@
|
|||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <Directory.h>
|
#include <Directory.h>
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
#include <NodeInfo.h>
|
||||||
|
#include <Clipboard.h>
|
||||||
|
|
||||||
#include "ShowImageConstants.h"
|
#include "ShowImageConstants.h"
|
||||||
#include "ShowImageView.h"
|
#include "ShowImageView.h"
|
||||||
@ -114,10 +118,17 @@ ShowImageView::RotatePatterns()
|
|||||||
memset(fPatternRight.data, p, 8);
|
memset(fPatternRight.data, p, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::AnimateSelection(bool a)
|
||||||
|
{
|
||||||
|
fAnimateSelection = a;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::Pulse()
|
ShowImageView::Pulse()
|
||||||
{
|
{
|
||||||
if (fbHasSelection) {
|
// animate marching ants
|
||||||
|
if (fbHasSelection && fAnimateSelection && Window()->IsActive()) {
|
||||||
RotatePatterns();
|
RotatePatterns();
|
||||||
DrawSelectionBox(fSelectionRect);
|
DrawSelectionBox(fSelectionRect);
|
||||||
}
|
}
|
||||||
@ -141,10 +152,12 @@ ShowImageView::ShowImageView(BRect rect, const char *name, uint32 resizingMode,
|
|||||||
fpBitmap = NULL;
|
fpBitmap = NULL;
|
||||||
fDocumentIndex = 1;
|
fDocumentIndex = 1;
|
||||||
fDocumentCount = 1;
|
fDocumentCount = 1;
|
||||||
|
fAnimateSelection = true;
|
||||||
fbHasSelection = false;
|
fbHasSelection = false;
|
||||||
fResizeToViewBounds = false;
|
fResizeToViewBounds = false;
|
||||||
fDiaShow = false;
|
fDiaShow = false;
|
||||||
SetDiaShowDelay(3); // 3 seconds
|
SetDiaShowDelay(3); // 3 seconds
|
||||||
|
fBeginDrag = false;
|
||||||
|
|
||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
SetHighColor(kborderColor);
|
SetHighColor(kborderColor);
|
||||||
@ -181,7 +194,8 @@ ShowImageView::IsImage(const entry_ref *pref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send message to parent about new image
|
// send message to parent about new image
|
||||||
void ShowImageView::Notify(const char* status)
|
void
|
||||||
|
ShowImageView::Notify(const char* status)
|
||||||
{
|
{
|
||||||
BMessage msg(MSG_UPDATE_STATUS);
|
BMessage msg(MSG_UPDATE_STATUS);
|
||||||
if (status != NULL) {
|
if (status != NULL) {
|
||||||
@ -195,6 +209,13 @@ void ShowImageView::Notify(const char* status)
|
|||||||
Invalidate();
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::AddToRecentDocuments()
|
||||||
|
{
|
||||||
|
be_roster->AddToRecentDocuments(&fCurrentRef, APP_SIG);
|
||||||
|
be_app_messenger.SendMessage(MSG_UPDATE_RECENT_DOCUMENTS);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::SetImage(const entry_ref *pref)
|
ShowImageView::SetImage(const entry_ref *pref)
|
||||||
{
|
{
|
||||||
@ -242,6 +263,8 @@ ShowImageView::SetImage(const entry_ref *pref)
|
|||||||
else
|
else
|
||||||
fDocumentCount = 1;
|
fDocumentCount = 1;
|
||||||
|
|
||||||
|
AddToRecentDocuments();
|
||||||
|
|
||||||
Notify(info.name);
|
Notify(info.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +284,14 @@ ShowImageView::GetBitmap()
|
|||||||
return fpBitmap;
|
return fpBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::FlushToLeftTop()
|
||||||
|
{
|
||||||
|
BRect rect = AlignBitmap();
|
||||||
|
BPoint p(rect.left, rect.top);
|
||||||
|
ScrollTo(p);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::AttachedToWindow()
|
ShowImageView::AttachedToWindow()
|
||||||
{
|
{
|
||||||
@ -394,9 +425,200 @@ ShowImageView::FrameResized(float /* width */, float /* height */)
|
|||||||
void
|
void
|
||||||
ShowImageView::ConstrainToImage(BPoint &point)
|
ShowImageView::ConstrainToImage(BPoint &point)
|
||||||
{
|
{
|
||||||
point.ConstrainTo(
|
point.ConstrainTo(fpBitmap->Bounds());
|
||||||
fpBitmap->Bounds()
|
}
|
||||||
);
|
|
||||||
|
BBitmap*
|
||||||
|
ShowImageView::CopySelection(uchar alpha)
|
||||||
|
{
|
||||||
|
bool hasAlpha = alpha != 255;
|
||||||
|
|
||||||
|
if (!fbHasSelection) return NULL;
|
||||||
|
|
||||||
|
BRect rect(0, 0, fSelectionRect.IntegerWidth(), fSelectionRect.IntegerHeight());
|
||||||
|
BView view(rect, NULL, B_FOLLOW_NONE, B_WILL_DRAW);
|
||||||
|
BBitmap *bitmap = new BBitmap(rect, hasAlpha ? B_RGBA32 : fpBitmap->ColorSpace(), true);
|
||||||
|
if (bitmap == NULL) return NULL;
|
||||||
|
|
||||||
|
if (bitmap->Lock()) {
|
||||||
|
bitmap->AddChild(&view);
|
||||||
|
view.DrawBitmap(fpBitmap, fSelectionRect, rect);
|
||||||
|
if (hasAlpha) {
|
||||||
|
view.SetDrawingMode(B_OP_SUBTRACT);
|
||||||
|
view.SetHighColor(0, 0, 0, 255-alpha);
|
||||||
|
view.FillRect(rect, B_SOLID_HIGH);
|
||||||
|
}
|
||||||
|
view.Sync();
|
||||||
|
bitmap->RemoveChild(&view);
|
||||||
|
bitmap->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ShowImageView::AddSupportedTypes(BMessage* msg, BBitmap* bitmap)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
||||||
|
if (roster == NULL) return false;
|
||||||
|
|
||||||
|
BBitmapStream stream(bitmap);
|
||||||
|
|
||||||
|
translator_info *outInfo;
|
||||||
|
int32 outNumInfo;
|
||||||
|
if (roster->GetTranslators(&stream, NULL, &outInfo, &outNumInfo) == B_OK) {
|
||||||
|
for (int32 i = 0; i < outNumInfo; i++) {
|
||||||
|
const translation_format *fmts;
|
||||||
|
int32 num_fmts;
|
||||||
|
roster->GetOutputFormats(outInfo[i].translator, &fmts, &num_fmts);
|
||||||
|
for (int32 j = 0; j < num_fmts; j++) {
|
||||||
|
if (strcmp(fmts[j].MIME, "image/x-be-bitmap") != 0) {
|
||||||
|
// needed to send data in message
|
||||||
|
msg->AddString("be:types", fmts[j].MIME);
|
||||||
|
// needed to pass data via file
|
||||||
|
msg->AddString("be:filetypes", fmts[j].MIME);
|
||||||
|
msg->AddString("be:type_descriptions", fmts[j].name);
|
||||||
|
}
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream.DetachBitmap(&bitmap);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::BeginDrag(BPoint point)
|
||||||
|
{
|
||||||
|
// mouse moved?
|
||||||
|
if (!fBeginDrag) return;
|
||||||
|
point = ViewToImage(point);
|
||||||
|
if (point == fFirstPoint) return;
|
||||||
|
fBeginDrag = false;
|
||||||
|
|
||||||
|
BBitmap* bitmap = CopySelection(128);
|
||||||
|
if (bitmap == NULL) return;
|
||||||
|
|
||||||
|
SetMouseEventMask(B_POINTER_EVENTS);
|
||||||
|
BPoint leftTop(fSelectionRect.left, fSelectionRect.top);
|
||||||
|
|
||||||
|
// fill the drag message
|
||||||
|
BMessage drag(B_SIMPLE_DATA);
|
||||||
|
drag.AddInt32("be:actions", B_COPY_TARGET);
|
||||||
|
drag.AddString("be:clip_name", "Bitmap Clip");
|
||||||
|
// XXX undocumented fields
|
||||||
|
drag.AddPoint("be:_source_point", fFirstPoint);
|
||||||
|
drag.AddRect("be:_frame", fSelectionRect);
|
||||||
|
// XXX meaning unknown???
|
||||||
|
// drag.AddInt32("be:_format", e.g.: B_TGA_FORMAT);
|
||||||
|
// drag.AddInt32("be_translator", translator_id);
|
||||||
|
// drag.AddPointer("be:_bitmap_ptr, ?);
|
||||||
|
if (AddSupportedTypes(&drag, bitmap)) {
|
||||||
|
// we also support "Passing Data via File" protocol
|
||||||
|
drag.AddString("be:types", B_FILE_MIME_TYPE);
|
||||||
|
// avoid flickering of dragged bitmap caused by drawing into the window
|
||||||
|
AnimateSelection(false);
|
||||||
|
// DragMessage takes ownership of bitmap
|
||||||
|
DragMessage(&drag, bitmap, B_OP_ALPHA, fFirstPoint - leftTop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ShowImageView::OutputFormatForType(BBitmap* bitmap, const char* type, translation_format* format)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
||||||
|
if (roster == NULL) return false;
|
||||||
|
|
||||||
|
BBitmapStream stream(bitmap);
|
||||||
|
|
||||||
|
translator_info *outInfo;
|
||||||
|
int32 outNumInfo;
|
||||||
|
if (roster->GetTranslators(&stream, NULL, &outInfo, &outNumInfo) == B_OK) {
|
||||||
|
for (int32 i = 0; i < outNumInfo; i++) {
|
||||||
|
const translation_format *fmts;
|
||||||
|
int32 num_fmts;
|
||||||
|
roster->GetOutputFormats(outInfo[i].translator, &fmts, &num_fmts);
|
||||||
|
for (int32 j = 0; j < num_fmts; j++) {
|
||||||
|
if (strcmp(fmts[j].MIME, type) == 0) {
|
||||||
|
*format = fmts[j];
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream.DetachBitmap(&bitmap);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::SaveToFile(BDirectory* dir, const char* name, BBitmap* bitmap, translation_format* format)
|
||||||
|
{
|
||||||
|
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
||||||
|
BBitmapStream stream(bitmap); // destructor deletes bitmap
|
||||||
|
// write data
|
||||||
|
BFile file(dir, name, B_WRITE_ONLY);
|
||||||
|
roster->Translate(&stream, NULL, NULL, &file, format->type);
|
||||||
|
// set mime type
|
||||||
|
BNodeInfo info(&file);
|
||||||
|
if (info.InitCheck() == B_OK) {
|
||||||
|
info.SetType(format->MIME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::SendInMessage(BMessage* msg, BBitmap* bitmap, translation_format* format)
|
||||||
|
{
|
||||||
|
BMessage reply(B_MIME_DATA);
|
||||||
|
BBitmapStream stream(bitmap); // destructor deletes bitmap
|
||||||
|
BTranslatorRoster *roster = BTranslatorRoster::Default();
|
||||||
|
BMallocIO memStream;
|
||||||
|
if (roster->Translate(&stream, NULL, NULL, &memStream, format->type) == B_OK) {
|
||||||
|
reply.AddData(format->MIME, B_MIME_TYPE, memStream.Buffer(), memStream.BufferLength());
|
||||||
|
msg->SendReply(&reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::HandleDrop(BMessage* msg)
|
||||||
|
{
|
||||||
|
BMessage data(B_MIME_DATA);
|
||||||
|
entry_ref dirRef;
|
||||||
|
BString name, type;
|
||||||
|
bool saveToFile;
|
||||||
|
bool sendInMessage;
|
||||||
|
BBitmap *bitmap;
|
||||||
|
|
||||||
|
saveToFile = msg->FindString("be:filetypes", &type) == B_OK &&
|
||||||
|
msg->FindRef("directory", &dirRef) == B_OK &&
|
||||||
|
msg->FindString("name", &name) == B_OK;
|
||||||
|
|
||||||
|
sendInMessage = (!saveToFile) && msg->FindString("be:types", &type) == B_OK;
|
||||||
|
|
||||||
|
fprintf(stderr, "HandleDrop saveToFile %s, sendInMessage %s\n",
|
||||||
|
saveToFile ? "yes" : "no",
|
||||||
|
sendInMessage ? "yes" : "no");
|
||||||
|
|
||||||
|
bitmap = CopySelection();
|
||||||
|
if (bitmap == NULL) return;
|
||||||
|
|
||||||
|
translation_format format;
|
||||||
|
if (!OutputFormatForType(bitmap, type.String(), &format)) {
|
||||||
|
delete bitmap;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saveToFile) {
|
||||||
|
BDirectory dir(&dirRef);
|
||||||
|
SaveToFile(&dir, name.String(), bitmap, &format);
|
||||||
|
} else if (sendInMessage) {
|
||||||
|
SendInMessage(msg, bitmap, &format);
|
||||||
|
} else {
|
||||||
|
delete bitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -405,7 +627,8 @@ ShowImageView::MouseDown(BPoint point)
|
|||||||
point = ViewToImage(point);
|
point = ViewToImage(point);
|
||||||
|
|
||||||
if (fbHasSelection && fSelectionRect.Contains(point)) {
|
if (fbHasSelection && fSelectionRect.Contains(point)) {
|
||||||
// TODO: start drag and drop
|
// delay drag until mouse is moved
|
||||||
|
fBeginDrag = true; fFirstPoint = point;
|
||||||
} else {
|
} else {
|
||||||
// begin new selection
|
// begin new selection
|
||||||
fMakesSelection = true;
|
fMakesSelection = true;
|
||||||
@ -447,6 +670,8 @@ ShowImageView::MouseMoved(BPoint point, uint32 state, const BMessage *pmsg)
|
|||||||
{
|
{
|
||||||
if (fMakesSelection) {
|
if (fMakesSelection) {
|
||||||
UpdateSelectionRect(point, false);
|
UpdateSelectionRect(point, false);
|
||||||
|
} else {
|
||||||
|
BeginDrag(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,13 +681,20 @@ ShowImageView::MouseUp(BPoint point)
|
|||||||
if (fMakesSelection) {
|
if (fMakesSelection) {
|
||||||
UpdateSelectionRect(point, true);
|
UpdateSelectionRect(point, true);
|
||||||
fMakesSelection = false;
|
fMakesSelection = false;
|
||||||
|
} else {
|
||||||
|
BeginDrag(point);
|
||||||
}
|
}
|
||||||
|
//fBeginDrag = false;
|
||||||
|
AnimateSelection(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::MessageReceived(BMessage *pmsg)
|
ShowImageView::MessageReceived(BMessage *pmsg)
|
||||||
{
|
{
|
||||||
switch (pmsg->what) {
|
switch (pmsg->what) {
|
||||||
|
case B_COPY_TARGET:
|
||||||
|
HandleDrop(pmsg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
BView::MessageReceived(pmsg);
|
BView::MessageReceived(pmsg);
|
||||||
break;
|
break;
|
||||||
@ -521,6 +753,53 @@ ShowImageView::PageCount()
|
|||||||
return fDocumentCount;
|
return fDocumentCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::SelectAll()
|
||||||
|
{
|
||||||
|
fbHasSelection = true;
|
||||||
|
fSelectionRect.Set(0, 0, fpBitmap->Bounds().Width(), fpBitmap->Bounds().Height());
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::Unselect()
|
||||||
|
{
|
||||||
|
if (fbHasSelection) {
|
||||||
|
fbHasSelection = false;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageView::CopySelectionToClipboard()
|
||||||
|
{
|
||||||
|
if (fbHasSelection && be_clipboard->Lock()) {
|
||||||
|
be_clipboard->Clear();
|
||||||
|
BMessage *clip = NULL;
|
||||||
|
if ((clip = be_clipboard->Data()) != NULL) {
|
||||||
|
BMessage data;
|
||||||
|
BBitmap* bitmap = CopySelection();
|
||||||
|
if (bitmap != NULL) {
|
||||||
|
#if 1
|
||||||
|
// 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
|
||||||
|
bitmap->Archive(&msg);
|
||||||
|
clip->AddMessage("image/x-be-bitmap", &msg);
|
||||||
|
#else
|
||||||
|
// original ShowImage performs this. Paste works with original ShowImage.
|
||||||
|
bitmap->Archive(clip);
|
||||||
|
// original ShowImage uses be:location for insertion point
|
||||||
|
clip->AddPoint("be:location", BPoint(fSelectionRect.left, fSelectionRect.top));
|
||||||
|
#endif
|
||||||
|
delete bitmap;
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageView::FirstPage()
|
ShowImageView::FirstPage()
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <Bitmap.h>
|
#include <Bitmap.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
#include <TranslatorRoster.h>
|
||||||
|
|
||||||
class ShowImageView : public BView {
|
class ShowImageView : public BView {
|
||||||
public:
|
public:
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
void SetImage(const entry_ref *pref);
|
void SetImage(const entry_ref *pref);
|
||||||
void ResizeToViewBounds(bool resize);
|
void ResizeToViewBounds(bool resize);
|
||||||
BBitmap *GetBitmap();
|
BBitmap *GetBitmap();
|
||||||
|
void FlushToLeftTop();
|
||||||
|
|
||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void Draw(BRect updateRect);
|
virtual void Draw(BRect updateRect);
|
||||||
@ -59,6 +61,11 @@ public:
|
|||||||
int32 CurrentPage();
|
int32 CurrentPage();
|
||||||
int32 PageCount();
|
int32 PageCount();
|
||||||
|
|
||||||
|
void SelectAll();
|
||||||
|
void Unselect();
|
||||||
|
|
||||||
|
void CopySelectionToClipboard();
|
||||||
|
|
||||||
void FirstPage();
|
void FirstPage();
|
||||||
void LastPage();
|
void LastPage();
|
||||||
void NextPage();
|
void NextPage();
|
||||||
@ -84,7 +91,9 @@ private:
|
|||||||
};
|
};
|
||||||
void InitPatterns();
|
void InitPatterns();
|
||||||
void RotatePatterns();
|
void RotatePatterns();
|
||||||
|
void AnimateSelection(bool a);
|
||||||
void Notify(const char* status);
|
void Notify(const char* status);
|
||||||
|
void AddToRecentDocuments();
|
||||||
int32 BytesPerPixel(color_space cs) const;
|
int32 BytesPerPixel(color_space cs) const;
|
||||||
inline void CopyPixel(uchar* dest, int32 destX, int32 destY, int32 destBPR, uchar* src, int32 x, int32 y, int32 bpr, int32 bpp);
|
inline void CopyPixel(uchar* dest, int32 destX, int32 destY, int32 destBPR, uchar* src, int32 x, int32 y, int32 bpr, int32 bpp);
|
||||||
inline void InvertPixel(int32 x, int32 y, uchar* dest, int32 destBPR, uchar* src, int32 bpr, int32 bpp);
|
inline void InvertPixel(int32 x, int32 y, uchar* dest, int32 destBPR, uchar* src, int32 bpr, int32 bpp);
|
||||||
@ -100,6 +109,13 @@ private:
|
|||||||
bool ShowNextImage(bool next, bool rewind);
|
bool ShowNextImage(bool next, bool rewind);
|
||||||
bool FirstFile();
|
bool FirstFile();
|
||||||
void ConstrainToImage(BPoint &point);
|
void ConstrainToImage(BPoint &point);
|
||||||
|
BBitmap* CopySelection(uchar alpha = 255);
|
||||||
|
bool AddSupportedTypes(BMessage* msg, BBitmap* bitmap);
|
||||||
|
void BeginDrag(BPoint point);
|
||||||
|
void SaveToFile(BDirectory* dir, const char* name, BBitmap* bitmap, translation_format* format);
|
||||||
|
void SendInMessage(BMessage* msg, BBitmap* bitmap, translation_format* format);
|
||||||
|
bool OutputFormatForType(BBitmap* bitmap, const char* type, translation_format* format);
|
||||||
|
void HandleDrop(BMessage* msg);
|
||||||
void UpdateSelectionRect(BPoint point, bool final);
|
void UpdateSelectionRect(BPoint point, bool final);
|
||||||
void DrawBorder(BRect border);
|
void DrawBorder(BRect border);
|
||||||
void DrawSelectionBox(BRect &rect);
|
void DrawSelectionBox(BRect &rect);
|
||||||
@ -113,8 +129,10 @@ private:
|
|||||||
float fTop;
|
float fTop;
|
||||||
float fScaleX;
|
float fScaleX;
|
||||||
float fScaleY;
|
float fScaleY;
|
||||||
|
bool fBeginDrag;
|
||||||
bool fMakesSelection; // is a selection being made
|
bool fMakesSelection; // is a selection being made
|
||||||
BPoint fFirstPoint; // first point in image space of selection
|
BPoint fFirstPoint; // first point in image space of selection
|
||||||
|
bool fAnimateSelection; // marching ants
|
||||||
bool fbHasSelection; // is fSelectionRect valid
|
bool fbHasSelection; // is fSelectionRect valid
|
||||||
BRect fSelectionRect; // the selection in image space
|
BRect fSelectionRect; // the selection in image space
|
||||||
pattern fPatternUp, fPatternDown, fPatternLeft, fPatternRight;
|
pattern fPatternUp, fPatternDown, fPatternLeft, fPatternRight;
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <Alert.h>
|
#include <Alert.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <Screen.h>
|
#include <Screen.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
|
||||||
#include "ShowImageConstants.h"
|
#include "ShowImageConstants.h"
|
||||||
#include "ShowImageWindow.h"
|
#include "ShowImageWindow.h"
|
||||||
@ -110,7 +111,14 @@ ShowImageWindow::ShowImageWindow(const entry_ref *pref)
|
|||||||
|
|
||||||
SetPulseRate(100000); // every 1/10 second; ShowImageView needs it for marching ants
|
SetPulseRate(100000); // every 1/10 second; ShowImageView needs it for marching ants
|
||||||
|
|
||||||
Show();
|
if (InitCheck() == B_OK) {
|
||||||
|
fpImageView->FlushToLeftTop();
|
||||||
|
WindowRedimension(fpImageView->GetBitmap());
|
||||||
|
Show();
|
||||||
|
} else {
|
||||||
|
// exit if file could not be opened
|
||||||
|
Quit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowImageWindow::~ShowImageWindow()
|
ShowImageWindow::~ShowImageWindow()
|
||||||
@ -121,7 +129,7 @@ ShowImageWindow::~ShowImageWindow()
|
|||||||
status_t
|
status_t
|
||||||
ShowImageWindow::InitCheck()
|
ShowImageWindow::InitCheck()
|
||||||
{
|
{
|
||||||
if (!fpRef || !fpImageView)
|
if (!fpRef || !fpImageView || fpImageView->GetBitmap() == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
else
|
else
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -148,11 +156,40 @@ ShowImageWindow::UpdateTitle()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ShowImageWindow::UpdateRecentDocumentsMenu()
|
||||||
|
{
|
||||||
|
BMenuItem *item;
|
||||||
|
BMessage list, *msg;
|
||||||
|
entry_ref ref;
|
||||||
|
char name[B_FILE_NAME_LENGTH];
|
||||||
|
|
||||||
|
while ((item = fpOpenMenu->RemoveItem((int32)0)) != NULL) {
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
|
||||||
|
be_roster->GetRecentDocuments(&list, 20, NULL, APP_SIG);
|
||||||
|
for (int i = 0; list.FindRef("refs", i, &ref) == B_OK; i++) {
|
||||||
|
BEntry entry(&ref);
|
||||||
|
entry.GetName(name);
|
||||||
|
msg = new BMessage(B_REFS_RECEIVED);
|
||||||
|
msg->AddRef("refs", &ref);
|
||||||
|
item = new BMenuItem(name, msg, 0, 0);
|
||||||
|
fpOpenMenu->AddItem(item);
|
||||||
|
item->SetTarget(be_app, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
||||||
{
|
{
|
||||||
BMenu *pmenu = new BMenu("File");
|
BMenu *pmenu = new BMenu("File");
|
||||||
AddItemMenu(pmenu, "Open", MSG_FILE_OPEN, 'O', 0, 'A', true);
|
fpOpenMenu = new BMenu("Open");
|
||||||
|
pmenu->AddItem(fpOpenMenu);
|
||||||
|
fpOpenMenu->Superitem()->SetTrigger('O');
|
||||||
|
fpOpenMenu->Superitem()->SetMessage(new BMessage(MSG_FILE_OPEN));
|
||||||
|
fpOpenMenu->Superitem()->SetTarget(be_app);
|
||||||
|
fpOpenMenu->Superitem()->SetShortcut('O', 0);
|
||||||
pmenu->AddSeparatorItem();
|
pmenu->AddSeparatorItem();
|
||||||
AddItemMenu(pmenu, "Dia Show", MSG_DIA_SHOW, 0, 0, 'W', true);
|
AddItemMenu(pmenu, "Dia Show", MSG_DIA_SHOW, 0, 0, 'W', true);
|
||||||
BMenu* pDelay = new BMenu("Delay");
|
BMenu* pDelay = new BMenu("Delay");
|
||||||
@ -193,11 +230,11 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
|||||||
AddItemMenu(pmenu, "Undo", B_UNDO, 'Z', 0, 'W', false);
|
AddItemMenu(pmenu, "Undo", B_UNDO, 'Z', 0, 'W', false);
|
||||||
pmenu->AddSeparatorItem();
|
pmenu->AddSeparatorItem();
|
||||||
AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false);
|
AddItemMenu(pmenu, "Cut", B_CUT, 'X', 0, 'W', false);
|
||||||
AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', false);
|
AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', true);
|
||||||
AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false);
|
AddItemMenu(pmenu, "Paste", B_PASTE, 'V', 0, 'W', false);
|
||||||
AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', false);
|
AddItemMenu(pmenu, "Clear", MSG_CLEAR_SELECT, 0, 0, 'W', true);
|
||||||
pmenu->AddSeparatorItem();
|
pmenu->AddSeparatorItem();
|
||||||
AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', false);
|
AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
|
||||||
pbar->AddItem(pmenu);
|
pbar->AddItem(pmenu);
|
||||||
|
|
||||||
pmenu = fpPageMenu = new BMenu("Page");
|
pmenu = fpPageMenu = new BMenu("Page");
|
||||||
@ -223,6 +260,8 @@ ShowImageWindow::LoadMenus(BMenuBar *pbar)
|
|||||||
AddItemMenu(pmenu, "Fit To Window Size", MSG_FIT_TO_WINDOW_SIZE, 0, 0, 'W', true);
|
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, "Full Screen", MSG_FULL_SCREEN, B_ENTER, 0, 'W', true);
|
||||||
pbar->AddItem(pmenu);
|
pbar->AddItem(pmenu);
|
||||||
|
|
||||||
|
UpdateRecentDocumentsMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
BMenuItem *
|
BMenuItem *
|
||||||
@ -260,32 +299,28 @@ ShowImageWindow::AddDelayItem(BMenu *pmenu, char *caption, float value, bool mar
|
|||||||
void
|
void
|
||||||
ShowImageWindow::WindowRedimension(BBitmap *pbitmap)
|
ShowImageWindow::WindowRedimension(BBitmap *pbitmap)
|
||||||
{
|
{
|
||||||
// set the window's min & max size limits
|
BScreen screen;
|
||||||
// based on document's data bounds
|
BRect r(pbitmap->Bounds());
|
||||||
float maxWidth = pbitmap->Bounds().Width() + B_V_SCROLL_BAR_WIDTH;
|
float width, height;
|
||||||
float maxHeight = pbitmap->Bounds().Height() + fpBar->Frame().Height() +
|
float maxWidth, maxHeight;
|
||||||
B_H_SCROLL_BAR_HEIGHT + 1;
|
const float windowBorderWidth = 5;
|
||||||
float minWidth = min(maxWidth, 100.0f);
|
const float windowBorderHeight = 5;
|
||||||
float minHeight = min(maxHeight, 100.0f);
|
|
||||||
|
|
||||||
// adjust the window's current size based on new min/max values
|
if (screen.Frame().right == 0.0) {
|
||||||
float curWidth = Bounds().Width();
|
return; // invalid screen object
|
||||||
float curHeight = Bounds().Height();
|
}
|
||||||
if (curWidth < minWidth)
|
|
||||||
curWidth = minWidth;
|
|
||||||
else if (curWidth > maxWidth)
|
|
||||||
curWidth = maxWidth;
|
|
||||||
|
|
||||||
if (curHeight < minHeight)
|
width = r.Width() + B_V_SCROLL_BAR_WIDTH;
|
||||||
curHeight = minHeight;
|
height = r.Height() + 1 + fpBar->Frame().Height() + B_H_SCROLL_BAR_HEIGHT;
|
||||||
else if (curHeight > maxHeight)
|
|
||||||
curHeight = maxHeight;
|
|
||||||
|
|
||||||
if (minWidth < 250)
|
// dimensions so that window does not reach outside of screen
|
||||||
minWidth = 250;
|
maxWidth = screen.Frame().Width() + 1 - windowBorderWidth - Frame().left;
|
||||||
|
maxHeight = screen.Frame().Height() + 1 - windowBorderHeight - Frame().top;
|
||||||
|
|
||||||
SetSizeLimits(minWidth, maxWidth, minHeight, maxHeight);
|
if (width > maxWidth) width = maxWidth;
|
||||||
ResizeTo(curWidth, curHeight);
|
if (height > maxHeight) height = maxHeight;
|
||||||
|
|
||||||
|
ResizeTo(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -357,12 +392,15 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
|||||||
case B_CUT:
|
case B_CUT:
|
||||||
break;
|
break;
|
||||||
case B_COPY:
|
case B_COPY:
|
||||||
|
fpImageView->CopySelectionToClipboard();
|
||||||
break;
|
break;
|
||||||
case B_PASTE:
|
case B_PASTE:
|
||||||
break;
|
break;
|
||||||
case MSG_CLEAR_SELECT:
|
case MSG_CLEAR_SELECT:
|
||||||
|
fpImageView->Unselect();
|
||||||
break;
|
break;
|
||||||
case MSG_SELECT_ALL:
|
case MSG_SELECT_ALL:
|
||||||
|
fpImageView->SelectAll();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MSG_PAGE_FIRST:
|
case MSG_PAGE_FIRST:
|
||||||
@ -435,6 +473,10 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
|
|||||||
ToggleFullScreen();
|
ToggleFullScreen();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MSG_UPDATE_RECENT_DOCUMENTS:
|
||||||
|
UpdateRecentDocumentsMenu();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(pmsg);
|
BWindow::MessageReceived(pmsg);
|
||||||
break;
|
break;
|
||||||
|
@ -65,6 +65,7 @@ private:
|
|||||||
char target, bool enabled);
|
char target, bool enabled);
|
||||||
|
|
||||||
BMenuItem* AddDelayItem(BMenu *pmenu, char *caption, float value, bool marked);
|
BMenuItem* AddDelayItem(BMenu *pmenu, char *caption, float value, bool marked);
|
||||||
|
void UpdateRecentDocumentsMenu();
|
||||||
|
|
||||||
bool ToggleMenuItem(uint32 what);
|
bool ToggleMenuItem(uint32 what);
|
||||||
|
|
||||||
@ -78,6 +79,7 @@ private:
|
|||||||
|
|
||||||
BFilePanel *fpSavePanel;
|
BFilePanel *fpSavePanel;
|
||||||
BMenuBar *fpBar;
|
BMenuBar *fpBar;
|
||||||
|
BMenu *fpOpenMenu;
|
||||||
BMenu *fpPageMenu;
|
BMenu *fpPageMenu;
|
||||||
entry_ref *fpRef;
|
entry_ref *fpRef;
|
||||||
ShowImageView *fpImageView;
|
ShowImageView *fpImageView;
|
||||||
|
Loading…
Reference in New Issue
Block a user