Added initial implementation of Undo for OBOS ShowImage! Now, users can Undo/Redo merge/paste operations. Still need to enhance Undo further so that other operations can be undone, also need to account for image rotations and similar operations.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5693 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -299,6 +299,7 @@ void ShowImageView::DeleteSelBitmap()
|
||||
void
|
||||
ShowImageView::SetImage(const entry_ref *pref)
|
||||
{
|
||||
fUndo.Clear();
|
||||
DeleteBitmap();
|
||||
SetHasSelection(false);
|
||||
fMakesSelection = false;
|
||||
@@ -509,6 +510,7 @@ ShowImageView::SetScaleBilinear(bool s)
|
||||
void
|
||||
ShowImageView::AttachedToWindow()
|
||||
{
|
||||
fUndo.SetWindow(Window());
|
||||
FixupScrollBars();
|
||||
}
|
||||
|
||||
@@ -814,6 +816,25 @@ ShowImageView::ConstrainToImage(BRect &rect)
|
||||
rect.SetRightBottom(rightBottom);
|
||||
}
|
||||
|
||||
BBitmap*
|
||||
ShowImageView::CopyFromRect(BRect srcRect)
|
||||
{
|
||||
BRect rect(0, 0, srcRect.Width(), srcRect.Height());
|
||||
BView view(rect, NULL, B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
BBitmap *bitmap = new BBitmap(rect, fBitmap->ColorSpace(), true);
|
||||
if (bitmap == NULL) return NULL;
|
||||
|
||||
if (bitmap->Lock()) {
|
||||
bitmap->AddChild(&view);
|
||||
view.DrawBitmap(fBitmap, srcRect, rect);
|
||||
view.Sync();
|
||||
bitmap->RemoveChild(&view);
|
||||
bitmap->Unlock();
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
BBitmap*
|
||||
ShowImageView::CopySelection(uchar alpha, bool imageSize)
|
||||
{
|
||||
@@ -1038,12 +1059,12 @@ ShowImageView::GetMouseButtons()
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::GetSelMergeRects(BRect &srcBits, BRect &destRect)
|
||||
ShowImageView::GetMergeRects(BBitmap *merge, BRect selection, BRect &srcBits, BRect &destRect)
|
||||
{
|
||||
destRect = fSelectionRect;
|
||||
destRect = selection;
|
||||
ConstrainToImage(destRect);
|
||||
|
||||
srcBits = fSelectionRect;
|
||||
srcBits = selection;
|
||||
if (srcBits.left < 0)
|
||||
srcBits.left = -(srcBits.left);
|
||||
else
|
||||
@@ -1055,20 +1076,22 @@ ShowImageView::GetSelMergeRects(BRect &srcBits, BRect &destRect)
|
||||
if (srcBits.right > fBitmap->Bounds().right)
|
||||
srcBits.right = srcBits.left + destRect.Width();
|
||||
else
|
||||
srcBits.right = fSelBitmap->Bounds().right;
|
||||
srcBits.right = merge->Bounds().right;
|
||||
if (srcBits.bottom > fBitmap->Bounds().bottom)
|
||||
srcBits.bottom = srcBits.top + destRect.Height();
|
||||
else
|
||||
srcBits.bottom = fSelBitmap->Bounds().bottom;
|
||||
srcBits.bottom = merge->Bounds().bottom;
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::MergeSelection()
|
||||
ShowImageView::GetSelMergeRects(BRect &srcBits, BRect &destRect)
|
||||
{
|
||||
if (!HasSelection() || !fSelBitmap)
|
||||
return;
|
||||
GetMergeRects(fSelBitmap, fSelectionRect, srcBits, destRect);
|
||||
}
|
||||
|
||||
// Merge selection with background
|
||||
void
|
||||
ShowImageView::MergeWithBitmap(BBitmap *merge, BRect selection)
|
||||
{
|
||||
BView view(fBitmap->Bounds(), NULL, B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
BBitmap *bitmap = new BBitmap(fBitmap->Bounds(), fBitmap->ColorSpace(), true);
|
||||
if (bitmap == NULL)
|
||||
@@ -1077,10 +1100,9 @@ ShowImageView::MergeSelection()
|
||||
if (bitmap->Lock()) {
|
||||
bitmap->AddChild(&view);
|
||||
view.DrawBitmap(fBitmap, fBitmap->Bounds());
|
||||
|
||||
BRect srcBits, destRect;
|
||||
GetSelMergeRects(srcBits, destRect);
|
||||
view.DrawBitmap(fSelBitmap, srcBits, destRect);
|
||||
GetMergeRects(merge, selection, srcBits, destRect);
|
||||
view.DrawBitmap(merge, srcBits, destRect);
|
||||
|
||||
view.Sync();
|
||||
bitmap->RemoveChild(&view);
|
||||
@@ -1095,6 +1117,25 @@ ShowImageView::MergeSelection()
|
||||
delete bitmap;
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::MergeSelection()
|
||||
{
|
||||
if (!HasSelection())
|
||||
return;
|
||||
|
||||
if (!fSelBitmap) {
|
||||
// Even though the merge will not change
|
||||
// the background image, I still need to save
|
||||
// some undo information here
|
||||
fUndo.SetTo(fSelectionRect, NULL, CopySelection());
|
||||
return;
|
||||
}
|
||||
|
||||
// Merge selection with background
|
||||
fUndo.SetTo(fSelectionRect, CopyFromRect(fSelectionRect), CopySelection());
|
||||
MergeWithBitmap(fSelBitmap, fSelectionRect);
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::MouseDown(BPoint position)
|
||||
{
|
||||
@@ -1485,6 +1526,45 @@ ShowImageView::PageCount()
|
||||
return fDocumentCount;
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::Undo()
|
||||
{
|
||||
int32 undoType = fUndo.GetType();
|
||||
if (undoType != UNDO_UNDO && undoType != UNDO_REDO)
|
||||
return;
|
||||
|
||||
// backup current selection
|
||||
BRect undoneSelRect;
|
||||
BBitmap *undoneSelection;
|
||||
undoneSelRect = fSelectionRect;
|
||||
undoneSelection = CopySelection();
|
||||
|
||||
if (undoType == UNDO_UNDO) {
|
||||
BBitmap *undoRestore;
|
||||
undoRestore = fUndo.GetRestoreBitmap();
|
||||
if (undoRestore)
|
||||
MergeWithBitmap(undoRestore, fUndo.GetRect());
|
||||
}
|
||||
|
||||
// restore previous image/selection
|
||||
BBitmap *undoSelection;
|
||||
undoSelection = fUndo.GetSelectionBitmap();
|
||||
// NOTE: ShowImageView is responsible for deleting this bitmap
|
||||
// (Which it will, as it would with a fSelBitmap that it allocated itself)
|
||||
if (!undoSelection)
|
||||
SetHasSelection(false);
|
||||
else {
|
||||
SetHasSelection(true);
|
||||
fCopyFromRect = BRect();
|
||||
fSelectionRect = fUndo.GetRect();
|
||||
fSelBitmap = undoSelection;
|
||||
}
|
||||
|
||||
fUndo.Undo(undoneSelRect, NULL, undoneSelection);
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void
|
||||
ShowImageView::AddWhiteRect(BRect &rect)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user