Added code to merge selection with background image; removed Select None item, replaced it with Clear as Select None was behaving like Be ShowImage's Clear anyway; properly enabled/disabled Edit menu items when selection is made or cleared. Still no undo yet, but I'm planning to do that after Paste is implemented.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5403 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber 2003-11-18 02:48:53 +00:00
parent 497c0bf9c1
commit 8ad30bcf80
4 changed files with 90 additions and 32 deletions

View File

@ -40,9 +40,9 @@ const uint32 MSG_OUTPUT_TYPE = 'BTMN';
const uint32 MSG_SAVE_PANEL = 'mFSP'; const uint32 MSG_SAVE_PANEL = 'mFSP';
const uint32 MSG_CLEAR_SELECT = 'mCSL'; const uint32 MSG_CLEAR_SELECT = 'mCSL';
const uint32 MSG_SELECT_ALL = 'mSAL'; const uint32 MSG_SELECT_ALL = 'mSAL';
const uint32 MSG_SELECT_NONE = 'mSNO';
const uint32 MSG_DITHER_IMAGE = 'mDIM'; const uint32 MSG_DITHER_IMAGE = 'mDIM';
const uint32 MSG_UPDATE_STATUS = 'mUPS'; const uint32 MSG_UPDATE_STATUS = 'mUPS';
const uint32 MSG_SELECTION = 'mSEL';
const uint32 MSG_PAGE_FIRST = 'mPGF'; const uint32 MSG_PAGE_FIRST = 'mPGF';
const uint32 MSG_PAGE_LAST = 'mPGL'; const uint32 MSG_PAGE_LAST = 'mPGL';
const uint32 MSG_PAGE_NEXT = 'mPGN'; const uint32 MSG_PAGE_NEXT = 'mPGN';

View File

@ -625,30 +625,10 @@ ShowImageView::Draw(BRect updateRect)
if (HasSelection()) { if (HasSelection()) {
if (fSelBitmap) { if (fSelBitmap) {
BRect clippedRect, bounds; BRect srcBits, destRect;
clippedRect = fSelectionRect; GetSelMergeRects(srcBits, destRect);
ConstrainToImage(clippedRect); destRect = ImageToView(destRect);
clippedRect = ImageToView(clippedRect); DrawBitmap(fSelBitmap, srcBits, destRect);
bounds = fSelectionRect;
if (bounds.left < 0)
bounds.left = -(bounds.left);
else
bounds.left = 0;
if (bounds.top < 0)
bounds.top = -(bounds.top);
else
bounds.top = 0;
if (bounds.right > fBitmap->Bounds().right)
bounds.right = bounds.left + clippedRect.Width();
else
bounds.right = fSelBitmap->Bounds().right;
if (bounds.bottom > fBitmap->Bounds().bottom)
bounds.bottom = bounds.top + clippedRect.Height();
else
bounds.bottom = fSelBitmap->Bounds().bottom;
DrawBitmap(fSelBitmap, bounds, clippedRect);
} }
DrawSelectionBox(fSelectionRect); DrawSelectionBox(fSelectionRect);
} }
@ -924,6 +904,61 @@ ShowImageView::GetMouseButtons()
return buttons; return buttons;
} }
void
ShowImageView::GetSelMergeRects(BRect &srcBits, BRect &destRect)
{
destRect = fSelectionRect;
ConstrainToImage(destRect);
srcBits = fSelectionRect;
if (srcBits.left < 0)
srcBits.left = -(srcBits.left);
else
srcBits.left = 0;
if (srcBits.top < 0)
srcBits.top = -(srcBits.top);
else
srcBits.top = 0;
if (srcBits.right > fBitmap->Bounds().right)
srcBits.right = srcBits.left + destRect.Width();
else
srcBits.right = fSelBitmap->Bounds().right;
if (srcBits.bottom > fBitmap->Bounds().bottom)
srcBits.bottom = srcBits.top + destRect.Height();
else
srcBits.bottom = fSelBitmap->Bounds().bottom;
}
void
ShowImageView::MergeSelection()
{
if (!HasSelection() || !fSelBitmap)
return;
// Merge selection with background
BView view(fBitmap->Bounds(), NULL, B_FOLLOW_NONE, B_WILL_DRAW);
BBitmap *bitmap = new BBitmap(fBitmap->Bounds(), fBitmap->ColorSpace(), true);
if (bitmap == NULL)
return;
if (bitmap->Lock()) {
bitmap->AddChild(&view);
view.DrawBitmap(fBitmap, fBitmap->Bounds());
BRect srcBits, destRect;
GetSelMergeRects(srcBits, destRect);
view.DrawBitmap(fSelBitmap, srcBits, destRect);
view.Sync();
bitmap->RemoveChild(&view);
bitmap->Unlock();
DeleteBitmap();
fBitmap = bitmap;
} else
delete bitmap;
}
void void
ShowImageView::MouseDown(BPoint position) ShowImageView::MouseDown(BPoint position)
{ {
@ -971,6 +1006,11 @@ ShowImageView::MouseDown(BPoint position)
AnimateSelection(true); AnimateSelection(true);
} else if (buttons == B_PRIMARY_MOUSE_BUTTON) { } else if (buttons == B_PRIMARY_MOUSE_BUTTON) {
if (HasSelection())
// If there is an existing selection,
// Make it part of the background image
MergeSelection();
// begin new selection // begin new selection
SetHasSelection(true); SetHasSelection(true);
fMakesSelection = true; fMakesSelection = true;
@ -1271,7 +1311,7 @@ ShowImageView::SelectAll()
} }
void void
ShowImageView::Unselect() ShowImageView::ClearSelection()
{ {
if (HasSelection()) { if (HasSelection()) {
SetHasSelection(false); SetHasSelection(false);
@ -1284,6 +1324,11 @@ ShowImageView::SetHasSelection(bool bHasSelection)
{ {
DeleteSelBitmap(); DeleteSelBitmap();
fbHasSelection = bHasSelection; fbHasSelection = bHasSelection;
BMessage msg(MSG_SELECTION);
msg.AddBool("has_selection", fbHasSelection);
BMessenger msgr(Window());
msgr.SendMessage(&msg);
} }
void void

View File

@ -73,7 +73,7 @@ public:
int32 PageCount(); int32 PageCount();
void SelectAll(); void SelectAll();
void Unselect(); void ClearSelection();
void CopySelectionToClipboard(); void CopySelectionToClipboard();
@ -112,6 +112,8 @@ private:
void AnimateSelection(bool a); void AnimateSelection(bool a);
void Notify(const char* status); void Notify(const char* status);
void AddToRecentDocuments(); void AddToRecentDocuments();
void GetSelMergeRects(BRect &srcBits, BRect &destRect);
void MergeSelection();
void DeleteScaler(); void DeleteScaler();
void DeleteBitmap(); void DeleteBitmap();
void DeleteSelBitmap(); void DeleteSelBitmap();

View File

@ -258,12 +258,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', true); AddItemMenu(pmenu, "Copy", B_COPY, 'C', 0, 'W', false);
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', false);
pmenu->AddSeparatorItem(); pmenu->AddSeparatorItem();
AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true); AddItemMenu(pmenu, "Select All", MSG_SELECT_ALL, 'A', 0, 'W', true);
AddItemMenu(pmenu, "Select None", MSG_SELECT_NONE, 0, 0, 'W', true);
pbar->AddItem(pmenu); pbar->AddItem(pmenu);
pmenu = fpBrowseMenu = new BMenu("Browse"); pmenu = fpBrowseMenu = new BMenu("Browse");
@ -500,6 +499,20 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
UpdateTitle(); UpdateTitle();
break; break;
} }
case MSG_SELECTION:
{
// The view sends this message when a selection is
// made or the selection is cleared so that the window
// can update the state of the appropriate menu items
bool benable;
if (pmsg->FindBool("has_selection", &benable) == B_OK) {
EnableMenuItem(fpBar, B_CUT, benable);
EnableMenuItem(fpBar, B_COPY, benable);
EnableMenuItem(fpBar, MSG_CLEAR_SELECT, benable);
}
break;
}
case B_UNDO: case B_UNDO:
break; break;
@ -511,13 +524,11 @@ ShowImageWindow::MessageReceived(BMessage *pmsg)
case B_PASTE: case B_PASTE:
break; break;
case MSG_CLEAR_SELECT: case MSG_CLEAR_SELECT:
fpImageView->ClearSelection();
break; break;
case MSG_SELECT_ALL: case MSG_SELECT_ALL:
fpImageView->SelectAll(); fpImageView->SelectAll();
break; break;
case MSG_SELECT_NONE:
fpImageView->Unselect();
break;
case MSG_PAGE_FIRST: case MSG_PAGE_FIRST:
fpImageView->FirstPage(); fpImageView->FirstPage();