* MultipleManipulatorState invalidates the area of an

added or removed Manipulator
* added a menu bar to the MainWindow
* undo/redo work from the menu now
* one can add a new path object
* the selected path will get focus for being manipulated
  (will be moved elsewhere later on...)
TODO: allow to connect paths to shapes


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18004 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2006-07-02 09:56:06 +00:00
parent 466805c501
commit 8815fed657
3 changed files with 149 additions and 6 deletions
+125 -3
View File
@@ -10,11 +10,15 @@
#include <stdio.h>
#include <Menu.h>
#include <MenuBar.h>
#include <MenuItem.h>
#include <Message.h>
#include <ScrollView.h>
#include "Document.h"
#include "CanvasView.h"
#include "CommandStack.h"
#include "IconEditorApp.h"
#include "IconView.h"
#include "PathListView.h"
@@ -34,7 +38,15 @@
#include "Style.h"
#include "StyleManager.h"
#include "VectorPath.h"
enum {
MSG_UNDO = 'undo',
MSG_REDO = 'redo',
MSG_NEW_PATH = 'nwvp',
MSG_PATH_SELECTED = 'vpsl',
};
// constructor
MainWindow::MainWindow(IconEditorApp* app, Document* document)
: BWindow(BRect(50, 50, 661, 661), "Icon-O-Matic",
@@ -50,6 +62,8 @@ MainWindow::MainWindow(IconEditorApp* app, Document* document)
MainWindow::~MainWindow()
{
delete fState;
fDocument->CommandStack()->RemoveObserver(this);
}
// #pragma mark -
@@ -58,11 +72,40 @@ MainWindow::~MainWindow()
void
MainWindow::MessageReceived(BMessage* message)
{
if (!fDocument->WriteLock())
return;
switch (message->what) {
case MSG_UNDO:
fDocument->CommandStack()->Undo();
break;
case MSG_REDO:
fDocument->CommandStack()->Redo();
break;
// TODO: use an AddPathCommand and listen to
// selection in CanvasView to add a manipulator
case MSG_NEW_PATH: {
VectorPath* path = new VectorPath();
fDocument->Icon()->Paths()->AddPath(path);
break;
}
case MSG_PATH_SELECTED: {
VectorPath* path;
if (message->FindPointer("path", (void**)&path) == B_OK) {
PathManipulator* pathManipulator = new PathManipulator(path);
fState->DeleteManipulators();
fState->AddManipulator(pathManipulator);
}
break;
}
default:
BWindow::MessageReceived(message);
}
fDocument->WriteUnlock();
}
// QuitRequested
@@ -76,6 +119,38 @@ MainWindow::QuitRequested()
return false;
}
// #pragma mark -
// ObjectChanged
void
MainWindow::ObjectChanged(const Observable* object)
{
if (!fDocument)
return;
if (!Lock())
return;
if (object == fDocument->CommandStack()) {
// relable Undo item and update enabled status
BString label("Undo");
fUndoMI->SetEnabled(fDocument->CommandStack()->GetUndoName(label));
if (fUndoMI->IsEnabled())
fUndoMI->SetLabel(label.String());
else
fUndoMI->SetLabel("<nothing to undo>");
// relable Redo item and update enabled status
label.SetTo("Redo");
fRedoMI->SetEnabled(fDocument->CommandStack()->GetRedoName(label));
if (fRedoMI->IsEnabled())
fRedoMI->SetLabel(label.String());
else
fRedoMI->SetLabel("<nothing to redo>");
}
Unlock();
}
// #pragma mark -
// _Init
@@ -104,6 +179,8 @@ MainWindow::_Init()
// fIconPreview48->SetIcon(fDocument->Icon());
fIconPreview64->SetIcon(fDocument->Icon());
fDocument->CommandStack()->AddObserver(this);
// TODO: for testing only:
MultipleManipulatorState* state = new MultipleManipulatorState(fCanvasView);
fCanvasView->SetState(state);
@@ -169,12 +246,20 @@ MainWindow::_Init()
BView*
MainWindow::_CreateGUI(BRect bounds)
{
BRect menuFrame = bounds;
menuFrame.bottom = menuFrame.top + 15;
BMenuBar* menuBar = _CreateMenuBar(menuFrame);
AddChild(menuBar);
menuBar->ResizeToPreferred();
bounds.top = menuBar->Frame().bottom + 1;
BView* bg = new BView(bounds, "bg", B_FOLLOW_ALL, 0);
bg->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fSwatchGroup = new SwatchGroup(BRect(0, 0, 100, 100));
bounds.top = fSwatchGroup->Frame().bottom + 1;
fCanvasView = new CanvasView(bounds);
bounds.left = fSwatchGroup->Frame().right + 5;
@@ -202,7 +287,8 @@ MainWindow::_CreateGUI(BRect bounds)
bounds.right = bounds.left + 100;
bounds.bottom = fCanvasView->Frame().top - 5.0;
fPathListView = new PathListView(bounds, "path list view");
fPathListView = new PathListView(bounds, "path list view",
new BMessage(MSG_PATH_SELECTED), this);
bounds.OffsetBy(bounds.Width() + 6 + B_V_SCROLL_BAR_WIDTH, 0);
fShapeListView = new ShapeListView(bounds, "shape list view");
@@ -230,3 +316,39 @@ MainWindow::_CreateGUI(BRect bounds)
return bg;
}
// _CreateMenuBar
BMenuBar*
MainWindow::_CreateMenuBar(BRect frame)
{
BMenuBar* menuBar = new BMenuBar(frame, "main menu");
BMenu* fileMenu = new BMenu("File");
BMenu* editMenu = new BMenu("Edit");
BMenu* pathMenu = new BMenu("Path");
BMenu* styleMenu = new BMenu("Style");
BMenu* shapeMenu = new BMenu("Shape");
menuBar->AddItem(fileMenu);
menuBar->AddItem(editMenu);
menuBar->AddItem(pathMenu);
menuBar->AddItem(styleMenu);
menuBar->AddItem(shapeMenu);
// Edit
fUndoMI = new BMenuItem("<nothing to undo>",
new BMessage(MSG_UNDO), 'Z');
fRedoMI = new BMenuItem("<nothing to redo>",
new BMessage(MSG_REDO), 'Z', B_SHIFT_KEY);
fUndoMI->SetEnabled(false);
fRedoMI->SetEnabled(false);
editMenu->AddItem(fUndoMI);
editMenu->AddItem(fRedoMI);
// Path
pathMenu->AddItem(new BMenuItem("New", new BMessage(MSG_NEW_PATH)));
return menuBar;
}
+15 -3
View File
@@ -11,6 +11,10 @@
#include <Window.h>
#include "Observer.h"
class BMenuBar;
class BMenuItem;
class CanvasView;
class Document;
class IconEditorApp;
@@ -18,9 +22,10 @@ class IconView;
class PathListView;
class ShapeListView;
class SwatchGroup;
class ViewState;
class MultipleManipulatorState;
class MainWindow : public BWindow {
class MainWindow : public BWindow,
public Observer {
public:
MainWindow(IconEditorApp* app,
Document* document);
@@ -30,13 +35,20 @@ class MainWindow : public BWindow {
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
// Observer interface
virtual void ObjectChanged(const Observable* object);
private:
void _Init();
BView* _CreateGUI(BRect frame);
BMenuBar* _CreateMenuBar(BRect frame);
IconEditorApp* fApp;
Document* fDocument;
BMenuItem* fUndoMI;
BMenuItem* fRedoMI;
CanvasView* fCanvasView;
SwatchGroup* fSwatchGroup;
@@ -48,7 +60,7 @@ class MainWindow : public BWindow {
PathListView* fPathListView;
ShapeListView* fShapeListView;
// TODO: for testing only...
ViewState* fState;
MultipleManipulatorState* fState;
};
#endif // MAIN_WINDOW_H
@@ -199,6 +199,7 @@ MultipleManipulatorState::AddManipulator(Manipulator* manipulator)
if (fManipulators.AddItem((void*)manipulator)) {
manipulator->AttachedToView(fView);
fView->Invalidate(manipulator->Bounds());
return true;
}
return false;
@@ -213,6 +214,9 @@ MultipleManipulatorState::RemoveManipulator(int32 index)
if (manipulator == fCurrentManipulator)
fCurrentManipulator = NULL;
if (manipulator)
fView->Invalidate(manipulator->Bounds());
return manipulator;
}
@@ -220,15 +224,20 @@ MultipleManipulatorState::RemoveManipulator(int32 index)
void
MultipleManipulatorState::DeleteManipulators()
{
BRect dirty(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN);
int32 count = fManipulators.CountItems();
for (int32 i = 0; i < count; i++) {
Manipulator* m = (Manipulator*)fManipulators.ItemAtFast(i);
dirty = dirty | m->Bounds();
m->DetachedFromView(fView);
delete m;
}
fManipulators.MakeEmpty();
fCurrentManipulator = NULL;
fPreviousManipulator = NULL;
fView->Invalidate(dirty);
}
// CountManipulators