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 useOffscreen
)
54 BControl(BRect(leftTop
, leftTop
), name
, NULL
, message
,
55 B_FOLLOW_LEFT
| B_FOLLOW_TOP
, B_WILL_DRAW
| B_NAVIGABLE
),
59 fOffscreenBitmap(NULL
)
61 _InitData(layout
, cellSize
, useOffscreen
, NULL
);
65 BColorControl::BColorControl(BMessage
* data
)
71 fOffscreenBitmap(NULL
)
77 data
->FindInt32("_layout", &layout
);
78 data
->FindFloat("_csize", &cellSize
);
79 data
->FindBool("_use_off", &useOffscreen
);
81 _InitData((color_control_layout
)layout
, cellSize
, useOffscreen
, data
);
85 BColorControl::~BColorControl()
87 delete fOffscreenBitmap
;
92 BColorControl::_InitData(color_control_layout layout
, float size
,
93 bool useOffscreen
, BMessage
* data
)
95 fPaletteMode
= BScreen(B_MAIN_SCREEN_ID
).ColorSpace() == B_CMAP8
;
96 //TODO: we don't support workspace and colorspace changing for now
97 // so we take the main_screen colorspace at startup
99 fRows
= 256 / fColumns
;
103 fSelectedPaletteColorIndex
= -1;
104 fPreviousSelectedPaletteColorIndex
= -1;
105 fFocusedRamp
= !fPaletteMode
&& IsFocus() ? 1 : -1;
108 const char* red
= B_TRANSLATE_MARK("Red:");
109 const char* green
= B_TRANSLATE_MARK("Green:");
110 const char* blue
= B_TRANSLATE_MARK("Blue:");
111 red
= gSystemCatalog
.GetString(red
, "ColorControl");
112 green
= gSystemCatalog
.GetString(green
, "ColorControl");
113 blue
= gSystemCatalog
.GetString(blue
, "ColorControl");
116 fRedText
= (BTextControl
*)FindView("_red");
117 fGreenText
= (BTextControl
*)FindView("_green");
118 fBlueText
= (BTextControl
*)FindView("_blue");
121 data
->FindInt32("_val", &value
);
125 BRect
textRect(0.0f
, 0.0f
, 0.0f
, 0.0f
);
126 float labelWidth
= std::max(StringWidth(red
),
127 std::max(StringWidth(green
), StringWidth(blue
)))
128 + kTextFieldsHSpacing
;
129 textRect
.right
= labelWidth
+ StringWidth("999999");
130 // enough room for 3 digits plus 3 digits of padding
131 font_height fontHeight
;
132 GetFontHeight(&fontHeight
);
133 float labelHeight
= fontHeight
.ascent
+ fontHeight
.descent
;
134 textRect
.bottom
= labelHeight
;
138 fRedText
= new BTextControl(textRect
, "_red", red
, "0",
139 new BMessage(kMsgColorEntered
), B_FOLLOW_LEFT
| B_FOLLOW_TOP
,
140 B_WILL_DRAW
| B_NAVIGABLE
);
141 fRedText
->SetDivider(labelWidth
);
143 for (int32 i
= 0; i
< 256; i
++)
144 fRedText
->TextView()->DisallowChar(i
);
145 for (int32 i
= '0'; i
<= '9'; i
++)
146 fRedText
->TextView()->AllowChar(i
);
147 fRedText
->TextView()->SetMaxBytes(3);
151 textRect
.OffsetBy(0, _TextRectOffset());
152 fGreenText
= new BTextControl(textRect
, "_green", green
, "0",
153 new BMessage(kMsgColorEntered
), B_FOLLOW_LEFT
| B_FOLLOW_TOP
,
154 B_WILL_DRAW
| B_NAVIGABLE
);
155 fGreenText
->SetDivider(labelWidth
);
157 for (int32 i
= 0; i
< 256; i
++)
158 fGreenText
->TextView()->DisallowChar(i
);
159 for (int32 i
= '0'; i
<= '9'; i
++)
160 fGreenText
->TextView()->AllowChar(i
);
161 fGreenText
->TextView()->SetMaxBytes(3);
165 textRect
.OffsetBy(0, _TextRectOffset());
166 fBlueText
= new BTextControl(textRect
, "_blue", blue
, "0",
167 new BMessage(kMsgColorEntered
), B_FOLLOW_LEFT
| B_FOLLOW_TOP
,
168 B_WILL_DRAW
| B_NAVIGABLE
);
169 fBlueText
->SetDivider(labelWidth
);
171 for (int32 i
= 0; i
< 256; i
++)
172 fBlueText
->TextView()->DisallowChar(i
);
173 for (int32 i
= '0'; i
<= '9'; i
++)
174 fBlueText
->TextView()->AllowChar(i
);
175 fBlueText
->TextView()->SetMaxBytes(3);
178 AddChild(fGreenText
);
185 if (fOffscreenBitmap
!= NULL
) {
186 BRect bounds
= _PaletteFrame();
187 fOffscreenBitmap
= new BBitmap(bounds
, B_RGB32
, true, false);
188 BView
* offscreenView
= new BView(bounds
, "off_view", 0, 0);
190 fOffscreenBitmap
->Lock();
191 fOffscreenBitmap
->AddChild(offscreenView
);
192 fOffscreenBitmap
->Unlock();
195 delete fOffscreenBitmap
;
196 fOffscreenBitmap
= NULL
;
202 BColorControl::_LayoutView()
204 fPaletteFrame
.Set(0, 0, fColumns
* fCellSize
, fRows
* fCellSize
);
205 fPaletteFrame
.OffsetBy(kBevelSpacing
, kBevelSpacing
);
207 // Reduce the inner space by 1 pixel so that the frame
208 // is exactly rows * cellsize pixels in height
209 fPaletteFrame
.bottom
-= 1;
212 float rampHeight
= (float)(fRows
* fCellSize
/ kRampCount
);
213 float offset
= _TextRectOffset();
215 if (rampHeight
> fRedText
->Frame().Height()) {
216 // there is enough room to fit kRampCount labels,
217 // shift text controls down by one ramp
219 y
= floorf(offset
+ (offset
- fRedText
->Frame().Height()) / 2);
222 BRect rect
= _PaletteFrame();
223 fRedText
->MoveTo(rect
.right
+ kTextFieldsHSpacing
, y
);
226 fGreenText
->MoveTo(rect
.right
+ kTextFieldsHSpacing
, y
);
229 fBlueText
->MoveTo(rect
.right
+ kTextFieldsHSpacing
, y
);
234 BColorControl::Instantiate(BMessage
* data
)
236 if (validate_instantiation(data
, "BColorControl"))
237 return new BColorControl(data
);
244 BColorControl::Archive(BMessage
* data
, bool deep
) const
246 status_t status
= BControl::Archive(data
, deep
);
249 status
= data
->AddInt32("_layout", Layout());
252 status
= data
->AddFloat("_csize", fCellSize
);
255 status
= data
->AddBool("_use_off", fOffscreenBitmap
!= NULL
);
262 BColorControl::SetLayout(BLayout
* layout
)
264 // We need to implement this method, since we have another SetLayout()
265 // method and C++ has this special method hiding "feature".
266 BControl::SetLayout(layout
);
271 BColorControl::SetValue(int32 value
)
273 rgb_color c1
= ValueAsColor();
275 c2
.red
= (value
& 0xFF000000) >> 24;
276 c2
.green
= (value
& 0x00FF0000) >> 16;
277 c2
.blue
= (value
& 0x0000FF00) >> 8;
281 //workaround when two indexes have the same color
283 = BScreen(Window()).ColorForIndex(fSelectedPaletteColorIndex
);
285 if (fSelectedPaletteColorIndex
== -1 || c
!= c2
) {
286 //here SetValue hasn't been called by mouse tracking
287 fSelectedPaletteColorIndex
= BScreen(Window()).IndexForColor(c2
);
290 c2
= BScreen(Window()).ColorForIndex(fSelectedPaletteColorIndex
);
292 Invalidate(_PaletteSelectorFrame(fPreviousSelectedPaletteColorIndex
));
293 Invalidate(_PaletteSelectorFrame(fSelectedPaletteColorIndex
));
295 fPreviousSelectedPaletteColorIndex
= fSelectedPaletteColorIndex
;
299 // Set the value here, since BTextControl will trigger
300 // Window()->UpdateIfNeeded() which will cause us to draw the indicators
301 // at the old offset.
302 if (Value() != value
)
303 BControl::SetValueNoUpdate(value
);
305 // the textcontrols have to be updated even when the color
306 // hasn't changed since the value is clamped upstream
307 // and the textcontrols would still show the unclamped value
309 sprintf(string
, "%d", c2
.red
);
310 fRedText
->SetText(string
);
311 sprintf(string
, "%d", c2
.green
);
312 fGreenText
->SetText(string
);
313 sprintf(string
, "%d", c2
.blue
);
314 fBlueText
->SetText(string
);
319 BColorControl::ValueAsColor()
321 int32 value
= Value();
324 color
.red
= (value
& 0xFF000000) >> 24;
325 color
.green
= (value
& 0x00FF0000) >> 16;
326 color
.blue
= (value
& 0x0000FF00) >> 8;
334 BColorControl::SetEnabled(bool enabled
)
336 BControl::SetEnabled(enabled
);
338 fRedText
->SetEnabled(enabled
);
339 fGreenText
->SetEnabled(enabled
);
340 fBlueText
->SetEnabled(enabled
);
345 BColorControl::AttachedToWindow()
347 BControl::AttachedToWindow();
351 fRedText
->SetTarget(this);
352 fGreenText
->SetTarget(this);
353 fBlueText
->SetTarget(this);
355 if (fOffscreenBitmap
!= NULL
)
361 BColorControl::MessageReceived(BMessage
* message
)
363 switch (message
->what
) {
364 case kMsgColorEntered
:
367 color
.red
= min_c(strtol(fRedText
->Text(), NULL
, 10), 255);
368 color
.green
= min_c(strtol(fGreenText
->Text(), NULL
, 10), 255);
369 color
.blue
= min_c(strtol(fBlueText
->Text(), NULL
, 10), 255);
377 case B_SCREEN_CHANGED
:
381 if (message
->FindRect("frame", &frame
) == B_OK
382 && message
->FindInt32("mode", (int32
*)&mode
) == B_OK
) {
383 if ((fPaletteMode
&& mode
== B_CMAP8
)
384 || (!fPaletteMode
&& mode
!= B_CMAP8
)) {
385 // not switching to or from B_CMAP8, break
389 // fake an archive message (so we don't rebuild views)
390 BMessage
* data
= new BMessage();
391 data
->AddInt32("_val", Value());
394 bool useOffscreen
= fOffscreenBitmap
!= NULL
;
395 _InitData((color_control_layout
)fColumns
, fCellSize
,
407 BControl::MessageReceived(message
);
413 BColorControl::Draw(BRect updateRect
)
415 if (fOffscreenBitmap
!= NULL
)
416 DrawBitmap(fOffscreenBitmap
, B_ORIGIN
);
418 _DrawColorArea(this, updateRect
);
420 _DrawSelectors(this);
425 BColorControl::_DrawColorArea(BView
* target
, BRect updateRect
)
427 BRect rect
= _PaletteFrame();
428 bool enabled
= IsEnabled();
430 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
431 rgb_color darken1
= tint_color(base
, B_DARKEN_1_TINT
);
433 uint32 flags
= be_control_look
->Flags(this);
434 be_control_look
->DrawTextControlBorder(target
, rect
, updateRect
,
438 int colBegin
= max_c(0, -1 + int(updateRect
.left
) / int(fCellSize
));
439 int colEnd
= min_c(fColumns
,
440 2 + int(updateRect
.right
) / int(fCellSize
));
441 int rowBegin
= max_c(0, -1 + int(updateRect
.top
) / int(fCellSize
));
442 int rowEnd
= min_c(fRows
, 2 + int(updateRect
.bottom
)
446 target
->SetHighColor(enabled
? darken1
: base
);
448 for (int xi
= 0; xi
< fColumns
+ 1; xi
++) {
449 float x
= fPaletteFrame
.left
+ float(xi
) * fCellSize
;
450 target
->StrokeLine(BPoint(x
, fPaletteFrame
.top
),
451 BPoint(x
, fPaletteFrame
.bottom
));
453 for (int yi
= 0; yi
< fRows
+ 1; yi
++) {
454 float y
= fPaletteFrame
.top
+ float(yi
) * fCellSize
;
455 target
->StrokeLine(BPoint(fPaletteFrame
.left
, y
),
456 BPoint(fPaletteFrame
.right
, y
));
460 for (int col
= colBegin
; col
< colEnd
; col
++) {
461 for (int row
= rowBegin
; row
< rowEnd
; row
++) {
462 uint8 colorIndex
= row
* fColumns
+ col
;
463 float x
= fPaletteFrame
.left
+ col
* fCellSize
;
464 float y
= fPaletteFrame
.top
+ row
* fCellSize
;
466 target
->SetHighColor(system_colors()->color_list
[colorIndex
]);
467 target
->FillRect(BRect(x
+ 1, y
+ 1,
468 x
+ fCellSize
- 1, y
+ fCellSize
- 1));
472 rgb_color white
= { 255, 255, 255, 255 };
473 rgb_color red
= { 255, 0, 0, 255 };
474 rgb_color green
= { 0, 255, 0, 255 };
475 rgb_color blue
= { 0, 0, 255, 255 };
477 rgb_color compColor
= { 0, 0, 0, 255 };
479 compColor
.red
= compColor
.green
= compColor
.blue
= 156;
480 red
.red
= green
.green
= blue
.blue
= 70;
481 white
.red
= white
.green
= white
.blue
= 70;
483 _DrawColorRamp(_RampFrame(0), target
, white
, compColor
, 0, false,
485 _DrawColorRamp(_RampFrame(1), target
, red
, compColor
, 0, false,
487 _DrawColorRamp(_RampFrame(2), target
, green
, compColor
, 0, false,
489 _DrawColorRamp(_RampFrame(3), target
, blue
, compColor
, 0, false,
496 BColorControl::_DrawSelectors(BView
* target
)
498 rgb_color base
= ui_color(B_PANEL_BACKGROUND_COLOR
);
499 rgb_color lightenmax
= tint_color(base
, B_LIGHTEN_MAX_TINT
);
502 if (fSelectedPaletteColorIndex
!= -1) {
503 target
->SetHighColor(lightenmax
);
505 _PaletteSelectorFrame(fSelectedPaletteColorIndex
));
508 rgb_color color
= ValueAsColor();
509 target
->SetHighColor(255, 255, 255);
510 target
->SetLowColor(0, 0, 0);
512 int components
[4] = { color
.alpha
, color
.red
, color
.green
, color
.blue
};
514 for (int i
= 1; i
< 4; i
++) {
515 BPoint center
= _SelectorPosition(_RampFrame(i
), components
[i
]);
517 target
->SetPenSize(kSelectorPenSize
);
518 target
->StrokeEllipse(center
, kSelectorSize
/ 2, kSelectorSize
/ 2);
519 target
->SetPenSize(kSelectorPenSize
/ 2);
520 target
->StrokeEllipse(center
, kSelectorSize
, kSelectorSize
,
522 if (i
== fFocusedRamp
) {
523 target
->StrokeEllipse(center
,
524 kSelectorSize
/ 2, kSelectorSize
/ 2, B_SOLID_LOW
);
528 target
->SetPenSize(1.0f
);
534 BColorControl::_DrawColorRamp(BRect rect
, BView
* target
,
535 rgb_color baseColor
, rgb_color compColor
, int16 flag
, bool focused
,
538 float width
= rect
.Width() + 1;
539 rgb_color color
= ValueAsColor();
542 updateRect
= updateRect
& rect
;
544 if (updateRect
.IsValid() && updateRect
.Width() >= 0) {
545 target
->BeginLineArray((int32
)updateRect
.Width() + 1);
547 for (float i
= (updateRect
.left
- rect
.left
);
548 i
<= (updateRect
.right
- rect
.left
) + 1; i
++) {
549 if (baseColor
.red
== 255)
550 color
.red
= (uint8
)(i
* 255 / width
) + compColor
.red
;
551 if (baseColor
.green
== 255)
552 color
.green
= (uint8
)(i
* 255 / width
) + compColor
.green
;
553 if (baseColor
.blue
== 255)
554 color
.blue
= (uint8
)(i
* 255 / width
) + compColor
.blue
;
556 target
->AddLine(BPoint(rect
.left
+ i
, rect
.top
),
557 BPoint(rect
.left
+ i
, rect
.bottom
- 1), color
);
560 target
->EndLineArray();
566 BColorControl::_SelectorPosition(const BRect
& rampRect
, uint8 shade
) const
568 float radius
= kSelectorSize
/ 2 + kSelectorPenSize
/ 2;
570 return BPoint(rampRect
.left
+ kSelectorHSpacing
+ radius
+
571 shade
* (rampRect
.Width() - 2 * (kSelectorHSpacing
+ radius
)) / 255,
572 rampRect
.top
+ rampRect
.Height() / 2);
577 BColorControl::_PaletteFrame() const
579 return fPaletteFrame
.InsetByCopy(-kBevelSpacing
, -kBevelSpacing
);
584 BColorControl::_RampFrame(uint8 rampIndex
) const
586 float rampHeight
= (float)(fRows
* fCellSize
/ kRampCount
);
588 return BRect(fPaletteFrame
.left
,
589 fPaletteFrame
.top
+ float(rampIndex
) * rampHeight
,
591 fPaletteFrame
.top
+ float(rampIndex
+ 1) * rampHeight
);
596 BColorControl::_SetCellSize(float size
)
600 fCellSize
= std::max(kMinCellSize
,
601 ceilf(size
* font
.Size() / kDefaultFontSize
));
606 BColorControl::_TextRectOffset()
608 return std::max(fRedText
->Bounds().Height(),
609 ceilf(_PaletteFrame().Height() / 3));
614 BColorControl::_PaletteSelectorFrame(uint8 colorIndex
) const
616 uint32 row
= colorIndex
/ fColumns
;
617 uint32 column
= colorIndex
% fColumns
;
618 float x
= fPaletteFrame
.left
+ column
* fCellSize
;
619 float y
= fPaletteFrame
.top
+ row
* fCellSize
;
620 return BRect(x
, y
, x
+ fCellSize
, y
+ fCellSize
);
625 BColorControl::_InitOffscreen()
627 if (fOffscreenBitmap
->Lock()) {
628 BView
* offscreenView
= fOffscreenBitmap
->ChildAt((int32
)0);
629 if (offscreenView
!= NULL
) {
630 _DrawColorArea(offscreenView
, _PaletteFrame());
631 offscreenView
->Sync();
633 fOffscreenBitmap
->Unlock();
639 BColorControl::_InvalidateSelector(int16 ramp
, rgb_color color
, bool focused
)
644 if (ramp
< 1 || ramp
> 3)
647 float invalidateRadius
= focused
648 ? kSelectorSize
+ kSelectorPenSize
/ 2
649 : kSelectorSize
/ 2 + kSelectorPenSize
;
651 uint8 colorValue
= ramp
== 1 ? color
.red
: ramp
== 2 ? color
.green
654 BPoint pos
= _SelectorPosition(_RampFrame(ramp
), colorValue
);
655 Invalidate(BRect(pos
.x
- invalidateRadius
, pos
.y
- invalidateRadius
,
656 pos
.x
+ invalidateRadius
, pos
.y
+ invalidateRadius
));
661 BColorControl::SetCellSize(float size
)
669 BColorControl::CellSize() const
676 BColorControl::SetLayout(color_control_layout layout
)
711 BColorControl::Layout() const
713 if (fColumns
== 4 && fRows
== 64)
716 if (fColumns
== 8 && fRows
== 32)
719 if (fColumns
== 16 && fRows
== 16)
720 return B_CELLS_16x16
;
722 if (fColumns
== 32 && fRows
== 8)
725 if (fColumns
== 64 && fRows
== 4)
733 BColorControl::WindowActivated(bool state
)
735 BControl::WindowActivated(state
);
740 BColorControl::KeyDown(const char* bytes
, int32 numBytes
)
742 if (IsFocus() && !fPaletteMode
&& numBytes
== 1) {
743 rgb_color color
= ValueAsColor();
748 int16 oldFocus
= fFocusedRamp
;
750 if (fFocusedRamp
< 1)
753 _InvalidateSelector(oldFocus
, color
, true);
754 _InvalidateSelector(fFocusedRamp
, color
, true);
760 int16 oldFocus
= fFocusedRamp
;
762 if (fFocusedRamp
> 3)
765 _InvalidateSelector(oldFocus
, color
, true);
766 _InvalidateSelector(fFocusedRamp
, color
, true);
772 bool goFaster
= false;
773 if (Window() != NULL
) {
774 BMessage
* message
= Window()->CurrentMessage();
775 if (message
!= NULL
&& message
->what
== B_KEY_DOWN
) {
777 if (message
->FindInt32("be:key_repeat", &repeats
)
778 == B_OK
&& repeats
> 4) {
784 if (fFocusedRamp
== 1) {
785 if (goFaster
&& color
.red
>= 5)
787 else if (color
.red
> 0)
789 } else if (fFocusedRamp
== 2) {
790 if (goFaster
&& color
.green
>= 5)
792 else if (color
.green
> 0)
794 } else if (fFocusedRamp
== 3) {
795 if (goFaster
&& color
.blue
>= 5)
797 else if (color
.blue
> 0)
808 bool goFaster
= false;
809 if (Window() != NULL
) {
810 BMessage
* message
= Window()->CurrentMessage();
811 if (message
!= NULL
&& message
->what
== B_KEY_DOWN
) {
813 if (message
->FindInt32("be:key_repeat", &repeats
)
814 == B_OK
&& repeats
> 4) {
820 if (fFocusedRamp
== 1) {
821 if (goFaster
&& color
.red
<= 250)
823 else if (color
.red
< 255)
825 } else if (fFocusedRamp
== 2) {
826 if (goFaster
&& color
.green
<= 250)
828 else if (color
.green
< 255)
830 } else if (fFocusedRamp
== 3) {
831 if (goFaster
&& color
.blue
<= 250)
833 else if (color
.blue
< 255)
844 BControl::KeyDown(bytes
, numBytes
);
849 BColorControl::MouseUp(BPoint point
)
857 BColorControl::MouseDown(BPoint point
)
861 if (!fPaletteFrame
.Contains(point
))
865 int col
= (int)((point
.x
- fPaletteFrame
.left
) / fCellSize
);
866 int row
= (int)((point
.y
- fPaletteFrame
.top
) / fCellSize
);
867 int colorIndex
= row
* fColumns
+ col
;
868 if (colorIndex
>= 0 && colorIndex
< 256) {
869 fSelectedPaletteColorIndex
= colorIndex
;
870 SetValue(system_colors()->color_list
[colorIndex
]);
873 rgb_color color
= ValueAsColor();
875 uint8 shade
= (unsigned char)max_c(0,
876 min_c((point
.x
- _RampFrame(0).left
) * 255
877 / _RampFrame(0).Width(), 255));
879 if (_RampFrame(0).Contains(point
)) {
880 color
.red
= color
.green
= color
.blue
= shade
;
882 } else if (_RampFrame(1).Contains(point
)) {
885 } else if (_RampFrame(2).Contains(point
)) {
888 } else if (_RampFrame(3).Contains(point
)) {
899 SetMouseEventMask(B_POINTER_EVENTS
,
900 B_NO_POINTER_HISTORY
| B_LOCK_WINDOW_FOCUS
);
905 BColorControl::MouseMoved(BPoint point
, uint32 transit
,
906 const BMessage
* message
)
911 if (fPaletteMode
&& fPaletteFrame
.Contains(point
)) {
912 int col
= (int)((point
.x
- fPaletteFrame
.left
) / fCellSize
);
913 int row
= (int)((point
.y
- fPaletteFrame
.top
) / fCellSize
);
914 int colorIndex
= row
* fColumns
+ col
;
915 if (colorIndex
>= 0 && colorIndex
< 256) {
916 fSelectedPaletteColorIndex
= colorIndex
;
917 SetValue(system_colors()->color_list
[colorIndex
]);
920 if (fClickedRamp
< 0 || fClickedRamp
> 3)
923 rgb_color color
= ValueAsColor();
925 uint8 shade
= (unsigned char)max_c(0,
926 min_c((point
.x
- _RampFrame(0).left
) * 255
927 / _RampFrame(0).Width(), 255));
929 if (fClickedRamp
== 0)
930 color
.red
= color
.green
= color
.blue
= shade
;
931 else if (fClickedRamp
== 1)
933 else if (fClickedRamp
== 2)
935 else if (fClickedRamp
== 3)
946 BColorControl::DetachedFromWindow()
948 BControl::DetachedFromWindow();
953 BColorControl::GetPreferredSize(float* _width
, float* _height
)
955 BRect rect
= _PaletteFrame();
957 if (rect
.Height() < fBlueText
->Frame().bottom
) {
958 // adjust the height to fit
959 rect
.bottom
= fBlueText
->Frame().bottom
;
963 *_width
= rect
.Width() + kTextFieldsHSpacing
964 + fRedText
->Bounds().Width();
968 *_height
= rect
.Height();
973 BColorControl::ResizeToPreferred()
976 BControl::ResizeToPreferred();
981 BColorControl::Invoke(BMessage
* message
)
983 return BControl::Invoke(message
);
988 BColorControl::FrameMoved(BPoint newPosition
)
990 BControl::FrameMoved(newPosition
);
995 BColorControl::FrameResized(float newWidth
, float newHeight
)
997 BControl::FrameResized(newWidth
, newHeight
);
1002 BColorControl::ResolveSpecifier(BMessage
* message
, int32 index
,
1003 BMessage
* specifier
, int32 form
, const char* property
)
1005 return BControl::ResolveSpecifier(message
, index
, specifier
, form
,
1011 BColorControl::GetSupportedSuites(BMessage
* data
)
1013 return BControl::GetSupportedSuites(data
);
1018 BColorControl::MakeFocus(bool focused
)
1020 fFocusedRamp
= !fPaletteMode
&& focused
? 1 : -1;
1021 BControl::MakeFocus(focused
);
1026 BColorControl::AllAttached()
1028 BControl::AllAttached();
1033 BColorControl::AllDetached()
1035 BControl::AllDetached();
1040 BColorControl::SetIcon(const BBitmap
* icon
, uint32 flags
)
1042 return BControl::SetIcon(icon
, flags
);
1047 BColorControl::Perform(perform_code code
, void* _data
)
1050 case PERFORM_CODE_MIN_SIZE
:
1051 ((perform_data_min_size
*)_data
)->return_value
1052 = BColorControl::MinSize();
1055 case PERFORM_CODE_MAX_SIZE
:
1056 ((perform_data_max_size
*)_data
)->return_value
1057 = BColorControl::MaxSize();
1060 case PERFORM_CODE_PREFERRED_SIZE
:
1061 ((perform_data_preferred_size
*)_data
)->return_value
1062 = BColorControl::PreferredSize();
1065 case PERFORM_CODE_LAYOUT_ALIGNMENT
:
1066 ((perform_data_layout_alignment
*)_data
)->return_value
1067 = BColorControl::LayoutAlignment();
1070 case PERFORM_CODE_HAS_HEIGHT_FOR_WIDTH
:
1071 ((perform_data_has_height_for_width
*)_data
)->return_value
1072 = BColorControl::HasHeightForWidth();
1075 case PERFORM_CODE_GET_HEIGHT_FOR_WIDTH
:
1077 perform_data_get_height_for_width
* data
1078 = (perform_data_get_height_for_width
*)_data
;
1079 BColorControl::GetHeightForWidth(data
->width
, &data
->min
,
1080 &data
->max
, &data
->preferred
);
1084 case PERFORM_CODE_SET_LAYOUT
:
1086 perform_data_set_layout
* data
= (perform_data_set_layout
*)_data
;
1087 BColorControl::SetLayout(data
->layout
);
1091 case PERFORM_CODE_LAYOUT_INVALIDATED
:
1093 perform_data_layout_invalidated
* data
1094 = (perform_data_layout_invalidated
*)_data
;
1095 BColorControl::LayoutInvalidated(data
->descendants
);
1099 case PERFORM_CODE_DO_LAYOUT
:
1101 BColorControl::DoLayout();
1105 case PERFORM_CODE_SET_ICON
:
1107 perform_data_set_icon
* data
= (perform_data_set_icon
*)_data
;
1108 return BColorControl::SetIcon(data
->icon
, data
->flags
);
1112 return BControl::Perform(code
, _data
);
1116 void BColorControl::_ReservedColorControl1() {}
1117 void BColorControl::_ReservedColorControl2() {}
1118 void BColorControl::_ReservedColorControl3() {}
1119 void BColorControl::_ReservedColorControl4() {}
1123 BColorControl::operator=(const BColorControl
&)