From 8815fed657af2ded0928525f76d5249c65a936a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 2 Jul 2006 09:56:06 +0000 Subject: [PATCH] * 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 --- src/apps/icon-o-matic/MainWindow.cpp | 128 +++++++++++++++++- src/apps/icon-o-matic/MainWindow.h | 18 ++- .../stateview/MultipleManipulatorState.cpp | 9 ++ 3 files changed, 149 insertions(+), 6 deletions(-) diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index 1cb141b86e..3511a667fb 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -10,11 +10,15 @@ #include +#include +#include +#include #include #include #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(""); + + // 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(""); + } + + 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("", + new BMessage(MSG_UNDO), 'Z'); + fRedoMI = new BMenuItem("", + 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; +} + diff --git a/src/apps/icon-o-matic/MainWindow.h b/src/apps/icon-o-matic/MainWindow.h index f7f0e1c873..fad4a1c912 100644 --- a/src/apps/icon-o-matic/MainWindow.h +++ b/src/apps/icon-o-matic/MainWindow.h @@ -11,6 +11,10 @@ #include +#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 diff --git a/src/apps/icon-o-matic/generic/gui/stateview/MultipleManipulatorState.cpp b/src/apps/icon-o-matic/generic/gui/stateview/MultipleManipulatorState.cpp index b0c1af938e..30623aa57b 100644 --- a/src/apps/icon-o-matic/generic/gui/stateview/MultipleManipulatorState.cpp +++ b/src/apps/icon-o-matic/generic/gui/stateview/MultipleManipulatorState.cpp @@ -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