IOM/ColorField: Get rid of useless threads

Generate bitmap in Draw() lazily. Removed liblayout stuff. Support for
Haiku layout methods. Fixed some bugs with selecting red/green/blue
as fixed values (ticket #10574).
This commit is contained in:
Stephan Aßmus 2015-05-09 22:17:22 +02:00
parent 44046ca5cd
commit 0ebc8ac6ef
2 changed files with 380 additions and 435 deletions

View File

@ -1,9 +1,9 @@
/*
/*
* Copyright 2001 Werner Freytag - please read to the LICENSE file
*
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
* All rights reserved.
*
*
*/
#include "ColorField.h"
@ -11,16 +11,17 @@
#include <stdio.h>
#include <Bitmap.h>
#include <ControlLook.h>
#include <LayoutUtils.h>
#include <OS.h>
#include <Region.h>
#include <Window.h>
#include "selected_color_mode.h"
#include "support_ui.h"
#include "rgb_hsv.h"
#define round(x) (int)(x+.5)
#define round(x) (int)(x +.5)
enum {
MSG_UPDATE = 'Updt',
@ -30,105 +31,77 @@ enum {
#define MAX_Y 255
// constructor
ColorField::ColorField(BPoint offset_point, selected_color_mode mode,
float fixed_value, orientation orient)
: BControl(BRect(0.0, 0.0, MAX_X + 4.0, MAX_Y + 4.0).OffsetToCopy(offset_point),
"ColorField", "", new BMessage(MSG_COLOR_FIELD),
B_FOLLOW_LEFT | B_FOLLOW_TOP,
B_WILL_DRAW | B_FRAME_EVENTS),
fMode(mode),
fFixedValue(fixed_value),
fOrientation(orient),
fMarkerPosition(0.0, 0.0),
fLastMarkerPosition(-1.0, -1.0),
fMouseDown(false),
fUpdateThread(B_ERROR),
fUpdatePort(B_ERROR)
ColorField::ColorField(BPoint offsetPoint, SelectedColorMode mode,
float fixedValue, orientation orient, border_style border)
: BControl(BRect(0.0, 0.0, MAX_X + 4.0, MAX_Y + 4.0)
.OffsetToCopy(offsetPoint),
"ColorField", "", new BMessage(MSG_COLOR_FIELD),
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS)
{
SetViewColor(B_TRANSPARENT_32_BIT);
_Init(mode, fixedValue, orient, border);
FrameResized(Bounds().Width(), Bounds().Height());
}
for (int i = 0; i < 2; ++i) {
fBgBitmap[i] = new BBitmap(Bounds(), B_RGB32, true);
fBgBitmap[i]->Lock();
fBgView[i] = new BView(Bounds(), "", B_FOLLOW_NONE, B_WILL_DRAW);
fBgBitmap[i]->AddChild(fBgView[i]);
fBgView[i]->SetOrigin(2.0, 2.0);
fBgBitmap[i]->Unlock();
}
_DrawBorder();
fUpdatePort = create_port(100, "color field update port");
fUpdateThread = spawn_thread(ColorField::_UpdateThread,
"color field update thread", 10, this);
resume_thread(fUpdateThread);
// Update(3);
// constructor
ColorField::ColorField(SelectedColorMode mode, float fixedValue,
orientation orient, border_style border)
: BControl("ColorField", "", new BMessage(MSG_COLOR_FIELD),
B_WILL_DRAW | B_FRAME_EVENTS)
{
_Init(mode, fixedValue, orient, border);
}
// destructor
ColorField::~ColorField()
{
if (fUpdatePort >= B_OK)
delete_port(fUpdatePort);
if (fUpdateThread >= B_OK)
kill_thread(fUpdateThread);
delete fBgBitmap[0];
delete fBgBitmap[1];
delete fBitmap;
}
#if LIB_LAYOUT
// layoutprefs
minimax
ColorField::layoutprefs()
// MinSize
BSize
ColorField::MinSize()
{
if (fOrientation == B_VERTICAL) {
mpm.mini.x = 4 + MAX_X / 17;
mpm.mini.y = 4 + MAX_Y / 5;
} else {
mpm.mini.x = 4 + MAX_X / 5;
mpm.mini.y = 4 + MAX_Y / 17;
}
mpm.maxi.x = 4 + MAX_X;
mpm.maxi.y = 4 + MAX_Y;
BSize minSize;
if (fOrientation == B_VERTICAL)
minSize = BSize(4 + MAX_X / 17, 4 + MAX_Y / 5);
else
minSize = BSize(4 + MAX_X / 5, 4 + MAX_Y / 17);
mpm.weight = 1.0;
return mpm;
return BLayoutUtils::ComposeSize(ExplicitMinSize(), minSize);
}
// layout
BRect
ColorField::layout(BRect frame)
// PreferredSize
BSize
ColorField::PreferredSize()
{
MoveTo(frame.LeftTop());
// reposition marker
fMarkerPosition.x *= (frame.Width() - 4.0) / (Bounds().Width() - 4.0);
fMarkerPosition.y *= (frame.Height() - 4.0) / (Bounds().Height() - 4.0);
ResizeTo(frame.Width(), frame.Height());
_DrawBorder();
Update(3);
return Frame();
return BLayoutUtils::ComposeSize(ExplicitPreferredSize(), MinSize());
}
// MaxSize
BSize
ColorField::MaxSize()
{
BSize maxSize(4 + MAX_X, 4 + MAX_Y);
return BLayoutUtils::ComposeSize(ExplicitMaxSize(), maxSize);
// return BLayoutUtils::ComposeSize(ExplicitMaxSize(),
// BSize(B_SIZE_UNLIMITED, B_SIZE_UNLIMITED));
}
#endif // LIB_LAYOUT
// Invoke
status_t
ColorField::Invoke(BMessage *msg)
{
if (!msg)
msg = Message();
ColorField::Invoke(BMessage* message)
{
if (message == NULL)
message = Message();
msg->RemoveName("value");
if (message == NULL)
return BControl::Invoke(message);
message->RemoveName("value");
float v1 = 0;
float v2 = 0;
switch (fMode) {
case R_SELECTED:
case G_SELECTED:
@ -146,7 +119,7 @@ ColorField::Invoke(BMessage *msg)
v2 = 1.0 - fMarkerPosition.x / Width();
}
break;
case S_SELECTED:
case V_SELECTED:
v1 = fMarkerPosition.x / Width() * 6.0;
@ -154,38 +127,73 @@ ColorField::Invoke(BMessage *msg)
break;
}
msg->AddFloat("value", v1);
msg->AddFloat("value", v2);
return BControl::Invoke(msg);
message->AddFloat("value", v1);
message->AddFloat("value", v2);
return BControl::Invoke(message);
}
// AttachedToWindow
void
ColorField::AttachedToWindow()
{
Update(3);
}
// Draw
void
ColorField::Draw(BRect updateRect)
{
Update(0);
if (fBitmapDirty && fBitmap != NULL) {
_FillBitmap(fBitmap, fMode, fFixedValue, fOrientation);
fBitmapDirty = false;
}
BRect bounds = Bounds();
// Frame
if (fBorderStyle == B_FANCY_BORDER) {
rgb_color color = LowColor();
be_control_look->DrawTextControlBorder(this, bounds, updateRect,
color);
BRegion region(bounds);
ConstrainClippingRegion(&region);
}
// Color field fill
if (fBitmap != NULL)
DrawBitmap(fBitmap, bounds.LeftTop());
else {
SetHighColor(255, 0, 0);
FillRect(bounds);
}
// Marker
SetHighColor(0, 0, 0);
StrokeEllipse(fMarkerPosition + bounds.LeftTop(), 5.0, 5.0);
SetHighColor(255.0, 255.0, 255.0);
StrokeEllipse(fMarkerPosition + bounds.LeftTop(), 4.0, 4.0);
}
// FrameResized
void
ColorField::FrameResized(float width, float height)
{
BRect r = _BitmapRect();
_AllocBitmap(r.IntegerWidth() + 1, r.IntegerHeight() + 1);
Invalidate();
}
// MouseDown
void
ColorField::MouseDown(BPoint where)
{
Window()->Activate();
fMouseDown = true;
SetMouseEventMask(B_POINTER_EVENTS, B_SUSPEND_VIEW_FOCUS|B_LOCK_WINDOW_FOCUS );
PositionMarkerAt( where );
SetMouseEventMask(B_POINTER_EVENTS,
B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
PositionMarkerAt(where);
if (Message()) {
if (Message() != NULL) {
BMessage message(*Message());
message.AddBool("begin", true);
Invoke(&message);
@ -202,83 +210,36 @@ ColorField::MouseUp(BPoint where)
// MouseMoved
void
ColorField::MouseMoved(BPoint where, uint32 code, const BMessage *a_message)
ColorField::MouseMoved(BPoint where, uint32 transit,
const BMessage* dragMessage)
{
if (a_message || !fMouseDown ) {
BView::MouseMoved( where, code, a_message);
if (dragMessage != NULL || !fMouseDown ) {
BView::MouseMoved(where, transit, dragMessage);
return;
}
PositionMarkerAt(where);
Invoke();
}
// Update
void
ColorField::Update(int depth)
{
// depth: 0 = only onscreen redraw, 1 = only cursor 1, 2 = full update part 2, 3 = full
if (depth == 3) {
write_port(fUpdatePort, MSG_UPDATE, NULL, 0);
return;
}
if (depth >= 1) {
fBgBitmap[1]->Lock();
fBgView[1]->DrawBitmap( fBgBitmap[0], BPoint(-2.0, -2.0) );
fBgView[1]->SetHighColor( 0, 0, 0 );
fBgView[1]->StrokeEllipse( fMarkerPosition, 5.0, 5.0 );
fBgView[1]->SetHighColor( 255.0, 255.0, 255.0 );
fBgView[1]->StrokeEllipse( fMarkerPosition, 4.0, 4.0 );
fBgView[1]->Sync();
fBgBitmap[1]->Unlock();
}
if (depth != 0 && depth != 2 && fMarkerPosition != fLastMarkerPosition) {
fBgBitmap[1]->Lock();
DrawBitmap( fBgBitmap[1],
BRect(-3.0, -3.0, 7.0, 7.0).OffsetByCopy(fMarkerPosition),
BRect(-3.0, -3.0, 7.0, 7.0).OffsetByCopy(fMarkerPosition));
DrawBitmap( fBgBitmap[1],
BRect(-3.0, -3.0, 7.0, 7.0).OffsetByCopy(fLastMarkerPosition),
BRect(-3.0, -3.0, 7.0, 7.0).OffsetByCopy(fLastMarkerPosition));
fLastMarkerPosition = fMarkerPosition;
fBgBitmap[1]->Unlock();
} else
DrawBitmap(fBgBitmap[1]);
}
// SetModeAndValue
void
ColorField::SetModeAndValue(selected_color_mode mode, float fixed_value)
ColorField::SetModeAndValue(SelectedColorMode mode, float fixedValue)
{
float R(0), G(0), B(0);
float H(0), S(0), V(0);
fBgBitmap[0]->Lock();
float width = Width();
float height = Height();
switch (fMode) {
case R_SELECTED: {
R = fFixedValue * 255;
G = round(fMarkerPosition.x / width * 255.0);
B = round(255.0 - fMarkerPosition.y / height * 255.0);
}; break;
case G_SELECTED: {
R = round(fMarkerPosition.x / width * 255.0);
G = fFixedValue * 255;
@ -314,17 +275,14 @@ ColorField::SetModeAndValue(selected_color_mode mode, float fixed_value)
HSV_to_RGB(H, S, V, R, G, B);
R *= 255.0; G *= 255.0; B *= 255.0;
}
rgb_color color = { (uint8)round(R), (uint8)round(G), (uint8)round(B),
255 };
fBgBitmap[0]->Unlock();
rgb_color color = { round(R), round(G), round(B), 255 };
if (fFixedValue != fixed_value || fMode != mode) {
fFixedValue = fixed_value;
if (fFixedValue != fixedValue || fMode != mode) {
fFixedValue = fixedValue;
fMode = mode;
Update(3);
_Update();
}
SetMarkerToColor(color);
@ -332,11 +290,11 @@ ColorField::SetModeAndValue(selected_color_mode mode, float fixed_value)
// SetFixedValue
void
ColorField::SetFixedValue(float fixed_value)
ColorField::SetFixedValue(float fixedValue)
{
if (fFixedValue != fixed_value) {
fFixedValue = fixed_value;
Update(3);
if (fFixedValue != fixedValue) {
fFixedValue = fixedValue;
_Update();
}
}
@ -345,285 +303,269 @@ void
ColorField::SetMarkerToColor(rgb_color color)
{
float h, s, v;
RGB_to_HSV( (float)color.red / 255.0, (float)color.green / 255.0, (float)color.blue / 255.0, h, s, v );
RGB_to_HSV(color.red / 255.0, color.green / 255.0, color.blue / 255.0,
h, s, v );
fLastMarkerPosition = fMarkerPosition;
float width = Width();
float height = Height();
switch (fMode) {
case R_SELECTED: {
case R_SELECTED:
fMarkerPosition = BPoint(color.green / 255.0 * width,
(255.0 - color.blue) / 255.0 * height);
} break;
case G_SELECTED: {
fMarkerPosition = BPoint(color.red / 255.0 * width,
(255.0 - color.blue) / 255.0 * height);
} break;
(255.0 - color.blue) / 255.0 * height);
break;
case B_SELECTED: {
case G_SELECTED:
fMarkerPosition = BPoint(color.red / 255.0 * width,
(255.0 - color.green) / 255.0 * height);
} break;
case H_SELECTED: {
(255.0 - color.blue) / 255.0 * height);
break;
case B_SELECTED:
fMarkerPosition = BPoint(color.red / 255.0 * width,
(255.0 - color.green) / 255.0 * height);
break;
case H_SELECTED:
if (fOrientation == B_VERTICAL)
fMarkerPosition = BPoint(s * width, height - v * height);
else
fMarkerPosition = BPoint(width - v * width, s * height);
} break;
case S_SELECTED: {
fMarkerPosition = BPoint(h / 6.0 * width, height - v * height);
} break;
break;
case V_SELECTED: {
case S_SELECTED:
fMarkerPosition = BPoint(h / 6.0 * width, height - v * height);
break;
case V_SELECTED:
fMarkerPosition = BPoint( h / 6.0 * width, height - s * height);
} break;
break;
}
Update(1);
Invalidate();
}
// PositionMarkerAt
void
ColorField::PositionMarkerAt( BPoint where )
ColorField::PositionMarkerAt(BPoint where)
{
BRect rect = Bounds().InsetByCopy( 2.0, 2.0 ).OffsetToCopy(0.0, 0.0);
where = BPoint(max_c(min_c(where.x - 2.0, rect.right), 0.0),
max_c(min_c(where.y - 2.0, rect.bottom), 0.0) );
BRect rect = _BitmapRect();
where.ConstrainTo(rect);
where -= rect.LeftTop();
fLastMarkerPosition = fMarkerPosition;
fMarkerPosition = where;
Update(1);
Invalidate();
}
// Width
float
ColorField::Width() const
{
return Bounds().IntegerWidth() + 1 - 4;
return _BitmapRect().IntegerWidth() + 1;
}
// Height
float
ColorField::Height() const
{
return Bounds().IntegerHeight() + 1 - 4;
return _BitmapRect().IntegerHeight() + 1;
}
// set_bits
void
static inline void
set_bits(uint8* bits, uint8 r, uint8 g, uint8 b)
{
bits[0] = b;
bits[1] = g;
bits[2] = r;
// bits[3] = 255;
bits[3] = 255;
}
// _UpdateThread
status_t
ColorField::_UpdateThread(void* data)
{
// initializing
ColorField* colorField = (ColorField *)data;
bool looperLocked = colorField->LockLooper();
BBitmap* bitmap = colorField->fBgBitmap[0];
port_id port = colorField->fUpdatePort;
orientation orient = colorField->fOrientation;
if (looperLocked)
colorField->UnlockLooper();
float h, s, v, r, g, b;
int R, G, B;
// drawing
int32 msg_code;
char msg_buffer;
while (true) {
port_info info;
do {
read_port(port, &msg_code, &msg_buffer, sizeof(msg_buffer));
get_port_info(port, &info);
} while (info.queue_count);
if (colorField->LockLooper()) {
uint colormode = colorField->fMode;
float fixedvalue = colorField->fFixedValue;
int width = (int)colorField->Width();
int height = (int)colorField->Height();
colorField->UnlockLooper();
bitmap->Lock();
//bigtime_t now = system_time();
uint8* bits = (uint8*)bitmap->Bits();
uint32 bpr = bitmap->BytesPerRow();
// offset 2 pixels from top and left
bits += 2 * 4 + 2 * bpr;
switch (colormode) {
case R_SELECTED: {
R = round(fixedvalue * 255);
for (int y = height; y >= 0; y--) {
uint8* bitsHandle = bits;
int B = y / height * 255;
for (int x = 0; x <= width; ++x) {
int G = x / width * 255;
set_bits(bitsHandle, R, G, B);
bitsHandle += 4;
}
bits += bpr;
}
}; break;
case G_SELECTED: {
G = round(fixedvalue * 255);
for (int y = height; y >= 0; y--) {
uint8* bitsHandle = bits;
int B = y / height * 255;
for (int x = 0; x <= width; ++x) {
int R = x / width * 255;
set_bits(bitsHandle, R, G, B);
bitsHandle += 4;
}
bits += bpr;
}
}; break;
case B_SELECTED: {
B = round(fixedvalue * 255);
for (int y = height; y >= 0; y--) {
uint8* bitsHandle = bits;
int G = y / height * 255;
for (int x = 0; x <= width; ++x) {
int R = x / width * 255;
set_bits(bitsHandle, R, G, B);
bitsHandle += 4;
}
bits += bpr;
}
}; break;
case H_SELECTED: {
h = fixedvalue;
if (orient == B_VERTICAL) {
for (int y = 0; y <= height; ++y) {
v = (float)(height - y) / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
s = (float)x / width;
HSV_to_RGB( h, s, v, r, g, b );
set_bits(bitsHandle, round(r * 255.0), round(g * 255.0), round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
} else {
for (int y = 0; y <= height; ++y) {
s = (float)y / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
v = (float)(width - x) / width;
HSV_to_RGB( h, s, v, r, g, b );
set_bits(bitsHandle, round(r * 255.0), round(g * 255.0), round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
}
}; break;
case S_SELECTED: {
s = fixedvalue;
for (int y = 0; y <= height; ++y) {
v = (float)(height - y) / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
h = 6.0 / width * x;
HSV_to_RGB( h, s, v, r, g, b );
set_bits(bitsHandle, round(r * 255.0), round(g * 255.0), round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
}; break;
case V_SELECTED: {
v = fixedvalue;
for (int y = 0; y <= height; ++y) {
s = (float)(height - y) / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
h = 6.0 / width * x;
HSV_to_RGB( h, s, v, r, g, b );
set_bits(bitsHandle, round(r * 255.0), round(g * 255.0), round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
}; break;
}
//printf("color field update: %lld\n", system_time() - now);
bitmap->Unlock();
if (colorField->LockLooper()) {
colorField->Update(2);
colorField->UnlockLooper();
}
}
}
return B_OK;
}
// _DrawBorder
// _Init
void
ColorField::_DrawBorder()
ColorField::_Init(SelectedColorMode mode, float fixedValue,
orientation orient, border_style border)
{
bool looperLocked = LockLooper();
fBgBitmap[1]->Lock();
fMode = mode;
fFixedValue = fixedValue;
fOrientation = orient;
fBorderStyle = border;
rgb_color background = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color shadow = tint_color(background, B_DARKEN_1_TINT);
rgb_color darkShadow = tint_color(background, B_DARKEN_3_TINT);
rgb_color light = tint_color(background, B_LIGHTEN_MAX_TINT);
fMarkerPosition = BPoint(0.0, 0.0);
fLastMarkerPosition = BPoint(-1.0, -1.0);
fMouseDown = false;
BRect r(fBgView[1]->Bounds());
r.OffsetBy(-2.0, -2.0);
BRegion region(r);
fBgView[1]->ConstrainClippingRegion(&region);
fBitmap = NULL;
fBitmapDirty = true;
r = Bounds();
r.OffsetBy(-2.0, -2.0);
stroke_frame(fBgView[1], r, shadow, shadow, light, light);
r.InsetBy(1.0, 1.0);
stroke_frame(fBgView[1], r, darkShadow, darkShadow, background, background);
r.InsetBy(1.0, 1.0);
region.Set(r);
fBgView[1]->ConstrainClippingRegion(&region);
fBgBitmap[1]->Unlock();
if (looperLocked)
UnlockLooper();
SetViewColor(B_TRANSPARENT_COLOR);
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
}
// _AllocBitmap
void
ColorField::_AllocBitmap(int32 width, int32 height)
{
if (width < 2 || height < 2)
return;
delete fBitmap;
fBitmap = new BBitmap(BRect(0, 0, width - 1, height - 1), 0, B_RGB32);
fBitmapDirty = true;
}
// _Update
void
ColorField::_Update()
{
fBitmapDirty = true;
Invalidate();
}
// _BitmapRect
BRect
ColorField::_BitmapRect() const
{
BRect r = Bounds();
if (fBorderStyle == B_FANCY_BORDER)
r.InsetBy(2, 2);
return r;
}
// _FillBitmap
void
ColorField::_FillBitmap(BBitmap* bitmap, SelectedColorMode mode,
float fixedValue, orientation orient) const
{
int32 width = bitmap->Bounds().IntegerWidth();
int32 height = bitmap->Bounds().IntegerHeight();
uint32 bpr = bitmap->BytesPerRow();
//bigtime_t now = system_time();
uint8* bits = (uint8*)bitmap->Bits();
float r = 0;
float g = 0;
float b = 0;
float h;
float s;
float v;
switch (mode) {
case R_SELECTED:
r = round(fixedValue * 255);
for (int y = height; y >= 0; y--) {
uint8* bitsHandle = bits;
b = y * 255 / height;
for (int32 x = 0; x <= width; x++) {
g = x * 255 / width;
set_bits(bitsHandle, (uint8)r, (uint8)g, (uint8)b);
bitsHandle += 4;
}
bits += bpr;
}
break;
case G_SELECTED:
g = round(fixedValue * 255);
for (int y = height; y >= 0; y--) {
uint8* bitsHandle = bits;
b = y * 255 / height;
for (int x = 0; x <= width; x++) {
r = x * 255 / width;
set_bits(bitsHandle, (uint8)r, (uint8)g, (uint8)b);
bitsHandle += 4;
}
bits += bpr;
}
break;
case B_SELECTED:
b = round(fixedValue * 255);
for (int y = height; y >= 0; y--) {
uint8* bitsHandle = bits;
g = y * 255 / height;
for (int x = 0; x <= width; ++x) {
r = x * 255 / width;
set_bits(bitsHandle, (uint8)r, (uint8)g, (uint8)b);
bitsHandle += 4;
}
bits += bpr;
}
break;
case H_SELECTED:
h = fixedValue;
if (orient == B_VERTICAL) {
for (int y = 0; y <= height; ++y) {
v = (float)(height - y) / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
s = (float)x / width;
HSV_to_RGB(h, s, v, r, g, b);
set_bits(bitsHandle,
round(r * 255.0),
round(g * 255.0),
round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
} else {
for (int y = 0; y <= height; ++y) {
s = (float)y / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
v = (float)(width - x) / width;
HSV_to_RGB(h, s, v, r, g, b);
set_bits(bitsHandle,
round(r * 255.0),
round(g * 255.0),
round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
}
break;
case S_SELECTED:
s = fixedValue;
for (int y = 0; y <= height; ++y) {
v = (float)(height - y) / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
h = 6.0 / width * x;
HSV_to_RGB(h, s, v, r, g, b);
set_bits(bitsHandle,
round(r * 255.0),
round(g * 255.0),
round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
break;
case V_SELECTED:
v = fixedValue;
for (int y = 0; y <= height; ++y) {
s = (float)(height - y) / height;
uint8* bitsHandle = bits;
for (int x = 0; x <= width; ++x) {
h = 6.0 / width * x;
HSV_to_RGB(h, s, v, r, g, b);
set_bits(bitsHandle,
round(r * 255.0),
round(g * 255.0),
round(b * 255.0));
bitsHandle += 4;
}
bits += bpr;
}
break;
}
}

View File

@ -1,21 +1,17 @@
/*
/*
* Copyright 2001 Werner Freytag - please read to the LICENSE file
*
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
* All rights reserved.
*
*
*/
#ifndef _COLOR_FIELD_H
#define _COLOR_FIELD_H
#ifndef COLOR_FIELD_H
#define COLOR_FIELD_H
#include <Control.h>
#if LIB_LAYOUT
# include <layout.h>
#endif
#include "selected_color_mode.h"
#include "SelectedColorMode.h"
enum {
MSG_COLOR_FIELD = 'ColF',
@ -23,69 +19,76 @@ enum {
class BBitmap;
class ColorField :
#if LIB_LAYOUT
public MView,
#endif
public BControl {
public:
class ColorField : public BControl {
public:
ColorField(BPoint offset_point,
selected_color_mode mode,
float fixed_value,
orientation orient = B_VERTICAL);
SelectedColorMode mode, float fixedValue,
orientation orient = B_VERTICAL,
border_style border = B_FANCY_BORDER);
ColorField(SelectedColorMode mode,
float fixedValue,
orientation orient = B_VERTICAL,
border_style border = B_FANCY_BORDER);
virtual ~ColorField();
// MView
#if LIB_LAYOUT
virtual minimax layoutprefs();
virtual BRect layout(BRect frame);
#endif
// BControl interface
virtual BSize MinSize();
virtual BSize PreferredSize();
virtual BSize MaxSize();
// BControl
virtual status_t Invoke(BMessage *msg = NULL);
virtual status_t Invoke(BMessage* message = NULL);
virtual void AttachedToWindow();
virtual void Draw(BRect updateRect);
virtual void FrameResized(float width, float height);
virtual void MouseDown(BPoint where);
virtual void MouseUp(BPoint where);
virtual void MouseMoved(BPoint where, uint32 code,
const BMessage* message);
const BMessage* dragMessage);
// ColorField
void Update(int depth);
void SetModeAndValue(selected_color_mode mode, float fixed_value);
void SetFixedValue(float fixed_value);
// ColorField
void SetModeAndValue(SelectedColorMode mode,
float fixedValue);
void SetFixedValue(float fixedValue);
float FixedValue() const
{ return fFixedValue; }
void SetMarkerToColor( rgb_color color );
void PositionMarkerAt( BPoint where );
void SetMarkerToColor(rgb_color color);
void PositionMarkerAt(BPoint where);
float Width() const;
float Height() const;
bool IsTracking() const
{ return fMouseDown; }
private:
static status_t _UpdateThread(void* data);
void _DrawBorder();
private:
void _Init(SelectedColorMode mode,
float fixedValue, orientation orient,
border_style border);
selected_color_mode fMode;
void _AllocBitmap(int32 width, int32 height);
void _Update();
BRect _BitmapRect() const;
void _FillBitmap(BBitmap* bitmap,
SelectedColorMode mode,
float fixedValue, orientation orient) const;
private:
SelectedColorMode fMode;
float fFixedValue;
orientation fOrientation;
border_style fBorderStyle;
BPoint fMarkerPosition;
BPoint fLastMarkerPosition;
bool fMouseDown;
BBitmap* fBgBitmap[2];
BView* fBgView[2];
thread_id fUpdateThread;
port_id fUpdatePort;
BBitmap* fBitmap;
bool fBitmapDirty;
};
#endif
#endif // COLOR_FIELD_H