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:
parent
44046ca5cd
commit
0ebc8ac6ef
@ -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(®ion);
|
||||
}
|
||||
|
||||
// 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(®ion);
|
||||
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(®ion);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user