culmulative update...

* holding down space, or using the third mouse button, will force
  the "pan canvas" mode
* using the mouse wheel zooms in and out
* fixed issues with the undo commands when nudging something with
  the cursor keys
* manipulators can now indicate wether they changed the mouse cursor
* ChangePointCommand is no longer inserted if the point didn't change
* new "flip" points feature in context menu, flips "in" and "out" curve
  control points
* mouse wheel events are now propagated together with the mouse position
* new "UndoesPrevious" method in Command interface (used to clean up
  command stack)
* clean ups in CommandStack



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20623 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2007-04-09 08:30:28 +00:00
parent 9261b12988
commit 7c4b3726d9
25 changed files with 373 additions and 104 deletions
+135 -3
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -9,10 +9,14 @@
#include "CanvasView.h" #include "CanvasView.h"
#include <Bitmap.h> #include <Bitmap.h>
#include <Cursor.h>
#include <Message.h>
#include <Region.h> #include <Region.h>
#include <Window.h>
#include <stdio.h> #include <stdio.h>
#include "cursors.h"
#include "ui_defines.h" #include "ui_defines.h"
#include "CommandStack.h" #include "CommandStack.h"
@@ -33,6 +37,10 @@ CanvasView::CanvasView(BRect frame)
fCanvasOrigin(0.0, 0.0), fCanvasOrigin(0.0, 0.0),
fZoomLevel(1.0), fZoomLevel(1.0),
fSpaceHeldDown(false),
fScrollTracking(false),
fScrollTrackingStart(0.0, 0.0),
fMouseFilterMode(SNAPPING_OFF), fMouseFilterMode(SNAPPING_OFF),
fOffsreenBitmap(NULL), fOffsreenBitmap(NULL),
@@ -136,7 +144,66 @@ CanvasView::MouseDown(BPoint where)
if (!IsFocus()) if (!IsFocus())
MakeFocus(true); MakeFocus(true);
StateView::MouseDown(where); uint32 buttons;
if (Window()->CurrentMessage()->FindInt32("buttons",
(int32*)&buttons) < B_OK)
buttons = 0;
// handle clicks of the third mouse button ourselves (panning),
// otherwise have StateView handle it (normal clicks)
if (fSpaceHeldDown || buttons & B_TERTIARY_MOUSE_BUTTON) {
// switch into scrolling mode and update cursor
fScrollTracking = true;
where.x = roundf(where.x);
where.y = roundf(where.y);
fScrollOffsetStart = ScrollOffset();
fScrollTrackingStart = where - fScrollOffsetStart;
_UpdateToolCursor();
SetMouseEventMask(B_POINTER_EVENTS,
B_LOCK_WINDOW_FOCUS | B_SUSPEND_VIEW_FOCUS);
} else {
StateView::MouseDown(where);
}
}
// MouseUp
void
CanvasView::MouseUp(BPoint where)
{
if (fScrollTracking) {
// stop scroll tracking and update cursor
fScrollTracking = false;
_UpdateToolCursor();
// update StateView mouse position
uint32 transit = Bounds().Contains(where) ?
B_INSIDE_VIEW : B_OUTSIDE_VIEW;
StateView::MouseMoved(where, transit, NULL);
} else {
StateView::MouseUp(where);
}
}
// MouseMoved
void
CanvasView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
{
if (fScrollTracking) {
uint32 buttons;
GetMouse(&where, &buttons, false);
if (!buttons) {
MouseUp(where);
return;
}
where.x = roundf(where.x);
where.y = roundf(where.y);
where -= ScrollOffset();
BPoint offset = where - fScrollTrackingStart;
SetScrollOffset(fScrollOffsetStart - offset);
} else {
// normal mouse movement handled by StateView
if (!fSpaceHeldDown)
StateView::MouseMoved(where, transit, dragMessage);
}
} }
// FilterMouse // FilterMouse
@@ -180,6 +247,23 @@ CanvasView::FilterMouse(BPoint* where) const
} }
} }
// MouseWheelChanged
bool
CanvasView::MouseWheelChanged(BPoint where, float x, float y)
{
if (!Bounds().Contains(where))
return false;
if (y > 0.0) {
_SetZoom(_NextZoomOutLevel(fZoomLevel));
return true;
} else if (y < 0.0) {
_SetZoom(_NextZoomInLevel(fZoomLevel));
return true;
}
return false;
}
// #pragma mark - // #pragma mark -
// ScrollOffsetChanged // ScrollOffsetChanged
@@ -187,9 +271,15 @@ void
CanvasView::ScrollOffsetChanged(BPoint oldOffset, BPoint newOffset) CanvasView::ScrollOffsetChanged(BPoint oldOffset, BPoint newOffset)
{ {
BPoint offset = newOffset - oldOffset; BPoint offset = newOffset - oldOffset;
if (offset == B_ORIGIN)
// prevent circular code (MouseMoved might call ScrollBy...)
return;
ScrollBy(offset.x, offset.y); ScrollBy(offset.x, offset.y);
MouseMoved(fMouseInfo.position + offset, fMouseInfo.transit, NULL); if (!fScrollTracking)
MouseMoved(fMouseInfo.position + offset, fMouseInfo.transit, NULL);
} }
// VisibleSizeChanged // VisibleSizeChanged
@@ -308,6 +398,11 @@ CanvasView::_HandleKeyDown(uint32 key, uint32 modifiers)
_SetZoom(_NextZoomOutLevel(fZoomLevel)); _SetZoom(_NextZoomOutLevel(fZoomLevel));
break; break;
case B_SPACE:
fSpaceHeldDown = true;
_UpdateToolCursor();
break;
default: default:
return StateView::_HandleKeyDown(key, modifiers); return StateView::_HandleKeyDown(key, modifiers);
} }
@@ -315,6 +410,23 @@ CanvasView::_HandleKeyDown(uint32 key, uint32 modifiers)
return true; return true;
} }
// _HandleKeyUp
bool
CanvasView::_HandleKeyUp(uint32 key, uint32 modifiers)
{
switch (key) {
case B_SPACE:
fSpaceHeldDown = false;
_UpdateToolCursor();
break;
default:
return StateView::_HandleKeyUp(key, modifiers);
}
return true;
}
// _CanvasRect() // _CanvasRect()
BRect BRect
CanvasView::_CanvasRect() const CanvasView::_CanvasRect() const
@@ -473,6 +585,26 @@ CanvasView::_MakeBackground()
} }
} }
// _UpdateToolCursor
void
CanvasView::_UpdateToolCursor()
{
if (fIcon) {
if (fScrollTracking || fSpaceHeldDown) {
// indicate scrolling mode
const uchar* cursorData = fScrollTracking ? kGrabCursor : kHandCursor;
BCursor cursor(cursorData);
SetViewCursor(&cursor, true);
} else {
// pass on to current state of StateView
UpdateStateCursor();
}
} else {
BCursor cursor(kStopCursor);
SetViewCursor(&cursor, true);
}
}
// #pragma mark - // #pragma mark -
// _NextZoomInLevel // _NextZoomInLevel
+14
View File
@@ -43,8 +43,14 @@ class CanvasView : public StateView,
virtual void Draw(BRect updateRect); virtual void Draw(BRect updateRect);
virtual void MouseDown(BPoint where); virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage);
virtual void FilterMouse(BPoint* where) const; virtual void FilterMouse(BPoint* where) const;
virtual bool MouseWheelChanged(BPoint where,
float x, float y);
// Scrollable interface // Scrollable interface
protected: protected:
virtual void ScrollOffsetChanged(BPoint oldOffset, virtual void ScrollOffsetChanged(BPoint oldOffset,
@@ -76,6 +82,7 @@ class CanvasView : public StateView,
protected: protected:
// StateView interface // StateView interface
virtual bool _HandleKeyDown(uint32 key, uint32 modifiers); virtual bool _HandleKeyDown(uint32 key, uint32 modifiers);
virtual bool _HandleKeyUp(uint32 key, uint32 modifiers);
// CanvasView // CanvasView
BRect _CanvasRect() const; BRect _CanvasRect() const;
@@ -88,6 +95,8 @@ class CanvasView : public StateView,
void _MakeBackground(); void _MakeBackground();
void _UpdateToolCursor();
private: private:
double _NextZoomInLevel(double zoom) const; double _NextZoomInLevel(double zoom) const;
double _NextZoomOutLevel(double zoom) const; double _NextZoomOutLevel(double zoom) const;
@@ -105,6 +114,11 @@ class CanvasView : public StateView,
BPoint fCanvasOrigin; BPoint fCanvasOrigin;
double fZoomLevel; double fZoomLevel;
bool fSpaceHeldDown;
bool fScrollTracking;
BPoint fScrollTrackingStart;
BPoint fScrollOffsetStart;
uint32 fMouseFilterMode; uint32 fMouseFilterMode;
BBitmap* fOffsreenBitmap; BBitmap* fOffsreenBitmap;
+1
View File
@@ -243,6 +243,7 @@ Application Icon-O-Matic :
AddTransformersCommand.cpp AddTransformersCommand.cpp
ChangePointCommand.cpp ChangePointCommand.cpp
CleanUpPathCommand.cpp CleanUpPathCommand.cpp
FlipPointsCommand.cpp
FreezeTransformationCommand.cpp FreezeTransformationCommand.cpp
InsertPointCommand.cpp InsertPointCommand.cpp
MoveShapesCommand.cpp MoveShapesCommand.cpp
@@ -58,6 +58,13 @@ Command::GetName(BString& name)
name << "Name of action goes here."; name << "Name of action goes here.";
} }
// UndoesPrevious
bool
Command::UndoesPrevious(const Command* previous)
{
return false;
}
// CombineWithNext // CombineWithNext
bool bool
Command::CombineWithNext(const Command* next) Command::CombineWithNext(const Command* next)
@@ -27,6 +27,7 @@ class Command {
virtual void GetName(BString& name); virtual void GetName(BString& name);
virtual bool UndoesPrevious(const Command* previous);
virtual bool CombineWithNext(const Command* next); virtual bool CombineWithNext(const Command* next);
virtual bool CombineWithPrevious(const Command* previous); virtual bool CombineWithPrevious(const Command* previous);
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -34,23 +34,25 @@ CommandStack::~CommandStack()
status_t status_t
CommandStack::Perform(Command* command) CommandStack::Perform(Command* command)
{ {
if (!Lock())
return B_ERROR;
status_t ret = command ? B_OK : B_BAD_VALUE; status_t ret = command ? B_OK : B_BAD_VALUE;
if (Lock()) { if (ret == B_OK)
if (ret == B_OK) ret = command->InitCheck();
ret = command->InitCheck();
if (ret == B_OK)
if (ret == B_OK) ret = command->Perform();
ret = command->Perform();
if (ret == B_OK)
if (ret == B_OK) ret = _AddCommand(command);
ret = _AddCommand(command);
if (ret != B_OK) {
if (ret != B_OK) { // no one else feels responsible...
// no one else feels responsible... delete command;
delete command;
}
Unlock();
} }
Unlock();
return ret; return ret;
} }
@@ -58,19 +60,20 @@ CommandStack::Perform(Command* command)
status_t status_t
CommandStack::Undo() CommandStack::Undo()
{ {
if (!Lock())
return B_ERROR;
status_t status = B_ERROR; status_t status = B_ERROR;
if (Lock()) { if (!fUndoHistory.empty()) {
if (!fUndoHistory.empty()) { Command* command = fUndoHistory.top();
Command* command = fUndoHistory.top(); fUndoHistory.pop();
fUndoHistory.pop(); status = command->Undo();
status = command->Undo(); if (status == B_OK)
if (status == B_OK) fRedoHistory.push(command);
fRedoHistory.push(command); else
else fUndoHistory.push(command);
fUndoHistory.push(command);
}
Unlock();
} }
Unlock();
Notify(); Notify();
@@ -81,19 +84,20 @@ CommandStack::Undo()
status_t status_t
CommandStack::Redo() CommandStack::Redo()
{ {
if (!Lock())
return B_ERROR;
status_t status = B_ERROR; status_t status = B_ERROR;
if (Lock()) { if (!fRedoHistory.empty()) {
if (!fRedoHistory.empty()) { Command* command = fRedoHistory.top();
Command* command = fRedoHistory.top(); fRedoHistory.pop();
fRedoHistory.pop(); status = command->Redo();
status = command->Redo(); if (status == B_OK)
if (status == B_OK) fUndoHistory.push(command);
fUndoHistory.push(command); else
else fRedoHistory.push(command);
fRedoHistory.push(command);
}
Unlock();
} }
Unlock();
Notify(); Notify();
@@ -187,29 +191,56 @@ status_t
CommandStack::_AddCommand(Command* command) CommandStack::_AddCommand(Command* command)
{ {
status_t status = B_OK; status_t status = B_OK;
// try to collapse commands to a single command
bool add = true; bool add = true;
if (!fUndoHistory.empty()) { if (!fUndoHistory.empty()) {
// try to collapse commands to a single command
// or remove this and the previous command if
// they reverse each other
if (Command* top = fUndoHistory.top()) { if (Command* top = fUndoHistory.top()) {
if (top->CombineWithNext(command)) { if (command->UndoesPrevious(top)) {
add = false;
fUndoHistory.pop();
delete top;
delete command;
} else if (top->CombineWithNext(command)) {
add = false; add = false;
delete command; delete command;
// after collapsing, the command might
// have changed it's mind about InitCheck()
// (the commands reversed each other)
if (top->InitCheck() < B_OK) {
fUndoHistory.pop();
delete top;
}
} else if (command->CombineWithPrevious(top)) { } else if (command->CombineWithPrevious(top)) {
fUndoHistory.pop(); fUndoHistory.pop();
delete top; delete top;
// after collapsing, the command might
// have changed it's mind about InitCheck()
// (the commands reversed each other)
if (command->InitCheck() < B_OK) {
delete command;
add = false;
}
} }
} }
} }
if (add) { if (add) {
// TODO: check return value and set status try {
fUndoHistory.push(command); fUndoHistory.push(command);
} catch (...) {
status = B_ERROR;
}
} }
// the redo stack needs to be empty if (status == B_OK) {
// as soon as a command was added (also in case of collapsing) // the redo stack needs to be empty
while (!fRedoHistory.empty()) { // as soon as a command was added (also in case of collapsing)
delete fRedoHistory.top(); while (!fRedoHistory.empty()) {
fRedoHistory.pop(); delete fRedoHistory.top();
fRedoHistory.pop();
}
} }
Notify(); Notify();
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -106,9 +106,10 @@ Manipulator::HandleKeyUp(uint32 key, uint32 modifiers, Command** _command)
} }
// UpdateCursor // UpdateCursor
void bool
Manipulator::UpdateCursor() Manipulator::UpdateCursor()
{ {
return false;
} }
// #pragma mark - // #pragma mark -
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -44,7 +44,7 @@ class Manipulator : public Observer {
virtual bool HandleKeyUp(uint32 key, uint32 modifiers, virtual bool HandleKeyUp(uint32 key, uint32 modifiers,
Command** _command); Command** _command);
virtual void UpdateCursor(); virtual bool UpdateCursor();
virtual BRect Bounds() = 0; virtual BRect Bounds() = 0;
// the area that the manipulator is // the area that the manipulator is
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -172,6 +172,10 @@ bool
MultipleManipulatorState::HandleKeyDown(uint32 key, uint32 modifiers, MultipleManipulatorState::HandleKeyDown(uint32 key, uint32 modifiers,
Command** _command) Command** _command)
{ {
// TODO: somehow this looks suspicious, because it doesn't
// seem guaranteed that the manipulator having indicated to
// handle the key down handles the matching key up event...
// maybe there should be the concept of the "focused manipulator"
int32 count = fManipulators.CountItems(); int32 count = fManipulators.CountItems();
for (int32 i = 0; i < count; i++) { for (int32 i = 0; i < count; i++) {
Manipulator* manipulator = Manipulator* manipulator =
@@ -197,6 +201,15 @@ MultipleManipulatorState::HandleKeyUp(uint32 key, uint32 modifiers,
return false; return false;
} }
// UpdateCursor
bool
MultipleManipulatorState::UpdateCursor()
{
if (fPreviousManipulator && fManipulators.HasItem(fPreviousManipulator))
return fPreviousManipulator->UpdateCursor();
return false;
}
// #pragma mark - // #pragma mark -
// AddManipulator // AddManipulator
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -44,6 +44,8 @@ class MultipleManipulatorState : public ViewState {
virtual bool HandleKeyUp(uint32 key, uint32 modifiers, virtual bool HandleKeyUp(uint32 key, uint32 modifiers,
Command** _command); Command** _command);
virtual bool UpdateCursor();
// MultipleManipulatorState // MultipleManipulatorState
bool AddManipulator(Manipulator* manipulator); bool AddManipulator(Manipulator* manipulator);
Manipulator* RemoveManipulator(int32 index); Manipulator* RemoveManipulator(int32 index);
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -78,7 +78,8 @@ if (dynamic_cast<GradientControl*>(*target))
float y; float y;
if (message->FindFloat("be:wheel_delta_x", &x) >= B_OK if (message->FindFloat("be:wheel_delta_x", &x) >= B_OK
&& message->FindFloat("be:wheel_delta_y", &y) >= B_OK) { && message->FindFloat("be:wheel_delta_y", &y) >= B_OK) {
if (fTarget->MouseWheelChanged(x, y)) if (fTarget->MouseWheelChanged(
fTarget->MouseInfo()->position, x, y))
result = B_SKIP_MESSAGE; result = B_SKIP_MESSAGE;
} }
break; break;
@@ -330,6 +331,15 @@ StateView::SetState(ViewState* state)
fCurrentState->Init(); fCurrentState->Init();
} }
// UpdateStateCursor
void
StateView::UpdateStateCursor()
{
if (!fCurrentState || !fCurrentState->UpdateCursor()) {
SetViewCursor(B_CURSOR_SYSTEM_DEFAULT, true);
}
}
// Draw // Draw
void void
StateView::Draw(BView* into, BRect updateRect) StateView::Draw(BView* into, BRect updateRect)
@@ -350,7 +360,7 @@ StateView::Draw(BView* into, BRect updateRect)
// MouseWheelChanged // MouseWheelChanged
bool bool
StateView::MouseWheelChanged(float x, float y) StateView::MouseWheelChanged(BPoint where, float x, float y)
{ {
return false; return false;
} }
@@ -359,6 +369,11 @@ StateView::MouseWheelChanged(float x, float y)
bool bool
StateView::HandleKeyDown(uint32 key, uint32 modifiers) StateView::HandleKeyDown(uint32 key, uint32 modifiers)
{ {
// down't allow key events if mouse already pressed
// (central place to prevent command stack mix up)
if (fMouseInfo.buttons != 0)
return false;
AutoWriteLocker locker(fLocker); AutoWriteLocker locker(fLocker);
if (fLocker && !locker.IsLocked()) if (fLocker && !locker.IsLocked())
return false; return false;
@@ -380,6 +395,11 @@ StateView::HandleKeyDown(uint32 key, uint32 modifiers)
bool bool
StateView::HandleKeyUp(uint32 key, uint32 modifiers) StateView::HandleKeyUp(uint32 key, uint32 modifiers)
{ {
// down't allow key events if mouse already pressed
// (central place to prevent command stack mix up)
if (fMouseInfo.buttons != 0)
return false;
AutoWriteLocker locker(fLocker); AutoWriteLocker locker(fLocker);
if (fLocker && !locker.IsLocked()) if (fLocker && !locker.IsLocked())
return false; return false;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -40,10 +40,12 @@ class StateView : public BView {
// StateView interface // StateView interface
void SetState(ViewState* state); void SetState(ViewState* state);
void UpdateStateCursor();
void Draw(BView* into, BRect updateRect); void Draw(BView* into, BRect updateRect);
virtual bool MouseWheelChanged(float x, float y); virtual bool MouseWheelChanged(BPoint where,
float x, float y);
bool HandleKeyDown(uint32 key, uint32 modifiers); bool HandleKeyDown(uint32 key, uint32 modifiers);
bool HandleKeyUp(uint32 key, uint32 modifiers); bool HandleKeyUp(uint32 key, uint32 modifiers);
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -109,4 +109,9 @@ ViewState::HandleKeyUp(uint32 key, uint32 modifiers, Command** _command)
return false; return false;
} }
// UpdateCursor
bool
ViewState::UpdateCursor()
{
return false;
}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -57,6 +57,8 @@ class ViewState {
virtual bool HandleKeyUp(uint32 key, uint32 modifiers, virtual bool HandleKeyUp(uint32 key, uint32 modifiers,
Command** _command); Command** _command);
virtual bool UpdateCursor();
inline uint32 PressedMouseButtons() const inline uint32 PressedMouseButtons() const
{ return fMouseInfo->buttons; } { return fMouseInfo->buttons; }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. All rights reserved. * Copyright 2006-2007, Haiku. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -26,6 +26,7 @@
#include "ChangePointCommand.h" #include "ChangePointCommand.h"
//#include "CloseCommand.h" //#include "CloseCommand.h"
#include "InsertPointCommand.h" #include "InsertPointCommand.h"
#include "FlipPointsCommand.h"
//#include "NewPathCommand.h" //#include "NewPathCommand.h"
#include "NudgePointsCommand.h" #include "NudgePointsCommand.h"
//#include "RemovePathCommand.h" //#include "RemovePathCommand.h"
@@ -74,6 +75,7 @@ enum {
MSG_UPDATE_SHAPE_UI = 'udsi', MSG_UPDATE_SHAPE_UI = 'udsi',
MSG_SPLIT_POINTS = 'splt', MSG_SPLIT_POINTS = 'splt',
MSG_FLIP_POINTS = 'flip',
}; };
inline const char* inline const char*
@@ -773,6 +775,11 @@ PathManipulator::ShowContextMenu(BPoint where)
item->SetEnabled(hasSelection); item->SetEnabled(hasSelection);
menu->AddItem(item); menu->AddItem(item);
message = new BMessage(MSG_FLIP_POINTS);
item = new BMenuItem("Flip", message);
item->SetEnabled(hasSelection);
menu->AddItem(item);
message = new BMessage(MSG_REMOVE_POINTS); message = new BMessage(MSG_REMOVE_POINTS);
item = new BMenuItem("Remove", message, 'A'); item = new BMenuItem("Remove", message, 'A');
item->SetEnabled(hasSelection); item->SetEnabled(hasSelection);
@@ -829,6 +836,11 @@ PathManipulator::MessageReceived(BMessage* message, Command** _command)
fSelection->Items(), fSelection->Items(),
fSelection->CountItems()); fSelection->CountItems());
break; break;
case MSG_FLIP_POINTS:
*_command = new FlipPointsCommand(fPath,
fSelection->Items(),
fSelection->CountItems());
break;
case B_SELECT_ALL: { case B_SELECT_ALL: {
*fOldSelection = *fSelection; *fOldSelection = *fSelection;
fSelection->MakeEmpty(); fSelection->MakeEmpty();
@@ -958,13 +970,12 @@ PathManipulator::HandleKeyUp(uint32 key, uint32 modifiers, Command** _command)
} }
// UpdateCursor // UpdateCursor
void bool
PathManipulator::UpdateCursor() PathManipulator::UpdateCursor()
{ {
if (fTransformBox) { if (fTransformBox)
fTransformBox->UpdateCursor(); return fTransformBox->UpdateCursor();
return;
}
const uchar* cursorData; const uchar* cursorData;
switch (fMode) { switch (fMode) {
case ADD_POINT: case ADD_POINT:
@@ -1008,6 +1019,8 @@ PathManipulator::UpdateCursor()
BCursor cursor(cursorData); BCursor cursor(cursorData);
fCanvasView->SetViewCursor(&cursor, true); fCanvasView->SetViewCursor(&cursor, true);
fCanvasView->Sync(); fCanvasView->Sync();
return true;
} }
// AttachedToView // AttachedToView
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -59,7 +59,7 @@ class PathManipulator : public Manipulator,
virtual bool HandleKeyUp(uint32 key, uint32 modifiers, virtual bool HandleKeyUp(uint32 key, uint32 modifiers,
Command** _command); Command** _command);
virtual void UpdateCursor(); virtual bool UpdateCursor();
virtual void AttachedToView(BView* view); virtual void AttachedToView(BView* view);
virtual void DetachedFromView(BView* view); virtual void DetachedFromView(BView* view);
@@ -39,6 +39,32 @@ ChangePointCommand::~ChangePointCommand()
delete[] fOldSelection; delete[] fOldSelection;
} }
// InitCheck
status_t
ChangePointCommand::InitCheck()
{
// TODO: figure out if selection changed!!!
// (this command is also used to undo changes to the selection)
// (but tracking the selection does not yet work in Icon-O-Matic)
status_t ret = PathCommand::InitCheck();
if (ret < B_OK)
return ret;
BPoint point;
BPoint pointIn;
BPoint pointOut;
bool connected;
if (!fPath->GetPointsAt(fIndex, point, pointIn, pointOut, &connected))
return B_ERROR;
if (point != fPoint || pointIn != fPointIn
|| pointOut != fPointOut || connected != fConnected)
return B_OK;
return B_ERROR;
}
// Perform // Perform
status_t status_t
ChangePointCommand::Perform() ChangePointCommand::Perform()
@@ -21,6 +21,8 @@ class ChangePointCommand : public PathCommand {
int32 count); int32 count);
virtual ~ChangePointCommand(); virtual ~ChangePointCommand();
virtual status_t InitCheck();
virtual status_t Perform(); virtual status_t Perform();
virtual status_t Undo(); virtual status_t Undo();
virtual status_t Redo(); virtual status_t Redo();
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. All rights reserved. * Copyright 2006-2007, Haiku. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -299,16 +299,19 @@ TransformBox::HandleKeyUp(uint32 key, uint32 modifiers, Command** _command)
return false; return false;
} }
// #pragma mark -
// UpdateCursor // UpdateCursor
void bool
TransformBox::UpdateCursor() TransformBox::UpdateCursor()
{ {
if (fCurrentState) if (fCurrentState) {
fCurrentState->UpdateViewCursor(fView, fMousePos); fCurrentState->UpdateViewCursor(fView, fMousePos);
return true;
}
return false;
} }
// #pragma mark -
// AttachedToView // AttachedToView
void void
TransformBox::AttachedToView(BView* view) TransformBox::AttachedToView(BView* view)
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -54,7 +54,7 @@ class TransformBox : public ChannelTransform,
virtual bool HandleKeyUp(uint32 key, uint32 modifiers, virtual bool HandleKeyUp(uint32 key, uint32 modifiers,
Command** _command); Command** _command);
virtual void UpdateCursor(); virtual bool UpdateCursor();
virtual void AttachedToView(BView* view); virtual void AttachedToView(BView* view);
virtual void DetachedFromView(BView* view); virtual void DetachedFromView(BView* view);
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006, Haiku. * Copyright 2006-2007, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -72,8 +72,8 @@ TransformCommand::InitCheck()
|| fNewXScale != fOldXScale || fNewXScale != fOldXScale
|| fNewYScale != fOldYScale)) || fNewYScale != fOldYScale))
return B_OK; return B_OK;
else
return B_NO_INIT; return B_NO_INIT;
} }
// Perform // Perform
@@ -88,30 +88,24 @@ TransformCommand::Perform()
status_t status_t
TransformCommand::Undo() TransformCommand::Undo()
{ {
status_t status = InitCheck(); _SetTransformation(fOldPivot,
if (status >= B_OK) { fOldTranslation,
_SetTransformation(fOldPivot, fOldRotation,
fOldTranslation, fOldXScale,
fOldRotation, fOldYScale);
fOldXScale, return B_OK;
fOldYScale);
}
return status;
} }
// Redo // Redo
status_t status_t
TransformCommand::Redo() TransformCommand::Redo()
{ {
status_t status = InitCheck(); _SetTransformation(fNewPivot,
if (status >= B_OK) { fNewTranslation,
_SetTransformation(fNewPivot, fNewRotation,
fNewTranslation, fNewXScale,
fNewRotation, fNewYScale);
fNewXScale, return B_OK;
fNewYScale);
}
return status;
} }
// GetName // GetName
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2007, Haiku. * Copyright 2006-2007, Haiku. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors: