2 * Copyright 2006-2012, Haiku.
3 * Distributed under the terms of the MIT License.
6 * Stephan Aßmus <superstippi@gmx.de>
9 #include "SwatchGroup.h"
13 #include "support_ui.h"
14 #include "ui_defines.h"
17 #include "AlphaSlider.h"
18 #include "ColorField.h"
19 #include "ColorPickerPanel.h"
20 #include "ColorSlider.h"
21 #include "CurrentColor.h"
23 #include "SwatchView.h"
27 MSG_SET_COLOR
= 'stcl',
28 MSG_COLOR_PICKER
= 'clpk',
29 MSG_ALPHA_SLIDER
= 'alps',
33 #define SWATCH_VIEW_WIDTH 20
34 #define SWATCH_VIEW_HEIGHT 15
37 SwatchGroup::SwatchGroup(BRect frame
)
39 BView(frame
, "style view", B_FOLLOW_NONE
, 0),
42 fIgnoreNotifications(false),
44 fColorPickerPanel(NULL
),
45 fColorPickerMode(H_SELECTED
),
46 fColorPickerFrame(100.0, 100.0, 200.0, 200.0)
48 frame
= BRect(0, 0, 100, 15);
49 fTopSwatchViews
= new Group(frame
, "top swatch group");
50 fBottomSwatchViews
= new Group(frame
, "bottom swatch group");
52 // create swatch views with rainbow default palette
61 for (int32 i
= 0; i
< 20; i
++) {
63 h
= ((float)i
/ 9.0) * 6.0;
65 h
= ((float)(i
- 9) / 10.0) * 6.0;
69 HSV_to_RGB(h
, s
, v
, r
, g
, b
);
70 color
.red
= (uint8
)(255.0 * r
);
71 color
.green
= (uint8
)(255.0 * g
);
72 color
.blue
= (uint8
)(255.0 * b
);
73 fSwatchViews
[i
] = new SwatchView("swatch", new BMessage(MSG_SET_COLOR
),
74 this, color
, SWATCH_VIEW_WIDTH
, SWATCH_VIEW_HEIGHT
);
76 fSwatchViews
[i
]->SetResizingMode(B_FOLLOW_LEFT
| B_FOLLOW_TOP
);
79 fTopSwatchViews
->AddChild(fSwatchViews
[i
]);
81 fBottomSwatchViews
->AddChild(fSwatchViews
[i
]);
84 // create current color swatch view
85 fCurrentColorSV
= new SwatchView("current swatch",
86 new BMessage(MSG_COLOR_PICKER
), this, color
, 28.0, 28.0);
88 // When the color of this swatch changes via drag&drop, we want to
89 // adopt it as current color.
90 fCurrentColorSV
->SetDroppedMessage(new BMessage(MSG_SET_COLOR
));
92 // create color field and slider
93 fColorField
= new ColorField(BPoint(0.0, 0.0), H_SELECTED
,
95 fColorSlider
= new ColorSlider(BPoint(0.0, 0.0), H_SELECTED
,
96 1.0, 1.0, B_HORIZONTAL
);
97 fAlphaSlider
= new AlphaSlider(B_HORIZONTAL
,
98 new BMessage(MSG_ALPHA_SLIDER
));
101 fTopSwatchViews
->SetSpacing(0, 0);
102 fTopSwatchViews
->ResizeToPreferred();
103 fTopSwatchViews
->SetResizingMode(B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
);
104 fBottomSwatchViews
->SetSpacing(0, 0);
105 fBottomSwatchViews
->ResizeToPreferred();
106 fBottomSwatchViews
->SetResizingMode(B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
);
108 float paletteHeight
= fBottomSwatchViews
->Frame().Height()
109 + fTopSwatchViews
->Frame().Height() + 1;
111 fTopSwatchViews
->MoveTo(paletteHeight
+ 2, 4);
112 fBottomSwatchViews
->MoveTo(paletteHeight
+ 2,
113 fTopSwatchViews
->Frame().bottom
+ 1);
115 fCurrentColorSV
->MoveTo(0, fTopSwatchViews
->Frame().top
);
116 fCurrentColorSV
->ResizeTo(paletteHeight
, paletteHeight
);
117 fCurrentColorSV
->SetResizingMode(B_FOLLOW_LEFT
| B_FOLLOW_TOP
);
119 float width
= fTopSwatchViews
->Frame().right
120 - fCurrentColorSV
->Frame().left
;
122 fColorField
->ResizeTo(width
, 40);
123 fColorField
->FrameResized(width
, 40);
124 fColorSlider
->ResizeTo(width
, 11);
125 fColorSlider
->FrameResized(width
, 11);
126 fAlphaSlider
->ResizeTo(width
, 11);
127 fAlphaSlider
->FrameResized(width
, 11);
129 fColorField
->MoveTo(0, fBottomSwatchViews
->Frame().bottom
+ 3);
130 fColorSlider
->MoveTo(0, fColorField
->Frame().bottom
+ 1);
131 fAlphaSlider
->MoveTo(0, fColorSlider
->Frame().bottom
+ 1);
132 fAlphaSlider
->SetResizingMode(B_FOLLOW_LEFT_RIGHT
| B_FOLLOW_TOP
);
135 ResizeTo(width
, fAlphaSlider
->Frame().bottom
+ 4);
136 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
139 AddChild(fCurrentColorSV
);
140 AddChild(fTopSwatchViews
);
141 AddChild(fBottomSwatchViews
);
142 AddChild(fColorField
);
143 AddChild(fColorSlider
);
144 AddChild(fAlphaSlider
);
148 SwatchGroup::~SwatchGroup()
150 SetCurrentColor(NULL
);
155 SwatchGroup::ObjectChanged(const Observable
* object
)
157 if (object
!= fCurrentColor
|| fIgnoreNotifications
)
160 rgb_color color
= fCurrentColor
->Color();
163 RGB_to_HSV(color
.red
/ 255.0, color
.green
/ 255.0, color
.blue
/ 255.0,
166 _SetColor(h
, s
, v
, color
.alpha
);
174 SwatchGroup::AttachedToWindow()
176 fColorField
->SetTarget(this);
177 fColorSlider
->SetTarget(this);
178 fAlphaSlider
->SetTarget(this);
183 SwatchGroup::MessageReceived(BMessage
* message
)
185 switch (message
->what
) {
189 if (restore_color_from_message(message
, color
) == B_OK
) {
190 // TODO: fix color picker panel to respect alpha
191 if (message
->HasRect("panel frame"))
192 color
.alpha
= fAlphaSlider
->Value();
194 if (fCurrentColor
!= NULL
)
195 fCurrentColor
->SetColor(color
);
197 // if message contains these fields,
198 // then it comes from the color picker panel.
199 // it also means the panel has died.
201 SelectedColorMode mode
;
202 if (message
->FindRect("panel frame", &frame
) == B_OK
203 && message
->FindInt32("panel mode", (int32
*)&mode
) == B_OK
) {
204 // message came from the color picker panel
205 // we remember the settings of the panel for later
206 fColorPickerFrame
= frame
;
207 fColorPickerMode
= mode
;
208 // color picker panel has quit
209 fColorPickerPanel
= NULL
;
214 case MSG_COLOR_FIELD
:
216 // get h from color slider
217 float h
= ((255 - fColorSlider
->Value()) / 255.0) * 6.0;
219 // s and v are comming from the message
220 if (message
->FindFloat("value", &s
) == B_OK
221 && message
->FindFloat("value", 1, &v
) == B_OK
) {
222 _SetColor(h
, s
, v
, fAlphaSlider
->Value());
227 case MSG_COLOR_SLIDER
:
231 fColorSlider
->GetOtherValues(&s
, &v
);
232 // h is comming from the message
233 if (message
->FindFloat("value", &h
) == B_OK
)
234 _SetColor(h
, s
, v
, fAlphaSlider
->Value());
238 case MSG_ALPHA_SLIDER
:
240 float h
= (1.0 - (float)fColorSlider
->Value() / 255.0) * 6;
242 fColorSlider
->GetOtherValues(&s
, &v
);
243 _SetColor(h
, s
, v
, fAlphaSlider
->Value());
247 case MSG_COLOR_PICKER
:
250 if (restore_color_from_message(message
, color
) < B_OK
)
253 if (fColorPickerPanel
== NULL
) {
254 fColorPickerPanel
= new ColorPickerPanel(fColorPickerFrame
,
255 color
, fColorPickerMode
, Window(),
256 new BMessage(MSG_SET_COLOR
), this);
257 fColorPickerPanel
->Show();
259 if (fColorPickerPanel
->Lock()) {
260 fColorPickerPanel
->SetColor(color
);
261 fColorPickerPanel
->Activate();
262 fColorPickerPanel
->Unlock();
269 BView::MessageReceived(message
);
279 SwatchGroup::SetCurrentColor(CurrentColor
* color
)
281 if (fCurrentColor
== color
)
284 if (fCurrentColor
!= NULL
)
285 fCurrentColor
->RemoveObserver(this);
287 fCurrentColor
= color
;
289 if (fCurrentColor
!= NULL
) {
290 fCurrentColor
->AddObserver(this);
292 ObjectChanged(fCurrentColor
);
301 SwatchGroup::_SetColor(rgb_color color
)
303 fCurrentColorSV
->SetColor(color
);
308 SwatchGroup::_SetColor(float h
, float s
, float v
, uint8 a
)
313 HSV_to_RGB(h
, s
, v
, r
, g
, b
);
316 color
.red
= (uint8
)(r
* 255.0);
317 color
.green
= (uint8
)(g
* 255.0);
318 color
.blue
= (uint8
)(b
* 255.0);
321 if (!fColorField
->IsTracking()) {
322 fColorField
->SetFixedValue(h
);
323 fColorField
->SetMarkerToColor(color
);
325 if (!fColorSlider
->IsTracking()) {
326 fColorSlider
->SetOtherValues(s
, v
);
327 fColorSlider
->SetValue(255 - (int32
)((h
/ 6.0) * 255.0 + 0.5));
329 if (!fAlphaSlider
->IsTracking()) {
330 fAlphaSlider
->SetColor(color
);
331 fAlphaSlider
->SetValue(a
);
334 fIgnoreNotifications
= true;
337 fCurrentColor
->SetColor(color
);
340 fIgnoreNotifications
= false;