2 * Copyright 2001-2013 Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
6 * Alexandre Deckner, alex@zappotek.com
7 * Axel Dörfler, axeld@pinc-software.de
9 * Marc Flerackers, mflerackers@androme.be
10 * John Scipione, jscipione@gmail.com
13 /** BColorControl displays a palette of selectable colors. */
15 #include <ColorControl.h>
24 #include <ControlLook.h>
26 #include <TextControl.h>
29 #include <SystemCatalog.h>
32 using BPrivate::gSystemCatalog
;
34 #include <binary_compatibility/Interface.h>
37 #undef B_TRANSLATION_CONTEXT
38 #define B_TRANSLATION_CONTEXT "ColorControl"
40 static const uint32 kMsgColorEntered
= 'ccol';
41 static const float kMinCellSize
= 6.0f
;
42 static const float kSelectorPenSize
= 2.0f
;
43 static const float kSelectorSize
= 4.0f
;
44 static const float kSelectorHSpacing
= 2.0f
;
45 static const float kTextFieldsHSpacing
= 6.0f
;
46 static const float kDefaultFontSize
= 12.0f
;
47 static const float kBevelSpacing
= 2.0f
;
48 static const uint32 kRampCount
= 4;
51 BColorControl::BColorControl(BPoint leftTop
, color_control_layout layout
,
52 float cellSize
, const char* name
, BMessage
* message
, bool bufferedDrawing
)
54 BControl(BRect(leftTop
, leftTop
), name
, NULL
, message
,
55 B_FOLLOW_LEFT
| B_FOLLOW_TOP
, B_WILL_DRAW
| B_NAVIGABLE
)
57 _InitData(layout
, cellSize
, bufferedDrawing
, NULL
);
61 BColorControl::BColorControl(BMessage
* data
)
69 data
->FindInt32("_layout", &layout
);
70 data
->FindFloat("_csize", &cellSize
);
71 data
->FindBool("_use_off", &useOffscreen
);
73 _InitData((color_control_layout
)layout
, cellSize
, useOffscreen
, data
);
77 BColorControl::~BColorControl()
84 BColorControl::_InitData(color_control_layout layout
, float size
,
85 bool useOffscreen
, BMessage
* data
)
87 fPaletteMode
= BScreen(B_MAIN_SCREEN_ID
).ColorSpace() == B_CMAP8
;
88 //TODO: we don't support workspace and colorspace changing for now
89 // so we take the main_screen colorspace at startup
91 fRows
= 256 / fColumns
;
95 fSelectedPaletteColorIndex
= -1;
96 fPreviousSelectedPaletteColorIndex
= -1;
97 fFocusedRamp
= !fPaletteMode
&& IsFocus() ? 1 : -1;
100 const char* red
= B_TRANSLATE_MARK("Red:");
101 const char* green
= B_TRANSLATE_MARK("Green:");
102 const char* blue
= B_TRANSLATE_MARK("Blue:");
103 red
= gSystemCatalog
.GetString(red
, "ColorControl");
104 green
= gSystemCatalog
.GetString(green
, "ColorControl");
105 blue
= gSystemCatalog
.GetString(blue
, "ColorControl");
108 fRedText
= (BTextControl
*)FindView("_red");
109 fGreenText
= (BTextControl
*)FindView("_green");
110 fBlueText
= (BTextControl
*)FindView("_blue");
113 data
->FindInt32("_val", &value
);
117 BRect
textRect(0.0f
, 0.0f
, 0.0f
, 0.0f
);
118 float labelWidth
= std::max(StringWidth(red
),
119 std::max(StringWidth(green
), StringWidth(blue
)))
120 + kTextFieldsHSpacing
;
121 textRect
.right
= labelWidth
+ StringWidth("999999");
122 // enough room for 3 digits plus 3 digits of padding
123 font_height fontHeight
;
124 GetFontHeight(&fontHeight
);
125 float labelHeight
= fontHeight
.ascent
+ fontHeight
.descent
;
126 textRect
.bottom
= labelHeight
;
130 fRedText
= new BTextControl(textRect
, "_red", red
, "0",
131 new BMessage(kMsgColorEntered
), B_FOLLOW_LEFT
| B_FOLLOW_TOP
,
132 B_WILL_DRAW
| B_NAVIGABLE
);
133 fRedText
->SetDivider(labelWidth
);
135 for (int32 i
= 0; i
< 256; i
++)
136 fRedText
->TextView()->DisallowChar(i
);
137 for (int32 i
= '0'; i
<= '9'; i
++)
138 fRedText
->TextView()->AllowChar(i
);
139 fRedText
->TextView()->SetMaxBytes(3);
143 textRect
.OffsetBy(0, _TextRectOffset());
144 fGreenText
= new BTextControl(textRect
, "_green", green
, "0",
145 new BMessage(kMsgColorEntered
), B_FOLLOW_LEFT
| B_FOLLOW_TOP
,
146 B_WILL_DRAW
| B_NAVIGABLE
);
147 fGreenText
->SetDivider(labelWidth
);
149 for (int32 i
= 0; i
< 256; i
++)
150 fGreenText
->TextView()->DisallowChar(i
);
151 for (int32 i
= '0'; i
<= '9'; i
++)
152 fGreenText
->TextView()->AllowChar(i
);
153 fGreenText
->TextView()->SetMaxBytes(3);
157 textRect
.OffsetBy(0, _TextRectOffset());
158 fBlueText
= new BTextControl(textRect
, "_blue", blue
, "0",
159 new BMessage(kMsgColorEntered
), B_FOLLOW_LEFT
| B_FOLLOW_TOP
,
160 B_WILL_DRAW
| B_NAVIGABLE
);
161 fBlueText
->SetDivider(labelWidth
);
163 for (int32 i
= 0; i
< 256; i
++)
164 fBlueText
->TextView()->DisallowChar(i
);
165 for (int32 i
= '0'; i
<= '9'; i
++)
166 fBlueText
->TextView()->AllowChar(i
);
167 fBlueText
->TextView()->SetMaxBytes(3);
170 AddChild(fGreenText
);
177 BRect bounds
= _PaletteFrame();
178 fBitmap
= new BBitmap(bounds
, B_RGB32
, true, false);
179 fOffscreenView
= new BView(bounds
, "off_view", 0, 0);
182 fBitmap
->AddChild(fOffscreenView
);
186 fOffscreenView
= NULL
;
192 BColorControl::_LayoutView()
194 fPaletteFrame
.Set(0, 0, fColumns
* fCellSize
, fRows
* fCellSize
);
195 fPaletteFrame
.OffsetBy(kBevelSpacing
, kBevelSpacing
);
197 // Reduce the inner space by 1 pixel so that the frame
198 // is exactly rows * cellsize pixels in height
199 fPaletteFrame
.bottom
-= 1;
202 float rampHeight
= (float)(fRows
* fCellSize
/ kRampCount
);
203 float offset
= _TextRectOffset();
205 if (rampHeight
> fRedText
->Frame().Height()) {
206 // there is enough room to fit kRampCount labels,
207 // shift text controls down by one ramp
209 y
= floorf(offset
+ (offset
- fRedText
->Frame().Height()) / 2);
212 BRect rect
= _PaletteFrame();
213 fRedText
->MoveTo(rect
.right
+ kTextFieldsHSpacing
, y
);
216 fGreenText
->MoveTo(rect
.right
+ kTextFieldsHSpacing
, y
);
219 fBlueText
->MoveTo(rect
.right
+ kTextFieldsHSpacing
, y
);
224 BColorControl::Instantiate(BMessage
* data
)
226 if (validate_instantiation(data
, "BColorControl"))
227 return new BColorControl(data
);
234 BColorControl::Archive(BMessage
* data
, bool deep
) const
236 status_t status
= BControl::Archive(data
, deep
);
239 status
= data
->AddInt32("_layout", Layout());
242 status
= data
->AddFloat("_csize", fCellSize
);
245 status
= data
->AddBool("_use_off", fOffscreenView
!= NULL
);
252 BColorControl::SetLayout(BLayout
* layout
)
254 // We need to implement this method, since we have another SetLayout()
255 // method and C++ has this special method hiding "feature".
256 BControl::SetLayout(layout
);
261 BColorControl::SetValue(int32 value
)
263 rgb_color c1
= ValueAsColor();
265 c2
.red
= (value
& 0xFF000000) >> 24;
266 c2
.green
= (value
& 0x00FF0000) >> 16;
267 c2
.blue
= (value
& 0x0000FF00) >> 8;
271 //workaround when two indexes have the same color
272 rgb_color c
= BScreen(Window()).ColorForIndex(fSelectedPaletteColorIndex
);
274 if (fSelectedPaletteColorIndex
== -1 || c
!= c2
) {
275 //here SetValue hasn't been called by mouse tracking
276 fSelectedPaletteColorIndex
= BScreen(Window()).IndexForColor(c2
);
279 c2
= BScreen(Window()).ColorForIndex(fSelectedPaletteColorIndex
);
281 Invalidate(_PaletteSelectorFrame(fPreviousSelectedPaletteColorIndex
));
282 Invalidate(_PaletteSelectorFrame(fSelectedPaletteColorIndex
));
284 fPreviousSelectedPaletteColorIndex
= fSelectedPaletteColorIndex
;
288 // Set the value here, since BTextControl will trigger
289 // Window()->UpdateIfNeeded() which will cause us to draw the indicators
290 // at the old offset.
291 if (Value() != value
)
292 BControl::SetValueNoUpdate(value
);
294 // the textcontrols have to be updated even when the color
295 // hasn't changed since the value is clamped upstream
296 // and the textcontrols would still show the unclamped value
298 sprintf(string
, "%d", c2
.red
);
299 fRedText
->SetText(string
);
300 sprintf(string
, "%d", c2
.green
);
301 fGreenText
->SetText(string
);
302 sprintf(string
, "%d", c2
.blue
);
303 fBlueText
->SetText(string
);
308 BColorControl::ValueAsColor()
310 int32 value
= Value();
313 color
.red
= (value
& 0xFF000000) >> 24;
314 color
.green
= (value
& 0x00FF0000) >> 16;
315 color
.blue
= (value
& 0x0000FF00) >> 8;
323 BColorControl::SetEnabled(bool enabled
)
325 BControl::SetEnabled(enabled
);
327 fRedText
->SetEnabled(enabled
);
328 fGreenText
->SetEnabled(enabled
);
329 fBlueText
->SetEnabled(enabled
);
334 BColorControl::AttachedToWindow()
337 SetViewColor(Parent()->ViewColor());
339 SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR
));
341 BControl::AttachedToWindow();
343 fRedText
->SetTarget(this);
344 fGreenText
->SetTarget(this);
345 fBlueText
->SetTarget(this);
353 BColorControl::MessageReceived(BMessage
* message
)
355 switch (message
->what
) {
356 case kMsgColorEntered
:
359 color
.red
= min_c(strtol(fRedText
->Text(), NULL
, 10), 255);
360 color
.green
= min_c(strtol(fGreenText
->Text(), NULL
, 10), 255);
361 color
.blue
= min_c(strtol(fBlueText
->Text(), NULL
, 10), 255);
369 BControl::MessageReceived(message
);
375 BColorControl::Draw(BRect updateRect
)
378 DrawBitmap(fBitmap
, B_ORIGIN
);
380 _DrawColorArea(this, updateRect
);
382 _DrawSelectors(this);
387 BColorControl::_DrawColorArea(BView
* target
, BRect updateRect
)
389 BRect rect
= _PaletteFrame();
390 bool enabled
= IsEnabled();
392 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
393 rgb_color darken1
= tint_color(base
, B_DARKEN_1_TINT
);
395 if (be_control_look
!= NULL
) {
396 uint32 flags
= be_control_look
->Flags(this);
397 be_control_look
->DrawTextControlBorder(target
, rect
, updateRect
,
401 rgb_color lighten1
= tint_color(base
, B_LIGHTEN_1_TINT
);
402 rgb_color lightenmax
= tint_color(base
, B_LIGHTEN_MAX_TINT
);
403 target
->SetHighColor(enabled
? darken1
: base
);
405 target
->StrokeLine(rect
.LeftBottom(), rect
.LeftTop());
406 target
->StrokeLine(rect
.LeftTop(), rect
.RightTop());
407 target
->SetHighColor(enabled
? lightenmax
: lighten1
);
409 target
->StrokeLine(BPoint(rect
.left
+ 1.0f
, rect
.bottom
),
411 target
->StrokeLine(rect
.RightBottom(),
412 BPoint(rect
.right
, rect
.top
+ 1.0f
));
414 rect
.InsetBy(1.0f
, 1.0f
);
417 rgb_color darken2
= tint_color(base
, B_DARKEN_2_TINT
);
418 rgb_color darken4
= tint_color(base
, B_DARKEN_4_TINT
);
419 target
->SetHighColor(enabled
? darken4
: darken2
);
421 target
->StrokeLine(rect
.LeftBottom(), rect
.LeftTop());
422 target
->StrokeLine(rect
.LeftTop(), rect
.RightTop());
423 target
->SetHighColor(base
);
424 target
->StrokeLine(BPoint(rect
.left
+ 1.0f
, rect
.bottom
),
426 target
->StrokeLine(rect
.RightBottom(),
427 BPoint(rect
.right
, rect
.top
+ 1.0f
));
431 int colBegin
= max_c(0, -1 + int(updateRect
.left
) / int(fCellSize
));
432 int colEnd
= min_c(fColumns
,
433 2 + int(updateRect
.right
) / int(fCellSize
));
434 int rowBegin
= max_c(0, -1 + int(updateRect
.top
) / int(fCellSize
));
435 int rowEnd
= min_c(fRows
, 2 + int(updateRect
.bottom
)
439 target
->SetHighColor(enabled
? darken1
: base
);
441 for (int xi
= 0; xi
< fColumns
+ 1; xi
++) {
442 float x
= fPaletteFrame
.left
+ float(xi
) * fCellSize
;
443 target
->StrokeLine(BPoint(x
, fPaletteFrame
.top
),
444 BPoint(x
, fPaletteFrame
.bottom
));
446 for (int yi
= 0; yi
< fRows
+ 1; yi
++) {
447 float y
= fPaletteFrame
.top
+ float(yi
) * fCellSize
;
448 target
->StrokeLine(BPoint(fPaletteFrame
.left
, y
),
449 BPoint(fPaletteFrame
.right
, y
));
453 for (int col
= colBegin
; col
< colEnd
; col
++) {
454 for (int row
= rowBegin
; row
< rowEnd
; row
++) {
455 uint8 colorIndex
= row
* fColumns
+ col
;
456 float x
= fPaletteFrame
.left
+ col
* fCellSize
;
457 float y
= fPaletteFrame
.top
+ row
* fCellSize
;
459 target
->SetHighColor(system_colors()->color_list
[colorIndex
]);
460 target
->FillRect(BRect(x
+ 1, y
+ 1,
461 x
+ fCellSize
- 1, y
+ fCellSize
- 1));
465 rgb_color white
= { 255, 255, 255, 255 };
466 rgb_color red
= { 255, 0, 0, 255 };
467 rgb_color green
= { 0, 255, 0, 255 };
468 rgb_color blue
= { 0, 0, 255, 255 };
470 rgb_color compColor
= { 0, 0, 0, 255 };
472 compColor
.red
= compColor
.green
= compColor
.blue
= 156;
473 red
.red
= green
.green
= blue
.blue
= 70;
474 white
.red
= white
.green
= white
.blue
= 70;
476 _DrawColorRamp(_RampFrame(0), target
, white
, compColor
, 0, false,
478 _DrawColorRamp(_RampFrame(1), target
, red
, compColor
, 0, false,
480 _DrawColorRamp(_RampFrame(2), target
, green
, compColor
, 0, false,
482 _DrawColorRamp(_RampFrame(3), target
, blue
, compColor
, 0, false,
489 BColorControl::_DrawSelectors(BView
* target
)
491 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
492 rgb_color lightenmax
= tint_color(base
, B_LIGHTEN_MAX_TINT
);
495 if (fSelectedPaletteColorIndex
!= -1) {
496 target
->SetHighColor(lightenmax
);
497 target
->StrokeRect(_PaletteSelectorFrame(fSelectedPaletteColorIndex
));
500 rgb_color color
= ValueAsColor();
501 target
->SetHighColor(255, 255, 255);
502 target
->SetLowColor(0, 0, 0);
504 int components
[4] = { color
.alpha
, color
.red
, color
.green
, color
.blue
};
506 for (int i
= 1; i
< 4; i
++) {
507 BPoint center
= _SelectorPosition(_RampFrame(i
), components
[i
]);
509 target
->SetPenSize(kSelectorPenSize
);
510 target
->StrokeEllipse(center
, kSelectorSize
/ 2, kSelectorSize
/ 2);
511 target
->SetPenSize(kSelectorPenSize
/ 2);
512 target
->StrokeEllipse(center
, kSelectorSize
, kSelectorSize
,
514 if (i
== fFocusedRamp
) {
515 target
->StrokeEllipse(center
,
516 kSelectorSize
/ 2, kSelectorSize
/ 2, B_SOLID_LOW
);
520 target
->SetPenSize(1.0f
);
526 BColorControl::_DrawColorRamp(BRect rect
, BView
* target
,
527 rgb_color baseColor
, rgb_color compColor
, int16 flag
, bool focused
,
530 float width
= rect
.Width() + 1;
531 rgb_color color
= ValueAsColor();
534 updateRect
= updateRect
& rect
;
536 if (updateRect
.IsValid() && updateRect
.Width() >= 0) {
537 target
->BeginLineArray((int32
)updateRect
.Width() + 1);
539 for (float i
= (updateRect
.left
- rect
.left
);
540 i
<= (updateRect
.right
- rect
.left
) + 1; i
++) {
541 if (baseColor
.red
== 255)
542 color
.red
= (uint8
)(i
* 255 / width
) + compColor
.red
;
543 if (baseColor
.green
== 255)
544 color
.green
= (uint8
)(i
* 255 / width
) + compColor
.green
;
545 if (baseColor
.blue
== 255)
546 color
.blue
= (uint8
)(i
* 255 / width
) + compColor
.blue
;
548 target
->AddLine(BPoint(rect
.left
+ i
, rect
.top
),
549 BPoint(rect
.left
+ i
, rect
.bottom
- 1), color
);
552 target
->EndLineArray();
558 BColorControl::_SelectorPosition(const BRect
& rampRect
, uint8 shade
) const
560 float radius
= kSelectorSize
/ 2 + kSelectorPenSize
/ 2;
562 return BPoint(rampRect
.left
+ kSelectorHSpacing
+ radius
+
563 shade
* (rampRect
.Width() - 2 * (kSelectorHSpacing
+ radius
)) / 255,
564 rampRect
.top
+ rampRect
.Height() / 2);
569 BColorControl::_PaletteFrame() const
571 return fPaletteFrame
.InsetByCopy(-kBevelSpacing
, -kBevelSpacing
);
576 BColorControl::_RampFrame(uint8 rampIndex
) const
578 float rampHeight
= (float)(fRows
* fCellSize
/ kRampCount
);
580 return BRect(fPaletteFrame
.left
,
581 fPaletteFrame
.top
+ float(rampIndex
) * rampHeight
,
583 fPaletteFrame
.top
+ float(rampIndex
+ 1) * rampHeight
);
588 BColorControl::_SetCellSize(float size
)
592 fCellSize
= std::max(kMinCellSize
,
593 ceilf(size
* font
.Size() / kDefaultFontSize
));
598 BColorControl::_TextRectOffset()
600 return std::max(fRedText
->Bounds().Height(),
601 ceilf(_PaletteFrame().Height() / 3));
606 BColorControl::_PaletteSelectorFrame(uint8 colorIndex
) const
608 uint32 row
= colorIndex
/ fColumns
;
609 uint32 column
= colorIndex
% fColumns
;
610 float x
= fPaletteFrame
.left
+ column
* fCellSize
;
611 float y
= fPaletteFrame
.top
+ row
* fCellSize
;
612 return BRect(x
, y
, x
+ fCellSize
, y
+ fCellSize
);
617 BColorControl::_InitOffscreen()
619 if (fBitmap
->Lock()) {
620 _DrawColorArea(fOffscreenView
, _PaletteFrame());
621 fOffscreenView
->Sync();
628 BColorControl::_InvalidateSelector(int16 ramp
, rgb_color color
, bool focused
)
633 if (ramp
< 1 || ramp
> 3)
636 float invalidateRadius
= focused
637 ? kSelectorSize
+ kSelectorPenSize
/ 2
638 : kSelectorSize
/ 2 + kSelectorPenSize
;
640 uint8 colorValue
= ramp
== 1 ? color
.red
: ramp
== 2 ? color
.green
643 BPoint pos
= _SelectorPosition(_RampFrame(ramp
), colorValue
);
644 Invalidate(BRect(pos
.x
- invalidateRadius
, pos
.y
- invalidateRadius
,
645 pos
.x
+ invalidateRadius
, pos
.y
+ invalidateRadius
));
650 BColorControl::SetCellSize(float size
)
658 BColorControl::CellSize() const
665 BColorControl::SetLayout(color_control_layout layout
)
696 BColorControl::Layout() const
698 if (fColumns
== 4 && fRows
== 64)
700 if (fColumns
== 8 && fRows
== 32)
702 if (fColumns
== 16 && fRows
== 16)
703 return B_CELLS_16x16
;
704 if (fColumns
== 32 && fRows
== 8)
706 if (fColumns
== 64 && fRows
== 4)
714 BColorControl::WindowActivated(bool state
)
716 BControl::WindowActivated(state
);
721 BColorControl::KeyDown(const char* bytes
, int32 numBytes
)
723 if (IsFocus() && !fPaletteMode
&& numBytes
== 1) {
724 rgb_color color
= ValueAsColor();
729 int16 oldFocus
= fFocusedRamp
;
731 if (fFocusedRamp
< 1)
734 _InvalidateSelector(oldFocus
, color
, true);
735 _InvalidateSelector(fFocusedRamp
, color
, true);
741 int16 oldFocus
= fFocusedRamp
;
743 if (fFocusedRamp
> 3)
746 _InvalidateSelector(oldFocus
, color
, true);
747 _InvalidateSelector(fFocusedRamp
, color
, true);
753 bool goFaster
= false;
754 if (Window() != NULL
) {
755 BMessage
* message
= Window()->CurrentMessage();
756 if (message
!= NULL
&& message
->what
== B_KEY_DOWN
) {
758 if (message
->FindInt32("be:key_repeat", &repeats
)
759 == B_OK
&& repeats
> 4) {
765 if (fFocusedRamp
== 1) {
766 if (goFaster
&& color
.red
>= 5)
768 else if (color
.red
> 0)
770 } else if (fFocusedRamp
== 2) {
771 if (goFaster
&& color
.green
>= 5)
773 else if (color
.green
> 0)
775 } else if (fFocusedRamp
== 3) {
776 if (goFaster
&& color
.blue
>= 5)
778 else if (color
.blue
> 0)
789 bool goFaster
= false;
790 if (Window() != NULL
) {
791 BMessage
* message
= Window()->CurrentMessage();
792 if (message
!= NULL
&& message
->what
== B_KEY_DOWN
) {
794 if (message
->FindInt32("be:key_repeat", &repeats
)
795 == B_OK
&& repeats
> 4) {
801 if (fFocusedRamp
== 1) {
802 if (goFaster
&& color
.red
<= 250)
804 else if (color
.red
< 255)
806 } else if (fFocusedRamp
== 2) {
807 if (goFaster
&& color
.green
<= 250)
809 else if (color
.green
< 255)
811 } else if (fFocusedRamp
== 3) {
812 if (goFaster
&& color
.blue
<= 250)
814 else if (color
.blue
< 255)
825 BControl::KeyDown(bytes
, numBytes
);
830 BColorControl::MouseUp(BPoint point
)
838 BColorControl::MouseDown(BPoint point
)
842 if (!fPaletteFrame
.Contains(point
))
846 int col
= (int)((point
.x
- fPaletteFrame
.left
) / fCellSize
);
847 int row
= (int)((point
.y
- fPaletteFrame
.top
) / fCellSize
);
848 int colorIndex
= row
* fColumns
+ col
;
849 if (colorIndex
>= 0 && colorIndex
< 256) {
850 fSelectedPaletteColorIndex
= colorIndex
;
851 SetValue(system_colors()->color_list
[colorIndex
]);
854 rgb_color color
= ValueAsColor();
856 uint8 shade
= (unsigned char)max_c(0,
857 min_c((point
.x
- _RampFrame(0).left
) * 255
858 / _RampFrame(0).Width(), 255));
860 if (_RampFrame(0).Contains(point
)) {
861 color
.red
= color
.green
= color
.blue
= shade
;
863 } else if (_RampFrame(1).Contains(point
)) {
866 } else if (_RampFrame(2).Contains(point
)) {
869 } else if (_RampFrame(3).Contains(point
)) {
880 SetMouseEventMask(B_POINTER_EVENTS
,
881 B_NO_POINTER_HISTORY
| B_LOCK_WINDOW_FOCUS
);
886 BColorControl::MouseMoved(BPoint point
, uint32 transit
,
887 const BMessage
* message
)
892 if (fPaletteMode
&& fPaletteFrame
.Contains(point
)) {
893 int col
= (int)((point
.x
- fPaletteFrame
.left
) / fCellSize
);
894 int row
= (int)((point
.y
- fPaletteFrame
.top
) / fCellSize
);
895 int colorIndex
= row
* fColumns
+ col
;
896 if (colorIndex
>= 0 && colorIndex
< 256) {
897 fSelectedPaletteColorIndex
= colorIndex
;
898 SetValue(system_colors()->color_list
[colorIndex
]);
901 if (fClickedRamp
< 0 || fClickedRamp
> 3)
904 rgb_color color
= ValueAsColor();
906 uint8 shade
= (unsigned char)max_c(0,
907 min_c((point
.x
- _RampFrame(0).left
) * 255
908 / _RampFrame(0).Width(), 255));
910 if (fClickedRamp
== 0)
911 color
.red
= color
.green
= color
.blue
= shade
;
912 else if (fClickedRamp
== 1)
914 else if (fClickedRamp
== 2)
916 else if (fClickedRamp
== 3)
927 BColorControl::DetachedFromWindow()
929 BControl::DetachedFromWindow();
934 BColorControl::GetPreferredSize(float* _width
, float* _height
)
936 BRect rect
= _PaletteFrame();
938 if (rect
.Height() < fBlueText
->Frame().bottom
) {
939 // adjust the height to fit
940 rect
.bottom
= fBlueText
->Frame().bottom
;
944 *_width
= rect
.Width() + kTextFieldsHSpacing
945 + fRedText
->Bounds().Width();
949 *_height
= rect
.Height();
954 BColorControl::ResizeToPreferred()
957 BControl::ResizeToPreferred();
962 BColorControl::Invoke(BMessage
* message
)
964 return BControl::Invoke(message
);
969 BColorControl::FrameMoved(BPoint newPosition
)
971 BControl::FrameMoved(newPosition
);
976 BColorControl::FrameResized(float newWidth
, float newHeight
)
978 BControl::FrameResized(newWidth
, newHeight
);
983 BColorControl::ResolveSpecifier(BMessage
* message
, int32 index
,
984 BMessage
* specifier
, int32 form
, const char* property
)
986 return BControl::ResolveSpecifier(message
, index
, specifier
, form
,
992 BColorControl::GetSupportedSuites(BMessage
* data
)
994 return BControl::GetSupportedSuites(data
);
999 BColorControl::MakeFocus(bool focused
)
1001 fFocusedRamp
= !fPaletteMode
&& focused
? 1 : -1;
1002 BControl::MakeFocus(focused
);
1007 BColorControl::AllAttached()
1009 BControl::AllAttached();
1014 BColorControl::AllDetached()
1016 BControl::AllDetached();
1021 BColorControl::SetIcon(const BBitmap
* icon
, uint32 flags
)
1023 return BControl::SetIcon(icon
, flags
);
1028 BColorControl::Perform(perform_code code
, void* _data
)
1031 case PERFORM_CODE_MIN_SIZE
:
1032 ((perform_data_min_size
*)_data
)->return_value
1033 = BColorControl::MinSize();
1035 case PERFORM_CODE_MAX_SIZE
:
1036 ((perform_data_max_size
*)_data
)->return_value
1037 = BColorControl::MaxSize();
1039 case PERFORM_CODE_PREFERRED_SIZE
:
1040 ((perform_data_preferred_size
*)_data
)->return_value
1041 = BColorControl::PreferredSize();
1043 case PERFORM_CODE_LAYOUT_ALIGNMENT
:
1044 ((perform_data_layout_alignment
*)_data
)->return_value
1045 = BColorControl::LayoutAlignment();
1047 case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH
:
1048 ((perform_data_has_height_for_width
*)_data
)->return_value
1049 = BColorControl::HasHeightForWidth();
1051 case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH
:
1053 perform_data_get_height_for_width
* data
1054 = (perform_data_get_height_for_width
*)_data
;
1055 BColorControl::GetHeightForWidth(data
->width
, &data
->min
,
1056 &data
->max
, &data
->preferred
);
1059 case PERFORM_CODE_SET_LAYOUT
:
1061 perform_data_set_layout
* data
= (perform_data_set_layout
*)_data
;
1062 BColorControl::SetLayout(data
->layout
);
1065 case PERFORM_CODE_LAYOUT_INVALIDATED
:
1067 perform_data_layout_invalidated
* data
1068 = (perform_data_layout_invalidated
*)_data
;
1069 BColorControl::LayoutInvalidated(data
->descendants
);
1072 case PERFORM_CODE_DO_LAYOUT
:
1074 BColorControl::DoLayout();
1077 case PERFORM_CODE_SET_ICON
:
1079 perform_data_set_icon
* data
= (perform_data_set_icon
*)_data
;
1080 return BColorControl::SetIcon(data
->icon
, data
->flags
);
1084 return BControl::Perform(code
, _data
);
1088 void BColorControl::_ReservedColorControl1() {}
1089 void BColorControl::_ReservedColorControl2() {}
1090 void BColorControl::_ReservedColorControl3() {}
1091 void BColorControl::_ReservedColorControl4() {}
1095 BColorControl::operator=(const BColorControl
&)