* added a color picker panel
(heavily modified, but originally based on Colors! by Werner Freytag) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17915 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d134f89267
commit
31e2089106
@ -242,6 +242,7 @@ CanvasView::_AllocBackBitmap(float width, float height)
|
||||
fOffsreenView->SetFont(&font);
|
||||
fOffsreenView->SetHighColor(HighColor());
|
||||
fOffsreenView->SetLowColor(LowColor());
|
||||
fOffsreenView->SetFlags(Flags());
|
||||
fOffsreenBitmap->AddChild(fOffsreenView);
|
||||
} else {
|
||||
_FreeBackBitmap();
|
||||
|
@ -15,6 +15,9 @@
|
||||
#include "Document.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
// testing:
|
||||
#include "ColorPickerPanel.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// constructor
|
||||
@ -68,6 +71,11 @@ IconEditorApp::ReadyToRun()
|
||||
{
|
||||
fMainWindow = new MainWindow(this, fDocument);
|
||||
fMainWindow->Show();
|
||||
|
||||
ColorPickerPanel* panel = new ColorPickerPanel(
|
||||
BRect(80, 80, 200, 200),
|
||||
(rgb_color){ 100, 200, 150, 255 });
|
||||
panel->Show();
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@ local sourceDirs =
|
||||
generic/command
|
||||
generic/gui
|
||||
generic/gui/panel
|
||||
generic/gui/panel/color_picker
|
||||
generic/gui/popup_control
|
||||
generic/gui/scrollview
|
||||
generic/gui/stateview
|
||||
@ -43,6 +44,13 @@ Application Icon-O-Matic :
|
||||
Selection.cpp
|
||||
# generic/gui
|
||||
# generic/gui/panel
|
||||
Panel.cpp
|
||||
# generic/gui/panel/color_picker
|
||||
ColorField.cpp
|
||||
ColorPickerPanel.cpp
|
||||
ColorPickerView.cpp
|
||||
ColorPreview.cpp
|
||||
ColorSlider.cpp
|
||||
# generic/gui/popup_control
|
||||
# generic/gui/scrollview
|
||||
# generic/gui/stateview
|
||||
@ -57,6 +65,7 @@ Application Icon-O-Matic :
|
||||
# generic/support
|
||||
RWLocker.cpp
|
||||
support.cpp
|
||||
support_ui.cpp
|
||||
# gradient
|
||||
Gradient.cpp
|
||||
# shape
|
||||
|
@ -0,0 +1,627 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.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)
|
||||
|
||||
enum {
|
||||
MSG_UPDATE = 'Updt',
|
||||
};
|
||||
|
||||
#define MAX_X 255
|
||||
#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)
|
||||
{
|
||||
SetViewColor(B_TRANSPARENT_32_BIT);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// destructor
|
||||
ColorField::~ColorField()
|
||||
{
|
||||
if (fUpdatePort >= B_OK)
|
||||
delete_port(fUpdatePort);
|
||||
if (fUpdateThread >= B_OK)
|
||||
kill_thread(fUpdateThread);
|
||||
|
||||
delete fBgBitmap[0];
|
||||
delete fBgBitmap[1];
|
||||
}
|
||||
|
||||
#if LIB_LAYOUT
|
||||
// layoutprefs
|
||||
minimax
|
||||
ColorField::layoutprefs()
|
||||
{
|
||||
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;
|
||||
|
||||
mpm.weight = 1.0;
|
||||
|
||||
return mpm;
|
||||
}
|
||||
|
||||
// layout
|
||||
BRect
|
||||
ColorField::layout(BRect frame)
|
||||
{
|
||||
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();
|
||||
}
|
||||
#endif // LIB_LAYOUT
|
||||
|
||||
// Invoke
|
||||
status_t
|
||||
ColorField::Invoke(BMessage *msg)
|
||||
{
|
||||
if (!msg)
|
||||
msg = Message();
|
||||
|
||||
msg->RemoveName("value");
|
||||
|
||||
float v1 = 0;
|
||||
float v2 = 0;
|
||||
|
||||
switch (fMode) {
|
||||
case R_SELECTED:
|
||||
case G_SELECTED:
|
||||
case B_SELECTED:
|
||||
v1 = fMarkerPosition.x / Width();
|
||||
v2 = 1.0 - fMarkerPosition.y / Height();
|
||||
break;
|
||||
|
||||
case H_SELECTED:
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
v1 = fMarkerPosition.x / Width();
|
||||
v2 = 1.0 - fMarkerPosition.y / Height();
|
||||
} else {
|
||||
v1 = fMarkerPosition.y / Height();
|
||||
v2 = 1.0 - fMarkerPosition.x / Width();
|
||||
}
|
||||
break;
|
||||
|
||||
case S_SELECTED:
|
||||
case V_SELECTED:
|
||||
v1 = fMarkerPosition.x / Width() * 6.0;
|
||||
v2 = 1.0 - fMarkerPosition.y / Height();
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
msg->AddFloat("value", v1);
|
||||
msg->AddFloat("value", v2);
|
||||
|
||||
return BControl::Invoke(msg);
|
||||
}
|
||||
|
||||
// AttachedToWindow
|
||||
void
|
||||
ColorField::AttachedToWindow()
|
||||
{
|
||||
Update(3);
|
||||
}
|
||||
|
||||
// Draw
|
||||
void
|
||||
ColorField::Draw(BRect updateRect)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
|
||||
// MouseDown
|
||||
void
|
||||
ColorField::MouseDown(BPoint where)
|
||||
{
|
||||
Window()->Activate();
|
||||
|
||||
fMouseDown = true;
|
||||
SetMouseEventMask(B_POINTER_EVENTS, B_SUSPEND_VIEW_FOCUS|B_LOCK_WINDOW_FOCUS );
|
||||
PositionMarkerAt( where );
|
||||
|
||||
if (Message()) {
|
||||
BMessage message(*Message());
|
||||
message.AddBool("begin", true);
|
||||
Invoke(&message);
|
||||
} else
|
||||
Invoke();
|
||||
}
|
||||
|
||||
// MouseUp
|
||||
void
|
||||
ColorField::MouseUp(BPoint where)
|
||||
{
|
||||
fMouseDown = false;
|
||||
}
|
||||
|
||||
// MouseMoved
|
||||
void
|
||||
ColorField::MouseMoved(BPoint where, uint32 code, const BMessage *a_message)
|
||||
{
|
||||
if (a_message || !fMouseDown ) {
|
||||
BView::MouseMoved( where, code, a_message);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
B = round(255.0 - fMarkerPosition.y / height * 255.0);
|
||||
}; break;
|
||||
|
||||
case B_SELECTED: {
|
||||
R = round(fMarkerPosition.x / width * 255.0);
|
||||
G = round(255.0 - fMarkerPosition.y / height * 255.0);
|
||||
B = fFixedValue * 255;
|
||||
}; break;
|
||||
|
||||
case H_SELECTED: {
|
||||
H = fFixedValue;
|
||||
S = fMarkerPosition.x / width;
|
||||
V = 1.0 - fMarkerPosition.y / height;
|
||||
}; break;
|
||||
|
||||
case S_SELECTED: {
|
||||
H = fMarkerPosition.x / width * 6.0;
|
||||
S = fFixedValue;
|
||||
V = 1.0 - fMarkerPosition.y / height;
|
||||
}; break;
|
||||
|
||||
case V_SELECTED: {
|
||||
H = fMarkerPosition.x / width * 6.0;
|
||||
S = 1.0 - fMarkerPosition.y / height;
|
||||
V = fFixedValue;
|
||||
}; break;
|
||||
}
|
||||
|
||||
if (fMode & (H_SELECTED | S_SELECTED | V_SELECTED)) {
|
||||
HSV_to_RGB(H, S, V, R, G, B);
|
||||
R *= 255.0; G *= 255.0; B *= 255.0;
|
||||
}
|
||||
|
||||
rgb_color color = { round(R), round(G), round(B), 255 };
|
||||
|
||||
fBgBitmap[0]->Unlock();
|
||||
|
||||
if (fFixedValue != fixed_value || fMode != mode) {
|
||||
fFixedValue = fixed_value;
|
||||
fMode = mode;
|
||||
|
||||
Update(3);
|
||||
}
|
||||
|
||||
SetMarkerToColor(color);
|
||||
}
|
||||
|
||||
// SetFixedValue
|
||||
void
|
||||
ColorField::SetFixedValue(float fixed_value)
|
||||
{
|
||||
if (fFixedValue != fixed_value) {
|
||||
fFixedValue = fixed_value;
|
||||
Update(3);
|
||||
}
|
||||
}
|
||||
|
||||
// SetMarkerToColor
|
||||
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 );
|
||||
|
||||
fLastMarkerPosition = fMarkerPosition;
|
||||
|
||||
float width = Width();
|
||||
float height = Height();
|
||||
|
||||
switch (fMode) {
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
case V_SELECTED: {
|
||||
fMarkerPosition = BPoint( h / 6.0 * width, height - s * height);
|
||||
} break;
|
||||
}
|
||||
|
||||
Update(1);
|
||||
}
|
||||
|
||||
// PositionMarkerAt
|
||||
void
|
||||
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) );
|
||||
|
||||
fLastMarkerPosition = fMarkerPosition;
|
||||
fMarkerPosition = where;
|
||||
Update(1);
|
||||
|
||||
}
|
||||
|
||||
// Width
|
||||
float
|
||||
ColorField::Width() const
|
||||
{
|
||||
return Bounds().IntegerWidth() + 1 - 4;
|
||||
}
|
||||
|
||||
// Height
|
||||
float
|
||||
ColorField::Height() const
|
||||
{
|
||||
return Bounds().IntegerHeight() + 1 - 4;
|
||||
}
|
||||
|
||||
// set_bits
|
||||
void
|
||||
set_bits(uint8* bits, uint8 r, uint8 g, uint8 b)
|
||||
{
|
||||
bits[0] = b;
|
||||
bits[1] = g;
|
||||
bits[2] = r;
|
||||
// bits[3] = 255;
|
||||
}
|
||||
|
||||
// _UpdateThread
|
||||
int32
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _DrawBorder
|
||||
void
|
||||
ColorField::_DrawBorder()
|
||||
{
|
||||
bool looperLocked = LockLooper();
|
||||
|
||||
fBgBitmap[1]->Lock();
|
||||
|
||||
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);
|
||||
|
||||
BRect r(fBgView[1]->Bounds());
|
||||
r.OffsetBy(-2.0, -2.0);
|
||||
BRegion region(r);
|
||||
fBgView[1]->ConstrainClippingRegion(®ion);
|
||||
|
||||
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();
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
#include "ColorPickerDefs.h"
|
||||
|
||||
#include <Control.h>
|
||||
|
||||
#if LIB_LAYOUT
|
||||
# include <layout.h>
|
||||
#endif
|
||||
|
||||
#include "selected_color_mode.h"
|
||||
|
||||
enum {
|
||||
MSG_COLOR_FIELD = 'ColF',
|
||||
};
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class ColorField :
|
||||
#if LIB_LAYOUT
|
||||
public MView,
|
||||
#endif
|
||||
public BControl {
|
||||
public:
|
||||
ColorField(BPoint offset_point,
|
||||
selected_color_mode mode,
|
||||
float fixed_value,
|
||||
orientation orient = B_VERTICAL);
|
||||
virtual ~ColorField();
|
||||
|
||||
// MView
|
||||
#if LIB_LAYOUT
|
||||
virtual minimax layoutprefs();
|
||||
virtual BRect layout(BRect frame);
|
||||
#endif
|
||||
|
||||
// BControl
|
||||
virtual status_t Invoke(BMessage *msg = NULL);
|
||||
|
||||
virtual void AttachedToWindow();
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseUp(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 code,
|
||||
const BMessage* message);
|
||||
|
||||
// ColorField
|
||||
void Update(int depth);
|
||||
|
||||
void SetModeAndValue(selected_color_mode mode, float fixed_value);
|
||||
void SetFixedValue(float fixed_value);
|
||||
float FixedValue() const
|
||||
{ return fFixedValue; }
|
||||
|
||||
void SetMarkerToColor( rgb_color color );
|
||||
void PositionMarkerAt( BPoint where );
|
||||
|
||||
float Width() const;
|
||||
float Height() const;
|
||||
bool IsTracking() const
|
||||
{ return fMouseDown; }
|
||||
|
||||
private:
|
||||
static int32 _UpdateThread(void* data);
|
||||
void _DrawBorder();
|
||||
|
||||
selected_color_mode fMode;
|
||||
float fFixedValue;
|
||||
orientation fOrientation;
|
||||
|
||||
BPoint fMarkerPosition;
|
||||
BPoint fLastMarkerPosition;
|
||||
|
||||
bool fMouseDown;
|
||||
|
||||
BBitmap* fBgBitmap[2];
|
||||
BView* fBgView[2];
|
||||
|
||||
thread_id fUpdateThread;
|
||||
port_id fUpdatePort;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,6 @@
|
||||
#ifndef COLOR_PICKER_COMMON_H
|
||||
#define COLOR_PICKER_COMMON_H
|
||||
|
||||
#define LIB_LAYOUT 0
|
||||
|
||||
#endif // COLOR_PICKER_COMMON_H
|
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ColorPickerPanel.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
#include "ColorPickerDefs.h"
|
||||
|
||||
#if LIB_LAYOUT
|
||||
# include <MBorder.h>
|
||||
# include <HGroup.h>
|
||||
# include <Space.h>
|
||||
# include <MButton.h>
|
||||
# include <VGroup.h>
|
||||
#else
|
||||
# include <Box.h>
|
||||
# include <Button.h>
|
||||
#endif
|
||||
|
||||
#include "support_ui.h"
|
||||
|
||||
#include "ColorPickerView.h"
|
||||
|
||||
enum {
|
||||
MSG_CANCEL = 'cncl',
|
||||
MSG_DONE = 'done',
|
||||
};
|
||||
|
||||
// constructor
|
||||
ColorPickerPanel::ColorPickerPanel(BRect frame, rgb_color color,
|
||||
selected_color_mode mode,
|
||||
BMessage* message, BWindow* target)
|
||||
: Panel(frame, "Pick Color",
|
||||
B_FLOATING_WINDOW_LOOK, B_FLOATING_SUBSET_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS |
|
||||
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_NOT_CLOSABLE),
|
||||
fMessage(message),
|
||||
fTarget(target)
|
||||
{
|
||||
SetTitle("Pick Color");
|
||||
|
||||
fColorPickerView = new ColorPickerView("color picker", color, mode);
|
||||
|
||||
#if LIB_LAYOUT
|
||||
MButton* defaultButton = new MButton("Ok", new BMessage(MSG_DONE), this);
|
||||
|
||||
// interface layout
|
||||
BView* topView = new VGroup (
|
||||
fColorPickerView,
|
||||
new MBorder (
|
||||
M_RAISED_BORDER, 5, "buttons",
|
||||
new HGroup (
|
||||
new Space(minimax(0.0, 0.0, 10000.0, 10000.0, 5.0)),
|
||||
new MButton("Cancel", new BMessage(MSG_CANCEL), this),
|
||||
new Space(minimax(5.0, 0.0, 10.0, 10000.0, 1.0)),
|
||||
defaultButton,
|
||||
new Space(minimax(2.0, 0.0, 2.0, 10000.0, 0.0)),
|
||||
0
|
||||
)
|
||||
),
|
||||
0
|
||||
);
|
||||
#else // LIB_LAYOUT
|
||||
frame = BRect(0, 0, 40, 15);
|
||||
BButton* defaultButton = new BButton(frame, "ok button", "Ok",
|
||||
new BMessage(MSG_DONE),
|
||||
B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
||||
defaultButton->ResizeToPreferred();
|
||||
BButton* cancelButton = new BButton(frame, "cancel button", "Cancel",
|
||||
new BMessage(MSG_CANCEL),
|
||||
B_FOLLOW_RIGHT | B_FOLLOW_TOP);
|
||||
cancelButton->ResizeToPreferred();
|
||||
|
||||
frame.bottom = frame.top + (defaultButton->Frame().Height() + 16);
|
||||
frame.right = frame.left + fColorPickerView->Frame().Width();
|
||||
BBox* buttonBox = new BBox(frame, "button group",
|
||||
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP,
|
||||
B_PLAIN_BORDER);
|
||||
|
||||
ResizeTo(frame.Width(),
|
||||
fColorPickerView->Frame().Height() + frame.Height() + 1);
|
||||
|
||||
frame = Bounds();
|
||||
BView* topView = new BView(frame, "bg", B_FOLLOW_ALL, 0);
|
||||
topView->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
buttonBox->MoveTo(frame.left, frame.bottom - buttonBox->Frame().Height());
|
||||
|
||||
defaultButton->MoveTo(frame.right - defaultButton->Frame().Width() - 10,
|
||||
frame.top + 8);
|
||||
buttonBox->AddChild(defaultButton);
|
||||
|
||||
cancelButton->MoveTo(defaultButton->Frame().left - 10
|
||||
- cancelButton->Frame().Width(),
|
||||
frame.top + 8);
|
||||
buttonBox->AddChild(cancelButton);
|
||||
|
||||
topView->AddChild(fColorPickerView);
|
||||
topView->AddChild(buttonBox);
|
||||
#endif // LIB_LAYOUT
|
||||
|
||||
SetDefaultButton(defaultButton);
|
||||
|
||||
if (fTarget)
|
||||
AddToSubset(fTarget);
|
||||
else
|
||||
SetFeel(B_FLOATING_APP_WINDOW_FEEL);
|
||||
|
||||
AddChild(topView);
|
||||
}
|
||||
|
||||
// destructor
|
||||
ColorPickerPanel::~ColorPickerPanel()
|
||||
{
|
||||
delete fMessage;
|
||||
}
|
||||
|
||||
// Cancel
|
||||
void
|
||||
ColorPickerPanel::Cancel()
|
||||
{
|
||||
PostMessage(MSG_CANCEL);
|
||||
}
|
||||
|
||||
// MessageReceived
|
||||
void
|
||||
ColorPickerPanel::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_CANCEL:
|
||||
case MSG_DONE: {
|
||||
BMessage msg('PSTE');
|
||||
BLooper* looper = fTarget ? static_cast<BLooper*>(fTarget)
|
||||
: static_cast<BLooper*>(be_app);
|
||||
if (fMessage)
|
||||
msg = *fMessage;
|
||||
if (message->what == MSG_DONE)
|
||||
store_color_in_message(&msg, fColorPickerView->Color());
|
||||
msg.AddRect("panel frame", Frame());
|
||||
msg.AddInt32("panel mode", fColorPickerView->Mode());
|
||||
msg.AddBool("begin", true);
|
||||
looper->PostMessage(&msg);
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Panel::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// SetColor
|
||||
void
|
||||
ColorPickerPanel::SetColor(rgb_color color)
|
||||
{
|
||||
fColorPickerView->SetColor(color);
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COLOR_PICKER_PANEL_H
|
||||
#define COLOR_PICKER_PANEL_H
|
||||
|
||||
#include "Panel.h"
|
||||
|
||||
#include "selected_color_mode.h"
|
||||
|
||||
class ColorPickerView;
|
||||
|
||||
class ColorPickerPanel : public Panel {
|
||||
public:
|
||||
ColorPickerPanel(BRect frame,
|
||||
rgb_color color,
|
||||
selected_color_mode mode
|
||||
= H_SELECTED,
|
||||
BMessage* message = NULL,
|
||||
BWindow* target = NULL);
|
||||
virtual ~ColorPickerPanel();
|
||||
|
||||
// Panel
|
||||
virtual void Cancel();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
void SetColor(rgb_color color);
|
||||
|
||||
private:
|
||||
|
||||
ColorPickerView* fColorPickerView;
|
||||
BMessage* fMessage;
|
||||
BWindow* fTarget;
|
||||
};
|
||||
|
||||
#endif // COLOR_PICKER_PANEL_H
|
@ -0,0 +1,504 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Application.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Beep.h>
|
||||
#include <Font.h>
|
||||
#include <Message.h>
|
||||
#include <RadioButton.h>
|
||||
#include <Screen.h>
|
||||
#include <TextControl.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "ColorField.h"
|
||||
#include "ColorPreview.h"
|
||||
#include "ColorSlider.h"
|
||||
#include "rgb_hsv.h"
|
||||
|
||||
#include "ColorPickerView.h"
|
||||
|
||||
|
||||
#define round(x) (int)(x+.5)
|
||||
#define hexdec(str, offset) (int)(((str[offset]<60?str[offset]-48:(str[offset]|32)-87)<<4)|(str[offset+1]<60?str[offset+1]-48:(str[offset+1]|32)-87))
|
||||
|
||||
// constructor
|
||||
ColorPickerView::ColorPickerView(const char* name, rgb_color color,
|
||||
selected_color_mode mode)
|
||||
: BView(BRect(0.0, 0.0, 400.0, 277.0), name,
|
||||
B_FOLLOW_NONE, B_WILL_DRAW | B_PULSE_NEEDED),
|
||||
h(0.0),
|
||||
s(1.0),
|
||||
v(1.0),
|
||||
r((float)color.red / 255.0),
|
||||
g((float)color.green / 255.0),
|
||||
b((float)color.blue / 255.0),
|
||||
fRequiresUpdate(false)
|
||||
|
||||
{
|
||||
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
|
||||
RGB_to_HSV(r, g, b, h, s, v);
|
||||
|
||||
SetColorMode(mode, false);
|
||||
}
|
||||
|
||||
// destructor
|
||||
ColorPickerView::~ColorPickerView()
|
||||
{
|
||||
}
|
||||
|
||||
#if LIB_LAYOUT
|
||||
// layoutprefs
|
||||
minimax
|
||||
ColorPickerView::layoutprefs()
|
||||
{
|
||||
mpm.mini.x = mpm.maxi.x = Bounds().Width() + 1.0;
|
||||
mpm.mini.y = mpm.maxi.y = Bounds().Height() + 1.0;
|
||||
mpm.weight = 1.0;
|
||||
return mpm;
|
||||
}
|
||||
|
||||
// layout
|
||||
BRect
|
||||
ColorPickerView::layout(BRect frame)
|
||||
{
|
||||
MoveTo(frame.LeftTop());
|
||||
ResizeTo(frame.Width(), frame.Height());
|
||||
return Frame();
|
||||
}
|
||||
#endif // LIB_LAYOUT
|
||||
|
||||
// AttachedToWindow
|
||||
void
|
||||
ColorPickerView::AttachedToWindow()
|
||||
{
|
||||
rgb_color color = { (int)(r * 255), (int)(g * 255), (int)(b * 255), 255 };
|
||||
|
||||
BView::AttachedToWindow();
|
||||
|
||||
fColorField = new ColorField(BPoint(10.0, 10.0), fSelectedColorMode, *p);
|
||||
fColorField->SetMarkerToColor(color);
|
||||
AddChild(fColorField);
|
||||
fColorField->SetTarget(this);
|
||||
|
||||
fColorSlider = new ColorSlider(BPoint(278.0, 7.0), fSelectedColorMode, *p1, *p2);
|
||||
fColorSlider->SetMarkerToColor(color);
|
||||
AddChild(fColorSlider);
|
||||
fColorSlider->SetTarget(this);
|
||||
|
||||
fColorPreview = new ColorPreview(BRect(0.0, 0.0, 66.0, 70.0).OffsetToCopy(321.0, 10.0), color);
|
||||
AddChild(fColorPreview);
|
||||
fColorPreview->SetTarget(this);
|
||||
|
||||
BFont font(be_plain_font);
|
||||
font.SetSize(10.0);
|
||||
SetFont(&font);
|
||||
|
||||
const char *title[] = { "H", "S", "V", "R", "G", "B" };
|
||||
|
||||
BTextView *textView;
|
||||
|
||||
int32 selectedRadioButton = _NumForMode(fSelectedColorMode);
|
||||
for (int i=0; i<6; ++i) {
|
||||
|
||||
fRadioButton[i] = new BRadioButton(BRect(0.0, 0.0, 30.0, 10.0).OffsetToCopy(320.0, 92.0 + 24.0 * i + (int)i/3 * 8),
|
||||
NULL, title[i], new BMessage(MSG_RADIOBUTTON + i));
|
||||
fRadioButton[i]->SetFont(&font);
|
||||
AddChild(fRadioButton[i]);
|
||||
|
||||
fRadioButton[i]->SetTarget(this);
|
||||
|
||||
if (i == selectedRadioButton)
|
||||
fRadioButton[i]->SetValue(1);
|
||||
}
|
||||
|
||||
for (int i=0; i<6; ++i) {
|
||||
|
||||
fTextControl[i] = new BTextControl(BRect(0.0, 0.0, 32.0, 19.0).OffsetToCopy(350.0, 90.0 + 24.0 * i + (int)i/3 * 8),
|
||||
NULL, NULL, NULL, new BMessage(MSG_TEXTCONTROL + i));
|
||||
|
||||
textView = fTextControl[i]->TextView();
|
||||
textView->SetMaxBytes(3);
|
||||
for (int j=32; j<255; ++j) {
|
||||
if (j<'0'||j>'9') textView->DisallowChar(j);
|
||||
}
|
||||
|
||||
fTextControl[i]->SetFont(&font);
|
||||
fTextControl[i]->SetDivider(0.0);
|
||||
AddChild(fTextControl[i]);
|
||||
|
||||
fTextControl[i]->SetTarget(this);
|
||||
}
|
||||
|
||||
fHexTextControl = new BTextControl(BRect(0.0, 0.0, 69.0, 19.0).OffsetToCopy(320.0, 248.0),
|
||||
NULL, "#", NULL, new BMessage(MSG_HEXTEXTCONTROL));
|
||||
|
||||
textView = fHexTextControl->TextView();
|
||||
textView->SetMaxBytes(6);
|
||||
for (int j=32; j<255; ++j) {
|
||||
if (!((j>='0' && j<='9') || (j>='a' && j<='f') || (j>='A' && j<='F'))) textView->DisallowChar(j);
|
||||
}
|
||||
|
||||
fHexTextControl->SetFont(&font);
|
||||
fHexTextControl->SetDivider(12.0);
|
||||
AddChild(fHexTextControl);
|
||||
|
||||
fHexTextControl->SetTarget(this);
|
||||
|
||||
_UpdateTextControls();
|
||||
}
|
||||
|
||||
// MessageReceived
|
||||
void
|
||||
ColorPickerView::MessageReceived(BMessage *message)
|
||||
{
|
||||
switch (message->what) {
|
||||
|
||||
case MSG_COLOR_FIELD: {
|
||||
float value1, value2;
|
||||
value1 = message->FindFloat("value");
|
||||
value2 = message->FindFloat("value", 1);
|
||||
_UpdateColor(-1, value1, value2);
|
||||
fRequiresUpdate = true;
|
||||
} break;
|
||||
|
||||
case MSG_COLOR_SLIDER: {
|
||||
float value;
|
||||
message->FindFloat("value", &value);
|
||||
_UpdateColor(value, -1, -1);
|
||||
fRequiresUpdate = true;
|
||||
} break;
|
||||
|
||||
case MSG_COLOR_PREVIEW: {
|
||||
rgb_color *color;
|
||||
ssize_t numBytes;
|
||||
if (message->FindData("color", B_RGB_COLOR_TYPE, (const void **)&color, &numBytes)==B_OK) {
|
||||
color->alpha = 255;
|
||||
SetColor(*color);
|
||||
}
|
||||
} break;
|
||||
|
||||
case MSG_RADIOBUTTON: {
|
||||
SetColorMode(H_SELECTED);
|
||||
} break;
|
||||
|
||||
case MSG_RADIOBUTTON + 1: {
|
||||
SetColorMode(S_SELECTED);
|
||||
} break;
|
||||
|
||||
case MSG_RADIOBUTTON + 2: {
|
||||
SetColorMode(V_SELECTED);
|
||||
} break;
|
||||
|
||||
case MSG_RADIOBUTTON + 3: {
|
||||
SetColorMode(R_SELECTED);
|
||||
} break;
|
||||
|
||||
case MSG_RADIOBUTTON + 4: {
|
||||
SetColorMode(G_SELECTED);
|
||||
} break;
|
||||
|
||||
case MSG_RADIOBUTTON + 5: {
|
||||
SetColorMode(B_SELECTED);
|
||||
} break;
|
||||
|
||||
case MSG_TEXTCONTROL:
|
||||
case MSG_TEXTCONTROL + 1:
|
||||
case MSG_TEXTCONTROL + 2:
|
||||
case MSG_TEXTCONTROL + 3:
|
||||
case MSG_TEXTCONTROL + 4:
|
||||
case MSG_TEXTCONTROL + 5: {
|
||||
|
||||
int nr = message->what - MSG_TEXTCONTROL;
|
||||
int value = atoi(fTextControl[nr]->Text());
|
||||
|
||||
char string[4];
|
||||
|
||||
switch (nr) {
|
||||
case 0: {
|
||||
value %= 360;
|
||||
sprintf(string, "%d", value);
|
||||
h = (float)value / 60;
|
||||
} break;
|
||||
|
||||
case 1: {
|
||||
value = min_c(value, 100);
|
||||
sprintf(string, "%d", value);
|
||||
s = (float)value / 100;
|
||||
} break;
|
||||
|
||||
case 2: {
|
||||
value = min_c(value, 100);
|
||||
sprintf(string, "%d", value);
|
||||
v = (float)value / 100;
|
||||
} break;
|
||||
|
||||
case 3: {
|
||||
value = min_c(value, 255);
|
||||
sprintf(string, "%d", value);
|
||||
r = (float)value / 255;
|
||||
} break;
|
||||
|
||||
case 4: {
|
||||
value = min_c(value, 255);
|
||||
sprintf(string, "%d", value);
|
||||
g = (float)value / 255;
|
||||
} break;
|
||||
|
||||
case 5: {
|
||||
value = min_c(value, 255);
|
||||
sprintf(string, "%d", value);
|
||||
b = (float)value / 255;
|
||||
} break;
|
||||
}
|
||||
|
||||
if (nr<3) { // hsv-mode
|
||||
HSV_to_RGB(h, s, v, r, g, b);
|
||||
}
|
||||
|
||||
rgb_color color = { round(r*255), round(g*255), round(b*255), 255 };
|
||||
|
||||
SetColor(color);
|
||||
|
||||
} break;
|
||||
|
||||
case MSG_HEXTEXTCONTROL: {
|
||||
if (fHexTextControl->TextView()->TextLength()==6) {
|
||||
const char *string = fHexTextControl->TextView()->Text();
|
||||
rgb_color color = { hexdec(string, 0), hexdec(string, 2), hexdec(string, 4), 255 };
|
||||
SetColor(color);
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
BView::MessageReceived(message);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw
|
||||
void
|
||||
ColorPickerView::Draw(BRect updateRect)
|
||||
{
|
||||
// raised border
|
||||
BRect r(Bounds());
|
||||
if (updateRect.Intersects(r)) {
|
||||
rgb_color light = tint_color(LowColor(), B_LIGHTEN_MAX_TINT);
|
||||
rgb_color shadow = tint_color(LowColor(), B_DARKEN_2_TINT);
|
||||
|
||||
BeginLineArray(4);
|
||||
AddLine(BPoint(r.left, r.bottom),
|
||||
BPoint(r.left, r.top), light);
|
||||
AddLine(BPoint(r.left + 1.0, r.top),
|
||||
BPoint(r.right, r.top), light);
|
||||
AddLine(BPoint(r.right, r.top + 1.0),
|
||||
BPoint(r.right, r.bottom), shadow);
|
||||
AddLine(BPoint(r.right - 1.0, r.bottom),
|
||||
BPoint(r.left + 1.0, r.bottom), shadow);
|
||||
EndLineArray();
|
||||
// exclude border from update rect
|
||||
r.InsetBy(1.0, 1.0);
|
||||
updateRect = r & updateRect;
|
||||
}
|
||||
|
||||
// some additional labels
|
||||
font_height fh;
|
||||
GetFontHeight(&fh);
|
||||
|
||||
const char *title[] = { "°", "%", "%" };
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
DrawString(title[i],
|
||||
BPoint(385.0, 93.0 + 24.0 * i + (int)i / 3 * 8 + fh.ascent));
|
||||
}
|
||||
}
|
||||
|
||||
// Pulse
|
||||
void
|
||||
ColorPickerView::Pulse()
|
||||
{
|
||||
if (fRequiresUpdate)
|
||||
_UpdateTextControls();
|
||||
}
|
||||
|
||||
// SetColorMode
|
||||
void
|
||||
ColorPickerView::SetColorMode(selected_color_mode mode, bool update)
|
||||
{
|
||||
fSelectedColorMode = mode;
|
||||
switch (mode) {
|
||||
case R_SELECTED:
|
||||
p = &r; p1 = &g; p2 = &b;
|
||||
break;
|
||||
|
||||
case G_SELECTED:
|
||||
p = &g; p1 = &r; p2 = &b;
|
||||
break;
|
||||
|
||||
case B_SELECTED:
|
||||
p = &b; p1 = &r; p2 = &g;
|
||||
break;
|
||||
|
||||
case H_SELECTED:
|
||||
p = &h; p1 = &s; p2 = &v;
|
||||
break;
|
||||
|
||||
case S_SELECTED:
|
||||
p = &s; p1 = &h; p2 = &v;
|
||||
break;
|
||||
|
||||
case V_SELECTED:
|
||||
p = &v; p1 = &h; p2 = &s;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!update) return;
|
||||
|
||||
fColorSlider->SetModeAndValues(fSelectedColorMode, *p1, *p2);
|
||||
fColorField->SetModeAndValue(fSelectedColorMode, *p);
|
||||
|
||||
}
|
||||
|
||||
// SetColor
|
||||
void
|
||||
ColorPickerView::SetColor(rgb_color color)
|
||||
{
|
||||
r = (float)color.red/255; g = (float)color.green/255; b = (float)color.blue/255;
|
||||
RGB_to_HSV(r, g, b, h, s, v);
|
||||
|
||||
fColorSlider->SetModeAndValues(fSelectedColorMode, *p1, *p2);
|
||||
fColorSlider->SetMarkerToColor(color);
|
||||
|
||||
fColorField->SetModeAndValue(fSelectedColorMode, *p);
|
||||
fColorField->SetMarkerToColor(color);
|
||||
|
||||
fColorPreview->SetColor(color);
|
||||
|
||||
fRequiresUpdate = true;
|
||||
}
|
||||
|
||||
// Color
|
||||
rgb_color
|
||||
ColorPickerView::Color()
|
||||
{
|
||||
if (fSelectedColorMode & (R_SELECTED|G_SELECTED|B_SELECTED))
|
||||
RGB_to_HSV(r, g, b, h, s, v);
|
||||
else
|
||||
HSV_to_RGB(h, s, v, r, g, b);
|
||||
|
||||
rgb_color color;
|
||||
color.red = (uint8)round(r * 255.0);
|
||||
color.green = (uint8)round(g * 255.0);
|
||||
color.blue = (uint8)round(b * 255.0);
|
||||
color.alpha = 255;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
// _NumForMode
|
||||
int32
|
||||
ColorPickerView::_NumForMode(selected_color_mode mode) const
|
||||
{
|
||||
int32 num = -1;
|
||||
switch (mode) {
|
||||
case H_SELECTED:
|
||||
num = 0;
|
||||
break;
|
||||
case S_SELECTED:
|
||||
num = 1;
|
||||
break;
|
||||
case V_SELECTED:
|
||||
num = 2;
|
||||
break;
|
||||
case R_SELECTED:
|
||||
num = 3;
|
||||
break;
|
||||
case G_SELECTED:
|
||||
num = 4;
|
||||
break;
|
||||
case B_SELECTED:
|
||||
num = 5;
|
||||
break;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
// _UpdateColor
|
||||
void
|
||||
ColorPickerView::_UpdateColor(float value, float value1, float value2)
|
||||
{
|
||||
if (value!=-1) {
|
||||
fColorField->SetFixedValue(value);
|
||||
*p = value;
|
||||
}
|
||||
else if (value1!=-1 && value2!=-1) {
|
||||
fColorSlider->SetOtherValues(value1, value2);
|
||||
*p1 = value1; *p2 = value2;
|
||||
}
|
||||
|
||||
if (fSelectedColorMode & (R_SELECTED|G_SELECTED|B_SELECTED))
|
||||
RGB_to_HSV(r, g, b, h, s, v);
|
||||
else
|
||||
HSV_to_RGB(h, s, v, r, g, b);
|
||||
|
||||
rgb_color color = { (int)(r*255), (int)(g*255), (int)(b*255), 255 };
|
||||
fColorPreview->SetColor(color);
|
||||
}
|
||||
|
||||
// _UpdateTextControls
|
||||
void
|
||||
ColorPickerView::_UpdateTextControls()
|
||||
{
|
||||
Window()->DisableUpdates();
|
||||
|
||||
char string[10];
|
||||
|
||||
fRequiresUpdate = false;
|
||||
|
||||
sprintf(string, "%d", round(h*60));
|
||||
_SetText(fTextControl[0], string, &fRequiresUpdate);
|
||||
|
||||
sprintf(string, "%d", round(s*100));
|
||||
_SetText(fTextControl[1], string, &fRequiresUpdate);
|
||||
|
||||
sprintf(string, "%d", round(v*100));
|
||||
_SetText(fTextControl[2], string, &fRequiresUpdate);
|
||||
|
||||
sprintf(string, "%d", round(r*255));
|
||||
_SetText(fTextControl[3], string, &fRequiresUpdate);
|
||||
|
||||
sprintf(string, "%d", round(g*255));
|
||||
_SetText(fTextControl[4], string, &fRequiresUpdate);
|
||||
|
||||
sprintf(string, "%d", round(b*255));
|
||||
_SetText(fTextControl[5], string, &fRequiresUpdate);
|
||||
|
||||
sprintf(string, "%.6X", (round(r*255)<<16)|(round(g*255)<<8)|round(b*255));
|
||||
_SetText(fHexTextControl, string, &fRequiresUpdate);
|
||||
|
||||
Window()->EnableUpdates();
|
||||
}
|
||||
|
||||
// _SetText
|
||||
void
|
||||
ColorPickerView::_SetText(BTextControl* control, const char* text,
|
||||
bool* requiresUpdate)
|
||||
{
|
||||
if (strcmp(control->Text(), text) != 0) {
|
||||
// this textview needs updating
|
||||
if (!control->TextView()->IsFocus())
|
||||
// but don't screw with user while she is typing
|
||||
control->SetText(text);
|
||||
else
|
||||
*requiresUpdate = true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COLOR_PICKER_VIEW_H
|
||||
#define COLOR_PICKER_VIEW_H
|
||||
|
||||
#include "ColorPickerDefs.h"
|
||||
|
||||
#include <View.h>
|
||||
|
||||
#if LIB_LAYOUT
|
||||
# include <layout.h>
|
||||
#endif
|
||||
|
||||
#include "selected_color_mode.h"
|
||||
|
||||
#define MSG_RADIOBUTTON 'Rad0'
|
||||
#define MSG_TEXTCONTROL 'Txt0'
|
||||
#define MSG_HEXTEXTCONTROL 'HTxt'
|
||||
|
||||
class ColorField;
|
||||
class ColorSlider;
|
||||
class ColorPreview;
|
||||
|
||||
class BRadioButton;
|
||||
class BTextControl;
|
||||
|
||||
class ColorPickerView :
|
||||
#if LIB_LAYOUT
|
||||
public MView,
|
||||
#endif
|
||||
public BView {
|
||||
public:
|
||||
ColorPickerView(const char* name,
|
||||
rgb_color color,
|
||||
selected_color_mode mode);
|
||||
virtual ~ColorPickerView();
|
||||
|
||||
#if LIB_LAYOUT
|
||||
// MView
|
||||
virtual minimax layoutprefs();
|
||||
virtual BRect layout(BRect frame);
|
||||
#endif
|
||||
|
||||
// BView
|
||||
virtual void AttachedToWindow();
|
||||
virtual void MessageReceived(BMessage *message);
|
||||
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual void Pulse();
|
||||
|
||||
// ColorPickerView
|
||||
void SetColorMode(selected_color_mode mode,
|
||||
bool update = true);
|
||||
void SetColor(rgb_color color);
|
||||
rgb_color Color();
|
||||
selected_color_mode Mode() const
|
||||
{ return fSelectedColorMode; }
|
||||
|
||||
private:
|
||||
int32 _NumForMode(selected_color_mode mode) const;
|
||||
|
||||
void _UpdateColor(float value, float value1,
|
||||
float value2);
|
||||
void _UpdateTextControls();
|
||||
void _SetText(BTextControl* control,
|
||||
const char* text,
|
||||
bool* requiresUpdate);
|
||||
|
||||
|
||||
selected_color_mode fSelectedColorMode;
|
||||
|
||||
float h, s, v, r, g, b;
|
||||
float *p, *p1, *p2;
|
||||
|
||||
bool fRequiresUpdate;
|
||||
|
||||
ColorField* fColorField;
|
||||
ColorSlider* fColorSlider;
|
||||
ColorPreview* fColorPreview;
|
||||
|
||||
BRadioButton* fRadioButton[6];
|
||||
BTextControl* fTextControl[6];
|
||||
BTextControl* fHexTextControl;
|
||||
};
|
||||
|
||||
#endif // COLOR_PICKER_VIEW_H
|
||||
|
||||
|
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ColorPreview.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Cursor.h>
|
||||
#include <MessageRunner.h>
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "cursors.h"
|
||||
#include "support_ui.h"
|
||||
|
||||
// constructor
|
||||
ColorPreview::ColorPreview(BRect frame, rgb_color color)
|
||||
: BControl(frame, "colorpreview", "", new BMessage(MSG_COLOR_PREVIEW),
|
||||
B_FOLLOW_TOP|B_FOLLOW_LEFT, B_WILL_DRAW),
|
||||
fColor(color),
|
||||
fOldColor(color),
|
||||
|
||||
fMouseDown(false),
|
||||
|
||||
fMessageRunner(0)
|
||||
{
|
||||
}
|
||||
|
||||
// AttachedToWindow
|
||||
void
|
||||
ColorPreview::AttachedToWindow()
|
||||
{
|
||||
BControl::AttachedToWindow();
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
}
|
||||
|
||||
// Draw
|
||||
void
|
||||
ColorPreview::Draw(BRect updateRect)
|
||||
{
|
||||
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);
|
||||
|
||||
BRect r(Bounds());
|
||||
stroke_frame(this, r, shadow, shadow, light, light);
|
||||
r.InsetBy(1.0, 1.0);
|
||||
stroke_frame(this, r, darkShadow, darkShadow, background, background);
|
||||
r.InsetBy(1.0, 1.0);
|
||||
|
||||
r.bottom = r.top + r.Height() / 2.0;
|
||||
SetHighColor(fColor);
|
||||
FillRect(r);
|
||||
|
||||
r.top = r.bottom + 1;
|
||||
r.bottom = Bounds().bottom - 2.0;
|
||||
SetHighColor(fOldColor);
|
||||
FillRect(r);
|
||||
}
|
||||
|
||||
// MessageReceived
|
||||
void
|
||||
ColorPreview::MessageReceived(BMessage* message)
|
||||
{
|
||||
if (message->what == MSG_MESSAGERUNNER) {
|
||||
|
||||
BPoint where;
|
||||
uint32 buttons;
|
||||
|
||||
GetMouse(&where, &buttons);
|
||||
|
||||
_DragColor(where);
|
||||
|
||||
} else {
|
||||
#ifdef TARGET_PLATFORM_ZETA
|
||||
const
|
||||
#endif
|
||||
char* nameFound;
|
||||
type_code typeFound;
|
||||
|
||||
if (message->GetInfo(B_RGB_COLOR_TYPE, 0,
|
||||
&nameFound, &typeFound) != B_OK) {
|
||||
BControl::MessageReceived(message);
|
||||
return;
|
||||
}
|
||||
|
||||
rgb_color* color;
|
||||
ssize_t numBytes;
|
||||
message->FindData(nameFound, typeFound,
|
||||
(const void**)&color, &numBytes);
|
||||
|
||||
BPoint where;
|
||||
bool droppedOnNewArea = false;
|
||||
if (message->FindPoint("_drop_point_", &where) == B_OK) {
|
||||
ConvertFromScreen(&where);
|
||||
if (where.y > Bounds().top + (Bounds().IntegerHeight() >> 1))
|
||||
droppedOnNewArea = true;
|
||||
}
|
||||
|
||||
if (droppedOnNewArea)
|
||||
SetNewColor(*color);
|
||||
else
|
||||
SetColor(*color);
|
||||
Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
// MouseDown
|
||||
void
|
||||
ColorPreview::MouseDown(BPoint where)
|
||||
{
|
||||
Window()->Activate();
|
||||
|
||||
fMouseDown = true;
|
||||
|
||||
fMessageRunner = new BMessageRunner(
|
||||
this, new BMessage(MSG_MESSAGERUNNER), 300000, 1);
|
||||
|
||||
SetMouseEventMask(B_POINTER_EVENTS,
|
||||
B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
|
||||
|
||||
BRect rect = Bounds().InsetByCopy(2.0, 2.0);
|
||||
rect.top = rect.bottom/2 + 1;
|
||||
|
||||
if (rect.Contains( where ) ) {
|
||||
fColor = fOldColor;
|
||||
Draw( Bounds() );
|
||||
Invoke();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MouseUp
|
||||
void
|
||||
ColorPreview::MouseUp(BPoint where)
|
||||
{
|
||||
delete fMessageRunner;
|
||||
fMessageRunner = NULL;
|
||||
|
||||
fMouseDown = false;
|
||||
BControl::MouseUp(where);
|
||||
}
|
||||
|
||||
// MouseMoved
|
||||
void
|
||||
ColorPreview::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
|
||||
{
|
||||
if (transit == B_ENTERED_VIEW) {
|
||||
BCursor cursor(kDropperCursor);
|
||||
SetViewCursor(&cursor, true);
|
||||
}
|
||||
if (fMouseDown)
|
||||
_DragColor(where);
|
||||
}
|
||||
|
||||
// Invoke
|
||||
status_t
|
||||
ColorPreview::Invoke(BMessage* message)
|
||||
{
|
||||
if (!message)
|
||||
message = Message();
|
||||
|
||||
if (message) {
|
||||
message->RemoveName("color");
|
||||
message->AddData("color", B_RGB_COLOR_TYPE, &fColor, sizeof(fColor));
|
||||
}
|
||||
|
||||
return BControl::Invoke(message);
|
||||
}
|
||||
|
||||
// SetColor
|
||||
void
|
||||
ColorPreview::SetColor(rgb_color color)
|
||||
{
|
||||
color.alpha = 255;
|
||||
fColor = color;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
// SetNewColor
|
||||
void
|
||||
ColorPreview::SetNewColor(rgb_color color)
|
||||
{
|
||||
fColor = color;
|
||||
fOldColor = color;
|
||||
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// _DragColor
|
||||
void
|
||||
ColorPreview::_DragColor(BPoint where)
|
||||
{
|
||||
BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_RGB32);
|
||||
BMessage message = make_color_drop_message(fColor, bitmap);
|
||||
|
||||
DragMessage(&message, bitmap, B_OP_ALPHA, BPoint(9.0, 9.0));
|
||||
|
||||
MouseUp(where);
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _COLOR_PREVIEW_H
|
||||
#define _COLOR_PREVIEW_H
|
||||
|
||||
#include <Control.h>
|
||||
|
||||
#define MSG_COLOR_PREVIEW 'ColP'
|
||||
#define MSG_MESSAGERUNNER 'MsgR'
|
||||
|
||||
class BMessageRunner;
|
||||
|
||||
class ColorPreview : public BControl {
|
||||
public:
|
||||
|
||||
ColorPreview(BRect frame,
|
||||
rgb_color color);
|
||||
|
||||
// BControl interface
|
||||
virtual void AttachedToWindow();
|
||||
virtual void Draw(BRect updateRect);
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MouseUp(BPoint where);
|
||||
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||
const BMessage* message);
|
||||
|
||||
virtual status_t Invoke(BMessage* message = NULL);
|
||||
|
||||
// ColorPreview
|
||||
void SetColor(rgb_color color);
|
||||
// changes the displayed color
|
||||
void SetNewColor(rgb_color color);
|
||||
// changes also the old color
|
||||
|
||||
private:
|
||||
|
||||
void _DragColor(BPoint where);
|
||||
|
||||
rgb_color fColor;
|
||||
rgb_color fOldColor;
|
||||
|
||||
bool fMouseDown;
|
||||
|
||||
BMessageRunner* fMessageRunner;
|
||||
};
|
||||
|
||||
#endif // _COLOR_PREVIEW_H
|
||||
|
@ -0,0 +1,669 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ColorSlider.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <OS.h>
|
||||
#include <Window.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "selected_color_mode.h"
|
||||
#include "support_ui.h"
|
||||
|
||||
#include "rgb_hsv.h"
|
||||
|
||||
#define round(x) (int)(x+.5)
|
||||
|
||||
enum {
|
||||
MSG_UPDATE = 'Updt',
|
||||
};
|
||||
|
||||
#define MAX_X 255
|
||||
#define MAX_Y 255
|
||||
|
||||
// constructor
|
||||
ColorSlider::ColorSlider(BPoint offset_point,
|
||||
selected_color_mode mode,
|
||||
float value1, float value2, orientation dir)
|
||||
: BControl(BRect(0.0, 0.0, 35.0, 265.0).OffsetToCopy(offset_point),
|
||||
"ColorSlider", "", new BMessage(MSG_COLOR_SLIDER),
|
||||
B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS),
|
||||
fMode(mode),
|
||||
fFixedValue1(value1),
|
||||
fFixedValue2(value2),
|
||||
fMouseDown(false),
|
||||
fBgBitmap(new BBitmap(Bounds(), B_RGB32, true)),
|
||||
fBgView(NULL),
|
||||
fUpdateThread(0),
|
||||
fUpdatePort(0),
|
||||
fOrientation(dir)
|
||||
{
|
||||
SetViewColor(B_TRANSPARENT_32_BIT);
|
||||
|
||||
if (fBgBitmap->IsValid() && fBgBitmap->Lock()) {
|
||||
fBgView = new BView(Bounds(), "", B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
fBgBitmap->AddChild(fBgView);
|
||||
/* if (fOrientation == B_VERTICAL)
|
||||
fBgView->SetOrigin(8.0, 2.0);
|
||||
else
|
||||
fBgView->SetOrigin(2.0, 2.0);*/
|
||||
fBgBitmap->Unlock();
|
||||
} else {
|
||||
delete fBgBitmap;
|
||||
fBgBitmap = NULL;
|
||||
fBgView = this;
|
||||
}
|
||||
|
||||
fUpdatePort = create_port(100, "color slider update port");
|
||||
|
||||
fUpdateThread = spawn_thread(ColorSlider::_UpdateThread, "color slider update thread", 10, this);
|
||||
resume_thread( fUpdateThread );
|
||||
|
||||
Update(2);
|
||||
}
|
||||
|
||||
// destructor
|
||||
ColorSlider::~ColorSlider()
|
||||
{
|
||||
if (fUpdatePort)
|
||||
delete_port(fUpdatePort);
|
||||
if (fUpdateThread)
|
||||
kill_thread(fUpdateThread);
|
||||
|
||||
delete fBgBitmap;
|
||||
}
|
||||
|
||||
#if LIB_LAYOUT
|
||||
// layoutprefs
|
||||
minimax
|
||||
ColorSlider::layoutprefs()
|
||||
{
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
mpm.mini.x = 36;
|
||||
mpm.maxi.x = 36;
|
||||
mpm.mini.y = 10 + MAX_Y / 17;
|
||||
mpm.maxi.y = 10 + MAX_Y;
|
||||
} else {
|
||||
mpm.mini.x = 10 + MAX_X / 17;
|
||||
mpm.maxi.x = 10 + MAX_X;
|
||||
mpm.mini.y = 10.0;
|
||||
mpm.maxi.y = 12.0;
|
||||
}
|
||||
mpm.weight = 1.0;
|
||||
|
||||
return mpm;
|
||||
}
|
||||
|
||||
// layout
|
||||
BRect
|
||||
ColorSlider::layout(BRect frame)
|
||||
{
|
||||
MoveTo(frame.LeftTop());
|
||||
ResizeTo(frame.Width(), frame.Height());
|
||||
// Update(2);
|
||||
return Frame();
|
||||
}
|
||||
#endif // LIB_LAYOUT
|
||||
|
||||
// AttachedToWindow
|
||||
void
|
||||
ColorSlider::AttachedToWindow()
|
||||
{
|
||||
BControl::AttachedToWindow();
|
||||
|
||||
SetViewColor(B_TRANSPARENT_32_BIT);
|
||||
|
||||
if (fBgBitmap && fBgBitmap->Lock()) {
|
||||
fBgView->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
fBgView->FillRect(Bounds());
|
||||
fBgBitmap->Unlock();
|
||||
} else {
|
||||
SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||
}
|
||||
|
||||
Update(2);
|
||||
}
|
||||
|
||||
|
||||
// Invoke
|
||||
status_t
|
||||
ColorSlider::Invoke(BMessage *msg)
|
||||
{
|
||||
if (!msg) msg = Message();
|
||||
|
||||
msg->RemoveName("value");
|
||||
msg->RemoveName("begin");
|
||||
|
||||
switch (fMode) {
|
||||
|
||||
case R_SELECTED:
|
||||
case G_SELECTED:
|
||||
case B_SELECTED: {
|
||||
msg->AddFloat("value", 1.0 - (float)Value() / 255);
|
||||
} break;
|
||||
|
||||
case H_SELECTED: {
|
||||
msg->AddFloat("value", (1.0 - (float)Value() / 255) * 6);
|
||||
} break;
|
||||
|
||||
case S_SELECTED:
|
||||
case V_SELECTED: {
|
||||
msg->AddFloat("value", 1.0 - (float)Value() / 255);
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
// some other parts of WonderBrush rely on this.
|
||||
// if the flag is present, it triggers generating an undo action
|
||||
// fMouseDown is not set yet the first message is sent
|
||||
if (!fMouseDown)
|
||||
msg->AddBool("begin", true);
|
||||
|
||||
return BControl::Invoke(msg);
|
||||
}
|
||||
|
||||
// Draw
|
||||
void
|
||||
ColorSlider::Draw(BRect updateRect)
|
||||
{
|
||||
Update(0);
|
||||
}
|
||||
|
||||
// FrameResized
|
||||
void
|
||||
ColorSlider::FrameResized(float width, float height)
|
||||
{
|
||||
if (fBgBitmap) {
|
||||
fBgBitmap->Lock();
|
||||
delete fBgBitmap;
|
||||
}
|
||||
fBgBitmap = new BBitmap(Bounds(), B_RGB32, true);
|
||||
if (fBgBitmap->IsValid() && fBgBitmap->Lock()) {
|
||||
fBgView = new BView(Bounds(), "", B_FOLLOW_NONE, B_WILL_DRAW);
|
||||
fBgBitmap->AddChild(fBgView);
|
||||
/* if (fOrientation == B_VERTICAL)
|
||||
fBgView->SetOrigin(8.0, 2.0);
|
||||
else
|
||||
fBgView->SetOrigin(2.0, 2.0);*/
|
||||
fBgBitmap->Unlock();
|
||||
} else {
|
||||
delete fBgBitmap;
|
||||
fBgBitmap = NULL;
|
||||
fBgView = this;
|
||||
}
|
||||
Update(2);
|
||||
}
|
||||
|
||||
// MouseDown
|
||||
void
|
||||
ColorSlider::MouseDown(BPoint where)
|
||||
{
|
||||
Window()->Activate();
|
||||
|
||||
SetMouseEventMask(B_POINTER_EVENTS, B_SUSPEND_VIEW_FOCUS | B_LOCK_WINDOW_FOCUS);
|
||||
_TrackMouse(where);
|
||||
fMouseDown = true;
|
||||
}
|
||||
|
||||
// MouseUp
|
||||
void
|
||||
ColorSlider::MouseUp(BPoint where)
|
||||
{
|
||||
fMouseDown = false;
|
||||
}
|
||||
|
||||
// MouseMoved
|
||||
void
|
||||
ColorSlider::MouseMoved( BPoint where, uint32 code, const BMessage* dragMessage)
|
||||
{
|
||||
if (dragMessage || !fMouseDown)
|
||||
return;
|
||||
|
||||
_TrackMouse(where);
|
||||
}
|
||||
|
||||
// SetValue
|
||||
void
|
||||
ColorSlider::SetValue(int32 value)
|
||||
{
|
||||
value = max_c(min_c(value, 255), 0);
|
||||
if (value != Value()) {
|
||||
BControl::SetValue(value);
|
||||
|
||||
Update(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Update
|
||||
void
|
||||
ColorSlider::Update(int depth)
|
||||
{
|
||||
// depth: 0 = onscreen only, 1 = bitmap 1, 2 = bitmap 0
|
||||
if (depth == 2) {
|
||||
write_port(fUpdatePort, MSG_UPDATE, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Parent())
|
||||
return;
|
||||
|
||||
fBgBitmap->Lock();
|
||||
|
||||
// BRect r(fBgView->Bounds());
|
||||
BRect r(Bounds());
|
||||
BRect bounds(r);
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
// r.OffsetBy(-8.0, -2.0);
|
||||
r.InsetBy(6.0, 3.0);
|
||||
// bounds.Set(-8.0, -2.0, r.right - 8.0, r.bottom - 2.0);
|
||||
// bounds.OffsetBy(8.0, 2.0);
|
||||
} else {
|
||||
// r.OffsetBy(-2.0, -2.0);
|
||||
// bounds.Set(-2.0, -2.0, r.right - 2.0, r.bottom - 2.0);
|
||||
// bounds.OffsetBy(2.0, 2.0);
|
||||
}
|
||||
|
||||
fBgBitmap->Unlock();
|
||||
|
||||
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);
|
||||
|
||||
if (depth >= 1) {
|
||||
|
||||
fBgBitmap->Lock();
|
||||
|
||||
|
||||
// frame
|
||||
stroke_frame(fBgView, r, shadow, shadow, light, light);
|
||||
r.InsetBy(1.0, 1.0);
|
||||
stroke_frame(fBgView, r, darkShadow, darkShadow, background, background);
|
||||
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
// clear area left and right from slider
|
||||
fBgView->SetHighColor( background );
|
||||
fBgView->FillRect( BRect(bounds.left, bounds.top, bounds.left + 5.0, bounds.bottom) );
|
||||
fBgView->FillRect( BRect(bounds.right - 5.0, bounds.top, bounds.right, bounds.bottom) );
|
||||
}
|
||||
/*
|
||||
// marker
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
// clear area left and right from slider
|
||||
fBgView->SetHighColor( background );
|
||||
fBgView->FillRect( BRect(bounds.left, bounds.top, bounds.left + 5.0, bounds.bottom) );
|
||||
fBgView->FillRect( BRect(bounds.right - 5.0, bounds.top, bounds.right, bounds.bottom) );
|
||||
// draw the triangle markers
|
||||
fBgView->SetHighColor( 0, 0, 0 );
|
||||
float value = Value();
|
||||
fBgView->StrokeLine( BPoint(bounds.left, value - 2.0), BPoint(bounds.left + 5.0, value + 3.0));
|
||||
fBgView->StrokeLine( BPoint(bounds.left, value + 8.0));
|
||||
fBgView->StrokeLine( BPoint(bounds.left, value - 2.0));
|
||||
|
||||
fBgView->StrokeLine( BPoint(bounds.right, value - 2.0), BPoint(bounds.right - 5.0, value + 3.0));
|
||||
fBgView->StrokeLine( BPoint(bounds.right, value + 8.0));
|
||||
fBgView->StrokeLine( BPoint(bounds.right, value - 2.0));
|
||||
} else {
|
||||
r.InsetBy(1.0, 1.0);
|
||||
float value = (Value() / 255.0) * (bounds.Width() - 4.0);
|
||||
if (value - 2 > r.left) {
|
||||
fBgView->SetHighColor( 255, 255, 255 );
|
||||
fBgView->StrokeLine( BPoint(value - 2, bounds.top + 2.0),
|
||||
BPoint(value - 2, bounds.bottom - 2.0));
|
||||
}
|
||||
if (value - 1 > r.left) {
|
||||
fBgView->SetHighColor( 0, 0, 0 );
|
||||
fBgView->StrokeLine( BPoint(value - 1, bounds.top + 2.0),
|
||||
BPoint(value - 1, bounds.bottom - 2.0));
|
||||
}
|
||||
if (value + 1 < r.right) {
|
||||
fBgView->SetHighColor( 0, 0, 0 );
|
||||
fBgView->StrokeLine( BPoint(value + 1, bounds.top + 2.0),
|
||||
BPoint(value + 1, bounds.bottom - 2.0));
|
||||
}
|
||||
if (value + 2 < r.right) {
|
||||
fBgView->SetHighColor( 255, 255, 255 );
|
||||
fBgView->StrokeLine( BPoint(value + 2, bounds.top + 2.0),
|
||||
BPoint(value + 2, bounds.bottom - 2.0));
|
||||
}
|
||||
}*/
|
||||
|
||||
fBgView->Sync();
|
||||
|
||||
fBgBitmap->Unlock();
|
||||
} else
|
||||
r.InsetBy(1.0, 1.0);
|
||||
|
||||
DrawBitmap(fBgBitmap, BPoint(0.0, 0.0));
|
||||
|
||||
// marker
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
// draw the triangle markers
|
||||
SetHighColor( 0, 0, 0 );
|
||||
float value = Value();
|
||||
StrokeLine( BPoint(bounds.left, value),
|
||||
BPoint(bounds.left + 5.0, value + 5.0));
|
||||
StrokeLine( BPoint(bounds.left, value + 10.0));
|
||||
StrokeLine( BPoint(bounds.left, value));
|
||||
|
||||
StrokeLine( BPoint(bounds.right, value),
|
||||
BPoint(bounds.right - 5.0, value + 5.0));
|
||||
StrokeLine( BPoint(bounds.right, value + 10.0));
|
||||
StrokeLine( BPoint(bounds.right, value));
|
||||
} else {
|
||||
r.InsetBy(1.0, 1.0);
|
||||
float value = (Value() / 255.0) * (bounds.Width() - 4.0);
|
||||
if (value > r.left) {
|
||||
SetHighColor( 255, 255, 255 );
|
||||
StrokeLine( BPoint(value, bounds.top + 2.0),
|
||||
BPoint(value, bounds.bottom - 2.0));
|
||||
}
|
||||
if (value + 1 > r.left) {
|
||||
SetHighColor( 0, 0, 0 );
|
||||
StrokeLine( BPoint(value + 1, bounds.top + 2.0),
|
||||
BPoint(value + 1, bounds.bottom - 2.0));
|
||||
}
|
||||
if (value + 3 < r.right) {
|
||||
SetHighColor( 0, 0, 0 );
|
||||
StrokeLine( BPoint(value + 3, bounds.top + 2.0),
|
||||
BPoint(value + 3, bounds.bottom - 2.0));
|
||||
}
|
||||
if (value + 4 < r.right) {
|
||||
SetHighColor( 255, 255, 255 );
|
||||
StrokeLine( BPoint(value + 4, bounds.top + 2.0),
|
||||
BPoint(value + 4, bounds.bottom - 2.0));
|
||||
}
|
||||
}
|
||||
SetOrigin(0.0, 0.0);
|
||||
}
|
||||
|
||||
// SetModeAndValues
|
||||
void
|
||||
ColorSlider::SetModeAndValues(selected_color_mode mode,
|
||||
float value1, float value2)
|
||||
{
|
||||
float R(0), G(0), B(0);
|
||||
float h(0), s(0), v(0);
|
||||
|
||||
fBgBitmap->Lock();
|
||||
|
||||
switch (fMode) {
|
||||
|
||||
case R_SELECTED: {
|
||||
R = 255 - Value();
|
||||
G = round(fFixedValue1 * 255.0);
|
||||
B = round(fFixedValue2 * 255.0);
|
||||
}; break;
|
||||
|
||||
case G_SELECTED: {
|
||||
R = round(fFixedValue1 * 255.0);
|
||||
G = 255 - Value();
|
||||
B = round(fFixedValue2 * 255.0);
|
||||
}; break;
|
||||
|
||||
case B_SELECTED: {
|
||||
R = round(fFixedValue1 * 255.0);
|
||||
G = round(fFixedValue2 * 255.0);
|
||||
B = 255 - Value();
|
||||
}; break;
|
||||
|
||||
case H_SELECTED: {
|
||||
h = (1.0 - (float)Value()/255.0)*6.0;
|
||||
s = fFixedValue1;
|
||||
v = fFixedValue2;
|
||||
}; break;
|
||||
|
||||
case S_SELECTED: {
|
||||
h = fFixedValue1;
|
||||
s = 1.0 - (float)Value()/255.0;
|
||||
v = fFixedValue2;
|
||||
}; break;
|
||||
|
||||
case V_SELECTED: {
|
||||
h = fFixedValue1;
|
||||
s = fFixedValue2;
|
||||
v = 1.0 - (float)Value()/255.0;
|
||||
}; break;
|
||||
}
|
||||
|
||||
if (fMode & (H_SELECTED|S_SELECTED|V_SELECTED) ) {
|
||||
HSV_to_RGB(h, s, v, R, G, B);
|
||||
R*=255.0; G*=255.0; B*=255.0;
|
||||
}
|
||||
|
||||
rgb_color color = { round(R), round(G), round(B), 255 };
|
||||
|
||||
fMode = mode;
|
||||
SetOtherValues(value1, value2);
|
||||
fBgBitmap->Unlock();
|
||||
|
||||
SetMarkerToColor( color );
|
||||
Update(2);
|
||||
}
|
||||
|
||||
// SetOtherValues
|
||||
void
|
||||
ColorSlider::SetOtherValues(float value1, float value2)
|
||||
{
|
||||
fFixedValue1 = value1;
|
||||
fFixedValue2 = value2;
|
||||
|
||||
if (fMode != H_SELECTED) {
|
||||
Update(2);
|
||||
}
|
||||
}
|
||||
|
||||
// GetOtherValues
|
||||
void
|
||||
ColorSlider::GetOtherValues(float* value1, float* value2) const
|
||||
{
|
||||
if (value1 && value2) {
|
||||
*value1 = fFixedValue1;
|
||||
*value2 = fFixedValue2;
|
||||
}
|
||||
}
|
||||
|
||||
// SetMarkerToColor
|
||||
void
|
||||
ColorSlider::SetMarkerToColor(rgb_color color)
|
||||
{
|
||||
float h, s, v;
|
||||
if (fMode & (H_SELECTED | S_SELECTED | V_SELECTED)) {
|
||||
RGB_to_HSV((float)color.red / 255.0,
|
||||
(float)color.green / 255.0,
|
||||
(float)color.blue / 255.0,
|
||||
h, s, v);
|
||||
}
|
||||
|
||||
switch (fMode) {
|
||||
|
||||
case R_SELECTED: {
|
||||
SetValue( 255 - color.red );
|
||||
} break;
|
||||
|
||||
case G_SELECTED: {
|
||||
SetValue( 255 - color.green );
|
||||
} break;
|
||||
|
||||
case B_SELECTED: {
|
||||
SetValue( 255 - color.blue );
|
||||
} break;
|
||||
|
||||
case H_SELECTED: {
|
||||
SetValue( 255.0 - round(h / 6.0 * 255.0) );
|
||||
} break;
|
||||
|
||||
case S_SELECTED: {
|
||||
SetValue( 255.0 - round(s * 255.0) );
|
||||
} break;
|
||||
|
||||
case V_SELECTED: {
|
||||
SetValue( 255.0 - round(v * 255.0) );
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// _UpdateThread
|
||||
int32
|
||||
ColorSlider::_UpdateThread(void* data)
|
||||
{
|
||||
// initializing
|
||||
ColorSlider* colorSlider = (ColorSlider*)data;
|
||||
|
||||
bool looperLocked = colorSlider->LockLooper();
|
||||
|
||||
port_id port = colorSlider->fUpdatePort;
|
||||
orientation orient = colorSlider->fOrientation;
|
||||
|
||||
if (looperLocked)
|
||||
colorSlider->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 (colorSlider->LockLooper()) {
|
||||
|
||||
uint colormode = colorSlider->fMode;
|
||||
float fixedvalue1 = colorSlider->fFixedValue1;
|
||||
float fixedvalue2 = colorSlider->fFixedValue2;
|
||||
|
||||
BBitmap* bitmap = colorSlider->fBgBitmap;
|
||||
BView* view = colorSlider->fBgView;
|
||||
|
||||
bitmap->Lock();
|
||||
|
||||
colorSlider->UnlockLooper();
|
||||
|
||||
view->BeginLineArray(256);
|
||||
|
||||
switch (colormode) {
|
||||
|
||||
case R_SELECTED: {
|
||||
G = round(fixedvalue1 * 255);
|
||||
B = round(fixedvalue2 * 255);
|
||||
for (int R = 0; R < 256; ++R) {
|
||||
_DrawColorLineY( view, R, R, G, B );
|
||||
}
|
||||
}; break;
|
||||
|
||||
case G_SELECTED: {
|
||||
R = round(fixedvalue1 * 255);
|
||||
B = round(fixedvalue2 * 255);
|
||||
for (int G = 0; G < 256; ++G) {
|
||||
_DrawColorLineY( view, G, R, G, B );
|
||||
}
|
||||
}; break;
|
||||
|
||||
case B_SELECTED: {
|
||||
R = round(fixedvalue1 * 255);
|
||||
G = round(fixedvalue2 * 255);
|
||||
for (int B = 0; B < 256; ++B) {
|
||||
_DrawColorLineY( view, B, R, G, B );
|
||||
}
|
||||
}; break;
|
||||
|
||||
case H_SELECTED: {
|
||||
s = 1.0;//fixedvalue1;
|
||||
v = 1.0;//fixedvalue2;
|
||||
if (orient == B_VERTICAL) {
|
||||
for (int y = 0; y < 256; ++y) {
|
||||
HSV_to_RGB( (float)y*6.0/255.0, s, v, r, g, b );
|
||||
_DrawColorLineY( view, y, r*255, g*255, b*255 );
|
||||
}
|
||||
} else {
|
||||
for (int x = 0; x < 256; ++x) {
|
||||
HSV_to_RGB( (float)x*6.0/255.0, s, v, r, g, b );
|
||||
_DrawColorLineX( view, x, r*255, g*255, b*255 );
|
||||
}
|
||||
}
|
||||
}; break;
|
||||
|
||||
case S_SELECTED: {
|
||||
h = fixedvalue1;
|
||||
v = 1.0;//fixedvalue2;
|
||||
for (int y = 0; y < 256; ++y) {
|
||||
HSV_to_RGB( h, (float)y/255, v, r, g, b );
|
||||
_DrawColorLineY( view, y, r*255, g*255, b*255 );
|
||||
}
|
||||
}; break;
|
||||
|
||||
case V_SELECTED: {
|
||||
h = fixedvalue1;
|
||||
s = 1.0;//fixedvalue2;
|
||||
for (int y = 0; y < 256; ++y) {
|
||||
HSV_to_RGB( h, s, (float)y/255, r, g, b );
|
||||
_DrawColorLineY( view, y, r*255, g*255, b*255 );
|
||||
}
|
||||
}; break;
|
||||
}
|
||||
|
||||
view->EndLineArray();
|
||||
view->Sync();
|
||||
bitmap->Unlock();
|
||||
|
||||
if (colorSlider->LockLooper()) {
|
||||
colorSlider->Update(1);
|
||||
colorSlider->UnlockLooper();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// _DrawColorLineY
|
||||
void
|
||||
ColorSlider::_DrawColorLineY(BView *view, float y,
|
||||
int r, int g, int b)
|
||||
{
|
||||
rgb_color color = { r, g, b, 255 };
|
||||
y = 255.0 - y;
|
||||
view->AddLine( BPoint(8.0, y + 5.0), BPoint(27.0, y + 5.0), color );
|
||||
}
|
||||
|
||||
// _DrawColorLineX
|
||||
void
|
||||
ColorSlider::_DrawColorLineX(BView *view, float x,
|
||||
int r, int g, int b)
|
||||
{
|
||||
rgb_color color = { r, g, b, 255 };
|
||||
BRect bounds(view->Bounds());
|
||||
x = (255.0 - x) * (bounds.Width() - 2.0) / 255.0 + 2.0;
|
||||
view->AddLine( BPoint(x, bounds.top + 2.0), BPoint(x, bounds.bottom - 2.0), color );
|
||||
}
|
||||
|
||||
// _TrackMouse
|
||||
void
|
||||
ColorSlider::_TrackMouse(BPoint where)
|
||||
{
|
||||
if (fOrientation == B_VERTICAL) {
|
||||
SetValue((int)where.y - 2);
|
||||
} else {
|
||||
BRect b(Bounds());
|
||||
SetValue((int)(((where.x - 2.0) / b.Width()) * 255.0));
|
||||
}
|
||||
Invoke();
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
* Copyright 2002-2006, Stephan Aßmus <superstippi@gmx.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _COLOR_SLIDER_H
|
||||
#define _COLOR_SLIDER_H
|
||||
|
||||
#include "ColorPickerDefs.h"
|
||||
|
||||
#include <Control.h>
|
||||
|
||||
#if LIB_LAYOUT
|
||||
# include <layout.h>
|
||||
#endif
|
||||
|
||||
#include "selected_color_mode.h"
|
||||
|
||||
#define MSG_COLOR_SLIDER 'ColS'
|
||||
|
||||
class BBitmap;
|
||||
|
||||
class ColorSlider :
|
||||
#if LIB_LAYOUT
|
||||
public MView,
|
||||
#endif
|
||||
public BControl {
|
||||
|
||||
public:
|
||||
ColorSlider(BPoint offset_point,
|
||||
selected_color_mode mode,
|
||||
float value1, float value2,
|
||||
orientation dir = B_VERTICAL);
|
||||
virtual ~ColorSlider();
|
||||
|
||||
#if LIB_LAYOUT
|
||||
// MView
|
||||
virtual minimax layoutprefs();
|
||||
virtual BRect layout(BRect frame);
|
||||
#endif
|
||||
|
||||
// BControl
|
||||
virtual void AttachedToWindow();
|
||||
|
||||
virtual status_t Invoke(BMessage* message = NULL);
|
||||
|
||||
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* dragMessage);
|
||||
|
||||
virtual void SetValue(int32 value);
|
||||
|
||||
// ColorSlider
|
||||
void Update(int depth);
|
||||
|
||||
bool IsTracking() const
|
||||
{ return fMouseDown; }
|
||||
|
||||
void SetModeAndValues(selected_color_mode mode,
|
||||
float value1, float value2);
|
||||
void SetOtherValues(float value1, float value2);
|
||||
void GetOtherValues(float* value1, float* value2) const;
|
||||
|
||||
void SetMarkerToColor( rgb_color color );
|
||||
|
||||
// inline void _DrawColorLineY( float y, int r, int g, int b);
|
||||
private:
|
||||
|
||||
static int32 _UpdateThread(void* cookie);
|
||||
static inline void _DrawColorLineY(BView* view, float y,
|
||||
int r, int g, int b);
|
||||
static inline void _DrawColorLineX(BView* view, float x,
|
||||
int r, int g, int b);
|
||||
void _TrackMouse(BPoint where);
|
||||
|
||||
selected_color_mode fMode;
|
||||
float fFixedValue1;
|
||||
float fFixedValue2;
|
||||
|
||||
bool fMouseDown;
|
||||
|
||||
BBitmap* fBgBitmap;
|
||||
BView* fBgView;
|
||||
|
||||
thread_id fUpdateThread;
|
||||
port_id fUpdatePort;
|
||||
|
||||
orientation fOrientation;
|
||||
};
|
||||
|
||||
#endif
|
16
src/apps/icon-o-matic/generic/gui/panel/color_picker/LICENSE
Normal file
16
src/apps/icon-o-matic/generic/gui/panel/color_picker/LICENSE
Normal file
@ -0,0 +1,16 @@
|
||||
License
|
||||
You may use this source code without charge in your own projects, as long as you create a BeOS program. If you want to create something else, please contact the author about an individual license.
|
||||
|
||||
If you re-release this source code or parts of it, you must add this LICENSE file.
|
||||
|
||||
All graphics, especially the icon or brands are copyrighted by the author and may not be used in any form without the author's consent.
|
||||
|
||||
Author / contact
|
||||
Werner Freytag
|
||||
Neurieder Str. 8
|
||||
82152 Martinsried
|
||||
Germany
|
||||
|
||||
e-mail: info@pecora.de
|
||||
visit: http://www.pecora.de
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CONVERT_RGB_HSV_H
|
||||
#define CONVERT_RGB_HSV_H
|
||||
|
||||
#define RETURN_HSV(h, s, v) { H = h; S = s; V = v; return; }
|
||||
#define RETURN_RGB(r, g, b) { R = r; G = g; B = b; return; }
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define UNDEFINED 0
|
||||
|
||||
inline void
|
||||
RGB_to_HSV(float R, float G, float B, float& H, float& S, float& V)
|
||||
{
|
||||
// RGB are each on [0, 1]. S and max are returned on [0, 1] and H is
|
||||
// returned on [0, 6]. Eminception: H is returned UNDEFINED if S==0.
|
||||
|
||||
float min, max;
|
||||
|
||||
if (R > G) {
|
||||
if (R > B) {
|
||||
max = R;
|
||||
min = G > B ? B : G;
|
||||
}
|
||||
else {
|
||||
max = B;
|
||||
min = G;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (G > B) {
|
||||
max = G;
|
||||
min = R > B ? B : R;
|
||||
}
|
||||
else {
|
||||
max = B;
|
||||
min = R;
|
||||
}
|
||||
}
|
||||
|
||||
if (max == min) RETURN_HSV(UNDEFINED, 0, max);
|
||||
|
||||
float dist = max - min;
|
||||
|
||||
float f = (R == min) ? G - B : ((G == min) ? B - R : R - G);
|
||||
float i = (R == min) ? 3 : ((G == min) ? 5 : 1);
|
||||
float h = i - f / dist;
|
||||
|
||||
while (h >= 6.0) h -= 6.0;
|
||||
|
||||
RETURN_HSV(h, dist/max, max);
|
||||
|
||||
}
|
||||
|
||||
inline void
|
||||
HSV_to_RGB(float h, float s, float v, float& R, float& G, float& B)
|
||||
{
|
||||
// H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1].
|
||||
// RGB are each returned on [0, 1].
|
||||
|
||||
int i = (int)floor(h);
|
||||
|
||||
float f = h - i;
|
||||
|
||||
if ( !(i & 1) ) f = 1 - f; // if i is even
|
||||
|
||||
float m = v * (1 - s);
|
||||
|
||||
float n = v * (1 - s * f);
|
||||
|
||||
switch (i) {
|
||||
|
||||
case 6:
|
||||
|
||||
case 0: RETURN_RGB(v, n, m);
|
||||
|
||||
case 1: RETURN_RGB(n, v, m);
|
||||
|
||||
case 2: RETURN_RGB(m, v, n)
|
||||
|
||||
case 3: RETURN_RGB(m, n, v);
|
||||
|
||||
case 4: RETURN_RGB(n, m, v);
|
||||
|
||||
case 5: RETURN_RGB(v, m, n);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CONVERT_RGB_HSV_H
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2001 Werner Freytag - please read to the LICENSE file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SELECTED_COLOR_MODE_H
|
||||
#define _SELECTED_COLOR_MODE_H
|
||||
|
||||
enum selected_color_mode {
|
||||
R_SELECTED = 0x01,
|
||||
G_SELECTED = 0x02,
|
||||
B_SELECTED = 0x04,
|
||||
H_SELECTED = 0x10,
|
||||
S_SELECTED = 0x20,
|
||||
V_SELECTED = 0x40
|
||||
};
|
||||
|
||||
#endif // _SELECTED_COLOR_MODE_H
|
@ -6,7 +6,7 @@
|
||||
* Stephan Aßmus <superstippi@gmx.de>
|
||||
*/
|
||||
|
||||
#include "support.h"
|
||||
#include "support_ui.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -21,8 +21,6 @@
|
||||
#include <Path.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <Space.h>
|
||||
|
||||
// stroke_frame
|
||||
void
|
||||
stroke_frame(BView* v, BRect r, rgb_color left, rgb_color top,
|
||||
@ -42,20 +40,6 @@ stroke_frame(BView* v, BRect r, rgb_color left, rgb_color top,
|
||||
}
|
||||
}
|
||||
|
||||
// vertical_space
|
||||
Space*
|
||||
vertical_space()
|
||||
{
|
||||
return new Space(minimax(0.0, 3.0, 10000.0, 3.0, 1.0));
|
||||
}
|
||||
|
||||
// horizontal_space
|
||||
Space*
|
||||
horizontal_space()
|
||||
{
|
||||
return new Space(minimax(3.0, 0.0, 3.0, 10000.0, 1.0));
|
||||
}
|
||||
|
||||
// store_color_in_message
|
||||
status_t
|
||||
store_color_in_message(BMessage* message, rgb_color color)
|
||||
|
@ -20,7 +20,6 @@ class BPositionIO;
|
||||
class BString;
|
||||
class BView;
|
||||
class BWindow;
|
||||
class Space;
|
||||
|
||||
// looper of view must be locked!
|
||||
void stroke_frame(BView* view, BRect frame,
|
||||
@ -28,9 +27,6 @@ void stroke_frame(BView* view, BRect frame,
|
||||
rgb_color right, rgb_color bottom);
|
||||
|
||||
|
||||
Space* vertical_space();
|
||||
Space* horizontal_space();
|
||||
|
||||
status_t store_color_in_message(BMessage* message, rgb_color color);
|
||||
|
||||
status_t restore_color_from_message(const BMessage* message, rgb_color& color, int32 index = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user