diff --git a/src/apps/icon-o-matic/Jamfile b/src/apps/icon-o-matic/Jamfile index a04ea38e6b..5196f802ea 100644 --- a/src/apps/icon-o-matic/Jamfile +++ b/src/apps/icon-o-matic/Jamfile @@ -131,6 +131,7 @@ Application Icon-O-Matic : RemoveShapesCommand.cpp RemoveTransformersCommand.cpp # style + CurrentColor.cpp Gradient.cpp Style.cpp StyleManager.cpp diff --git a/src/apps/icon-o-matic/MainWindow.cpp b/src/apps/icon-o-matic/MainWindow.cpp index 3eadcf73d7..893979d41b 100644 --- a/src/apps/icon-o-matic/MainWindow.cpp +++ b/src/apps/icon-o-matic/MainWindow.cpp @@ -19,6 +19,7 @@ #include "Document.h" #include "CanvasView.h" #include "CommandStack.h" +#include "CurrentColor.h" #include "IconObjectListView.h" #include "IconEditorApp.h" #include "IconView.h" @@ -121,6 +122,13 @@ case MSG_NEW_STYLE: { StyleManager::Default()->AddStyle(style); break; } +case MSG_STYLE_SELECTED: { + Style* style; + if (message->FindPointer("style", (void**)&style) < B_OK) + style = NULL; + fSwatchGroup->SetCurrentStyle(style); + break; +} // TODO: use an AddShapeCommand case MSG_NEW_SHAPE: { Shape* shape = new Shape(StyleManager::Default()->StyleAt(0)); @@ -247,6 +255,8 @@ MainWindow::_Init() fDocument->CommandStack()->AddObserver(this); + fSwatchGroup->SetCurrentColor(CurrentColor::Default()); + // TODO: for testing only: MultipleManipulatorState* state = new MultipleManipulatorState(fCanvasView); fCanvasView->SetState(state); diff --git a/src/apps/icon-o-matic/generic/gui/SwatchView.cpp b/src/apps/icon-o-matic/generic/gui/SwatchView.cpp index a0dc391bf3..929d18fcc9 100644 --- a/src/apps/icon-o-matic/generic/gui/SwatchView.cpp +++ b/src/apps/icon-o-matic/generic/gui/SwatchView.cpp @@ -27,7 +27,7 @@ SwatchView::SwatchView(const char* name, BMessage* message, BHandler* target, rgb_color color, float width, float height) - : BView(BRect(0.0, 0.0, 23.0, 17.0), name, + : BView(BRect(0.0, 0.0, width, height), name, B_FOLLOW_NONE, B_WILL_DRAW), fColor(color), fTrackingStart(-1.0, -1.0), diff --git a/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.cpp b/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.cpp index 2384af4e23..031478893a 100644 --- a/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.cpp +++ b/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.cpp @@ -33,11 +33,13 @@ enum { // constructor ColorPickerPanel::ColorPickerPanel(BRect frame, rgb_color color, selected_color_mode mode, - BMessage* message, BWindow* target) + BWindow* window, + BMessage* message, BHandler* target) : Panel(frame, "Pick Color", B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL, B_ASYNCHRONOUS_CONTROLS | B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_NOT_CLOSABLE), + fWindow(window), fMessage(message), fTarget(target) { @@ -106,8 +108,8 @@ ColorPickerPanel::ColorPickerPanel(BRect frame, rgb_color color, SetDefaultButton(defaultButton); - if (fTarget) - AddToSubset(fTarget); + if (fWindow) + AddToSubset(fWindow); else SetFeel(B_FLOATING_APP_WINDOW_FEEL); @@ -135,8 +137,7 @@ ColorPickerPanel::MessageReceived(BMessage* message) case MSG_CANCEL: case MSG_DONE: { BMessage msg('PSTE'); - BLooper* looper = fTarget ? static_cast(fTarget) - : static_cast(be_app); + BLooper* looper = fTarget ? fTarget->Looper() : be_app; if (fMessage) msg = *fMessage; if (message->what == MSG_DONE) @@ -144,7 +145,7 @@ ColorPickerPanel::MessageReceived(BMessage* message) msg.AddRect("panel frame", Frame()); msg.AddInt32("panel mode", fColorPickerView->Mode()); msg.AddBool("begin", true); - looper->PostMessage(&msg); + looper->PostMessage(&msg, fTarget); PostMessage(B_QUIT_REQUESTED); break; } diff --git a/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.h b/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.h index f1a095be0b..05cdb9fba2 100644 --- a/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.h +++ b/src/apps/icon-o-matic/generic/gui/panel/color_picker/ColorPickerPanel.h @@ -19,8 +19,9 @@ class ColorPickerPanel : public Panel { rgb_color color, selected_color_mode mode = H_SELECTED, + BWindow* window = NULL, BMessage* message = NULL, - BWindow* target = NULL); + BHandler* target = NULL); virtual ~ColorPickerPanel(); // Panel @@ -33,8 +34,9 @@ class ColorPickerPanel : public Panel { private: ColorPickerView* fColorPickerView; + BWindow* fWindow; BMessage* fMessage; - BWindow* fTarget; + BHandler* fTarget; }; #endif // COLOR_PICKER_PANEL_H diff --git a/src/apps/icon-o-matic/gui/SwatchGroup.cpp b/src/apps/icon-o-matic/gui/SwatchGroup.cpp index 9a7a560e2d..5d34726d49 100644 --- a/src/apps/icon-o-matic/gui/SwatchGroup.cpp +++ b/src/apps/icon-o-matic/gui/SwatchGroup.cpp @@ -8,21 +8,39 @@ #include "SwatchGroup.h" +#include + +#include "support_ui.h" #include "ui_defines.h" #include "rgb_hsv.h" #include "ColorField.h" +#include "ColorPickerPanel.h" #include "ColorSlider.h" +#include "CurrentColor.h" #include "Group.h" +#include "Style.h" #include "SwatchView.h" enum { - MSG_SET_COLOR = 'stcl', + MSG_SET_COLOR = 'stcl', + MSG_COLOR_PICKER = 'clpk', }; +#define SWATCH_VIEW_WIDTH 20 +#define SWATCH_VIEW_HEIGHT 15 + // constructor SwatchGroup::SwatchGroup(BRect frame) - : BView(frame, "style view", B_FOLLOW_NONE, 0) + : BView(frame, "style view", B_FOLLOW_NONE, 0), + + fCurrentColor(NULL), + fCurrentStyle(NULL), + fIgnoreNotifications(false), + + fColorPickerPanel(NULL), + fColorPickerMode(H_SELECTED), + fColorPickerFrame(100.0, 100.0, 200.0, 200.0) { frame = BRect(0, 0, 100, 15); fTopSwatchViews = new Group(frame, "top swatch group"); @@ -47,36 +65,46 @@ SwatchGroup::SwatchGroup(BRect frame) color.green = (uint8)(255.0 * g); color.blue = (uint8)(255.0 * b); fSwatchViews[i] = new SwatchView("swatch", new BMessage(MSG_SET_COLOR), - this, color, 17.0, 14.0); - + this, color, + SWATCH_VIEW_WIDTH, + SWATCH_VIEW_HEIGHT); if (i < 10) fTopSwatchViews->AddChild(fSwatchViews[i]); else fBottomSwatchViews->AddChild(fSwatchViews[i]); } - // create color field and slider - color = kBlack; + // crrate current color swatch view + fCurrentColorSV = new SwatchView("current swatch", + new BMessage(MSG_COLOR_PICKER), + this, color, 28.0, 28.0); + // create color field and slider fColorField = new ColorField(BPoint(0.0, 0.0), H_SELECTED, 1.0, B_HORIZONTAL); fColorSlider = new ColorSlider(BPoint(0.0, 0.0), H_SELECTED, 1.0, 1.0, B_HORIZONTAL); - fColorField->SetMarkerToColor(color); - fColorSlider->SetMarkerToColor(color); // layout gui fTopSwatchViews->SetSpacing(0, 0); fTopSwatchViews->ResizeToPreferred(); fBottomSwatchViews->SetSpacing(0, 0); fBottomSwatchViews->ResizeToPreferred(); - float width = fTopSwatchViews->Frame().Width(); + + fTopSwatchViews->MoveTo(30, 4); + fBottomSwatchViews->MoveTo(30, fTopSwatchViews->Frame().bottom + 1); + + fCurrentColorSV->MoveTo(0, fTopSwatchViews->Frame().top); + fCurrentColorSV->ResizeTo(28, fBottomSwatchViews->Frame().bottom + - fTopSwatchViews->Frame().top); + + float width = fTopSwatchViews->Frame().right + - fCurrentColorSV->Frame().left; + fColorField->ResizeTo(width, 40); fColorField->FrameResized(width, 40); fColorSlider->ResizeTo(width, 15); fColorSlider->FrameResized(width, 40); - fTopSwatchViews->MoveTo(0, 4); - fBottomSwatchViews->MoveTo(0, fTopSwatchViews->Frame().bottom + 1); fColorField->MoveTo(0, fBottomSwatchViews->Frame().bottom + 3); fColorSlider->MoveTo(0, fColorField->Frame().bottom + 1); @@ -85,15 +113,207 @@ SwatchGroup::SwatchGroup(BRect frame) SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); // add views + AddChild(fCurrentColorSV); AddChild(fTopSwatchViews); AddChild(fBottomSwatchViews); AddChild(fColorField); AddChild(fColorSlider); - } // destructor SwatchGroup::~SwatchGroup() { + SetCurrentColor(NULL); + SetCurrentStyle(NULL); } +// ObjectChanged +void +SwatchGroup::ObjectChanged(const Observable* object) +{ + if (object == fCurrentColor) { + rgb_color color = fCurrentColor->Color(); + + if (!fIgnoreNotifications) { + float h, s, v; + RGB_to_HSV(color.red / 255.0, + color.green / 255.0, + color.blue / 255.0, + h, s, v); + + _SetColor(h, s, v); + } + + if (fCurrentStyle && !fCurrentStyle->Gradient()) { + fCurrentStyle->SetColor(color); + } + } +} + +// #pragma mark - + +// AttachedToWindow +void +SwatchGroup::AttachedToWindow() +{ + fColorField->SetTarget(this); + fColorSlider->SetTarget(this); +} + +// MessageReceived +void +SwatchGroup::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_SET_COLOR: { + rgb_color color; + if (restore_color_from_message(message, color) == B_OK) { + if (fCurrentColor) + fCurrentColor->SetColor(color); + } + // if message contains these fields, + // then it comes from the color picker panel. + // it also means the panel has died. + BRect frame; + selected_color_mode mode; + if (message->FindRect("panel frame", &frame) == B_OK + && message->FindInt32("panel mode", (int32*)&mode) == B_OK) { + // message came from the color picker panel + // we remember the settings of the panel for later + fColorPickerFrame = frame; + fColorPickerMode = mode; + // color picker panel has quit + fColorPickerPanel = NULL; + } + break; + } + case MSG_COLOR_FIELD: { + // get h from color slider + float h = ((255 - fColorSlider->Value()) / 255.0) * 6.0; + float s, v; + // s and v are comming from the message + if (message->FindFloat("value", &s) >= B_OK + && message->FindFloat("value", 1, &v) >= B_OK) { + + _SetColor(h, s, v); + } + break; + } + case MSG_COLOR_SLIDER: { + float h; + float s, v; + fColorSlider->GetOtherValues(&s, &v); + // h is comming from the message + if (message->FindFloat("value", &h) >= B_OK) { + + _SetColor(h, s, v); + } + break; + } + + case MSG_COLOR_PICKER: { + rgb_color color; + if (restore_color_from_message(message, color) < B_OK) + break; + if (!fColorPickerPanel) { + fColorPickerPanel + = new ColorPickerPanel(fColorPickerFrame, + color, + fColorPickerMode, + Window(), + new BMessage(MSG_SET_COLOR), + this); + fColorPickerPanel->Show(); + } else { + if (fColorPickerPanel->Lock()) { + fColorPickerPanel->Activate(); + fColorPickerPanel->Unlock(); + } + } + break; + } + + default: + BView::MessageReceived(message); + break; + } +} + +// #pragma mark - + +// SetCurrentColor +void +SwatchGroup::SetCurrentColor(CurrentColor* color) +{ + if (fCurrentColor == color) + return; + + if (fCurrentColor) + fCurrentColor->RemoveObserver(this); + + fCurrentColor = color; + + if (fCurrentColor) { + fCurrentColor->AddObserver(this); + + _SetColor(fCurrentColor->Color()); + } +} + +// SetCurrentStyle +void +SwatchGroup::SetCurrentStyle(Style* style) +{ + if (fCurrentStyle == style) + return; + + if (fCurrentStyle) + fCurrentStyle->Release(); + + fCurrentStyle = style; + + if (fCurrentStyle) { + fCurrentStyle->Acquire(); + + if (fCurrentColor && !fCurrentStyle->Gradient()) + fCurrentColor->SetColor(fCurrentStyle->Color()); + } +} + +// #pragma mark - + +// _SetColor +void +SwatchGroup::_SetColor(rgb_color color) +{ + fCurrentColorSV->SetColor(color); +} + +// _SetColor +void +SwatchGroup::_SetColor(float h, float s, float v) +{ + float r, g, b; + HSV_to_RGB(h, s, v, r, g, b); + + rgb_color color; + color.red = (uint8)(r * 255.0); + color.green = (uint8)(g * 255.0); + color.blue = (uint8)(b * 255.0); + color.alpha = 255; + + if (!fColorField->IsTracking()) { + fColorField->SetFixedValue(h); + fColorField->SetMarkerToColor(color); + } + if (!fColorSlider->IsTracking()) { + fColorSlider->SetOtherValues(s, v); + fColorSlider->SetValue(255 - (int32)((h / 6.0) * 255.0 + 0.5)); + } + + fIgnoreNotifications = true; + if (fCurrentColor) + fCurrentColor->SetColor(color); + _SetColor(color); + fIgnoreNotifications = false; +} diff --git a/src/apps/icon-o-matic/gui/SwatchGroup.h b/src/apps/icon-o-matic/gui/SwatchGroup.h index 21ef57b459..bdeaf7bf1e 100644 --- a/src/apps/icon-o-matic/gui/SwatchGroup.h +++ b/src/apps/icon-o-matic/gui/SwatchGroup.h @@ -11,17 +11,38 @@ #include +#include "selected_color_mode.h" + +#include "Observer.h" + class ColorField; +class ColorPickerPanel; class ColorSlider; +class CurrentColor; class Group; +class Style; class SwatchView; -class SwatchGroup : public BView { +class SwatchGroup : public BView, + public Observer { public: SwatchGroup(BRect frame); virtual ~SwatchGroup(); + // Observer interface + virtual void ObjectChanged(const Observable* object); + + // BView interface + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + + // SwatchGroup + void SetCurrentColor(CurrentColor* color); + void SetCurrentStyle(Style* style); + private: + void _SetColor(rgb_color color); + void _SetColor(float h, float s, float v); SwatchView* fCurrentColorSV; SwatchView* fSwatchViews[20]; @@ -30,6 +51,14 @@ class SwatchGroup : public BView { Group* fTopSwatchViews; Group* fBottomSwatchViews; + + CurrentColor* fCurrentColor; + Style* fCurrentStyle; + bool fIgnoreNotifications; + + ColorPickerPanel* fColorPickerPanel; + selected_color_mode fColorPickerMode; + BRect fColorPickerFrame; }; #endif // SWATCH_GROUP_H diff --git a/src/apps/icon-o-matic/style/CurrentColor.cpp b/src/apps/icon-o-matic/style/CurrentColor.cpp new file mode 100644 index 0000000000..d506469418 --- /dev/null +++ b/src/apps/icon-o-matic/style/CurrentColor.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#include "CurrentColor.h" + +#include + +#include + +#include "ui_defines.h" + +// init global CurrentColor instance +CurrentColor +CurrentColor::fDefaultInstance; + + +// constructor +CurrentColor::CurrentColor() + : Observable(), + fColor(kBlack) +{ +} + +// destructor +CurrentColor::~CurrentColor() +{ +} + +// Default +CurrentColor* +CurrentColor::Default() +{ + return &fDefaultInstance; +} + +// SetColor +void +CurrentColor::SetColor(rgb_color color) +{ + if ((uint32&)fColor == (uint32&)color) + return; + + fColor = color; + Notify(); +} + diff --git a/src/apps/icon-o-matic/style/CurrentColor.h b/src/apps/icon-o-matic/style/CurrentColor.h new file mode 100644 index 0000000000..8b3000fcb7 --- /dev/null +++ b/src/apps/icon-o-matic/style/CurrentColor.h @@ -0,0 +1,33 @@ +/* + * Copyright 2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus + */ + +#ifndef CURRENT_COLOR_H +#define CURRENT_COLOR_H + +#include + +#include "Observable.h" + +class CurrentColor : public Observable { + public: + CurrentColor(); + virtual ~CurrentColor(); + + static CurrentColor* Default(); + + void SetColor(rgb_color color); + inline rgb_color Color() const + { return fColor; } + + private: + rgb_color fColor; + + static CurrentColor fDefaultInstance; +}; + +#endif // CURRENT_COLOR_H