* added GradientControl which can edit a Gradient
* filled out StyleView for configuring a Style * added SetGradientCommand for undo/redo editing a Gradient * Style::SetGradient() doesn't assume ownership of the Gradient passed in anymore git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18092 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -108,10 +108,12 @@ Application Icon-O-Matic :
|
|||||||
support.cpp
|
support.cpp
|
||||||
support_ui.cpp
|
support_ui.cpp
|
||||||
# gui
|
# gui
|
||||||
|
GradientControl.cpp
|
||||||
IconObjectListView.cpp
|
IconObjectListView.cpp
|
||||||
PathListView.cpp
|
PathListView.cpp
|
||||||
ShapeListView.cpp
|
ShapeListView.cpp
|
||||||
StyleListView.cpp
|
StyleListView.cpp
|
||||||
|
StyleView.cpp
|
||||||
SwatchGroup.cpp
|
SwatchGroup.cpp
|
||||||
TransformerListView.cpp
|
TransformerListView.cpp
|
||||||
# shape
|
# shape
|
||||||
@@ -133,6 +135,7 @@ Application Icon-O-Matic :
|
|||||||
# style
|
# style
|
||||||
CurrentColor.cpp
|
CurrentColor.cpp
|
||||||
Gradient.cpp
|
Gradient.cpp
|
||||||
|
SetGradientCommand.cpp
|
||||||
Style.cpp
|
Style.cpp
|
||||||
StyleManager.cpp
|
StyleManager.cpp
|
||||||
# transformer
|
# transformer
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include "ScrollView.h"
|
#include "ScrollView.h"
|
||||||
#include "ShapeListView.h"
|
#include "ShapeListView.h"
|
||||||
#include "StyleListView.h"
|
#include "StyleListView.h"
|
||||||
|
#include "StyleView.h"
|
||||||
#include "SwatchGroup.h"
|
#include "SwatchGroup.h"
|
||||||
#include "TransformerFactory.h"
|
#include "TransformerFactory.h"
|
||||||
#include "TransformerListView.h"
|
#include "TransformerListView.h"
|
||||||
@@ -127,6 +128,7 @@ case MSG_STYLE_SELECTED: {
|
|||||||
if (message->FindPointer("style", (void**)&style) < B_OK)
|
if (message->FindPointer("style", (void**)&style) < B_OK)
|
||||||
style = NULL;
|
style = NULL;
|
||||||
fSwatchGroup->SetCurrentStyle(style);
|
fSwatchGroup->SetCurrentStyle(style);
|
||||||
|
fStyleView->SetStyle(style);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: use an AddShapeCommand
|
// TODO: use an AddShapeCommand
|
||||||
@@ -237,6 +239,8 @@ MainWindow::_Init()
|
|||||||
// fStyleListView->SetCommandStack(fDocument->CommandStack());
|
// fStyleListView->SetCommandStack(fDocument->CommandStack());
|
||||||
fStyleListView->SetSelection(fDocument->Selection());
|
fStyleListView->SetSelection(fDocument->Selection());
|
||||||
|
|
||||||
|
fStyleView->SetCommandStack(fDocument->CommandStack());
|
||||||
|
|
||||||
fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes());
|
fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes());
|
||||||
fShapeListView->SetCommandStack(fDocument->CommandStack());
|
fShapeListView->SetCommandStack(fDocument->CommandStack());
|
||||||
fShapeListView->SetSelection(fDocument->Selection());
|
fShapeListView->SetSelection(fDocument->Selection());
|
||||||
@@ -271,11 +275,11 @@ MainWindow::_Init()
|
|||||||
StyleManager::Default()->AddStyle(style1);
|
StyleManager::Default()->AddStyle(style1);
|
||||||
|
|
||||||
Style* style2 = new Style();
|
Style* style2 = new Style();
|
||||||
Gradient* gradient = new Gradient(true);
|
Gradient gradient(true);
|
||||||
gradient->AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0);
|
gradient.AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0);
|
||||||
gradient->AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5);
|
gradient.AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5);
|
||||||
gradient->AddColor((rgb_color){ 208, 43, 92, 255 }, 1.0);
|
gradient.AddColor((rgb_color){ 208, 43, 92, 255 }, 1.0);
|
||||||
style2->SetGradient(gradient);
|
style2->SetGradient(&gradient);
|
||||||
|
|
||||||
StyleManager::Default()->AddStyle(style2);
|
StyleManager::Default()->AddStyle(style2);
|
||||||
|
|
||||||
@@ -407,6 +411,14 @@ MainWindow::_CreateGUI(BRect bounds)
|
|||||||
new BMessage(MSG_STYLE_SELECTED), this);
|
new BMessage(MSG_STYLE_SELECTED), this);
|
||||||
|
|
||||||
|
|
||||||
|
// style view
|
||||||
|
bounds.left = menuBar->Frame().right + 1;
|
||||||
|
bounds.top = bg->Bounds().top;
|
||||||
|
bounds.right = fSwatchGroup->Frame().left - 1;
|
||||||
|
bounds.bottom = fCanvasView->Frame().top - 1;
|
||||||
|
fStyleView = new StyleView(bounds);
|
||||||
|
bg->AddChild(fStyleView);
|
||||||
|
|
||||||
// path list view
|
// path list view
|
||||||
bounds.left = 0;
|
bounds.left = 0;
|
||||||
bounds.right = fCanvasView->Frame().left - 1;
|
bounds.right = fCanvasView->Frame().left - 1;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class IconView;
|
|||||||
class PathListView;
|
class PathListView;
|
||||||
class ShapeListView;
|
class ShapeListView;
|
||||||
class StyleListView;
|
class StyleListView;
|
||||||
|
class StyleView;
|
||||||
class SwatchGroup;
|
class SwatchGroup;
|
||||||
class TransformerListView;
|
class TransformerListView;
|
||||||
|
|
||||||
@@ -62,6 +63,7 @@ class MainWindow : public BWindow,
|
|||||||
|
|
||||||
CanvasView* fCanvasView;
|
CanvasView* fCanvasView;
|
||||||
SwatchGroup* fSwatchGroup;
|
SwatchGroup* fSwatchGroup;
|
||||||
|
StyleView* fStyleView;
|
||||||
|
|
||||||
IconView* fIconPreview16;
|
IconView* fIconPreview16;
|
||||||
IconView* fIconPreview32;
|
IconView* fIconPreview32;
|
||||||
|
|||||||
@@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
* implement commands for the newly added editing features
|
* implement commands for the newly added editing features
|
||||||
|
|
||||||
|
* built-in transformation for Gradient and Shape?
|
||||||
|
|
||||||
|
* Transformation manipulator
|
||||||
|
|
||||||
|
|
||||||
--------- user interface
|
--------- user interface
|
||||||
|
|
||||||
@@ -45,7 +49,7 @@
|
|||||||
|
|
||||||
* list of transformers attached to the selected shape [done]
|
* list of transformers attached to the selected shape [done]
|
||||||
|
|
||||||
* area for styles, style is either solid color or gradient
|
* area for styles, style is either solid color or gradient [done]
|
||||||
|
|
||||||
|
|
||||||
--------- icon format
|
--------- icon format
|
||||||
|
|||||||
@@ -0,0 +1,634 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "GradientControl.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <AppDefs.h>
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "ui_defines.h"
|
||||||
|
#include "support_ui.h"
|
||||||
|
|
||||||
|
#include "Gradient.h"
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
GradientControl::GradientControl(BMessage* message, BHandler* target)
|
||||||
|
: BView(BRect(0, 0, 259, 19), "gradient control", B_FOLLOW_NONE,
|
||||||
|
B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE),
|
||||||
|
fGradient(new ::Gradient()),
|
||||||
|
fGradientBitmap(NULL),
|
||||||
|
fDraggingStepIndex(-1),
|
||||||
|
fCurrentStepIndex(-1),
|
||||||
|
fDropOffset(-1.0),
|
||||||
|
fDropIndex(-1),
|
||||||
|
fEnabled(true),
|
||||||
|
fMessage(message),
|
||||||
|
fTarget(target)
|
||||||
|
{
|
||||||
|
FrameResized(Bounds().Width(), Bounds().Height());
|
||||||
|
SetViewColor(B_TRANSPARENT_32_BIT);
|
||||||
|
SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
GradientControl::~GradientControl()
|
||||||
|
{
|
||||||
|
delete fGradient;
|
||||||
|
delete fGradientBitmap;
|
||||||
|
delete fMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LIB_LAYOUT
|
||||||
|
// layoutprefs
|
||||||
|
minimax
|
||||||
|
GradientControl::layoutprefs()
|
||||||
|
{
|
||||||
|
mpm.mini.x = 256 + 4;
|
||||||
|
mpm.maxi.x = mpm.mini.x + 10000;
|
||||||
|
mpm.mini.y = 20;
|
||||||
|
mpm.maxi.y = mpm.mini.y + 10;
|
||||||
|
|
||||||
|
mpm.weight = 2.0;
|
||||||
|
|
||||||
|
return mpm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// layout
|
||||||
|
BRect
|
||||||
|
GradientControl::layout(BRect frame)
|
||||||
|
{
|
||||||
|
MoveTo(frame.LeftTop());
|
||||||
|
ResizeTo(frame.Width(), frame.Height());
|
||||||
|
return Frame();
|
||||||
|
}
|
||||||
|
#endif // LIB_LAYOUT
|
||||||
|
|
||||||
|
// WindowActivated
|
||||||
|
void
|
||||||
|
GradientControl::WindowActivated(bool active)
|
||||||
|
{
|
||||||
|
if (IsFocus())
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MakeFocus
|
||||||
|
void
|
||||||
|
GradientControl::MakeFocus(bool focus)
|
||||||
|
{
|
||||||
|
if (focus != IsFocus()) {
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
Invalidate();
|
||||||
|
// keep the window informed when the focus of this object changes
|
||||||
|
if (BWindow* window = Window())
|
||||||
|
window->PostMessage(MSG_GRADIENT_CONTROL_FOCUS_CHANGED);
|
||||||
|
}
|
||||||
|
BView::MakeFocus(focus);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MouseDown
|
||||||
|
void
|
||||||
|
GradientControl::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
if (!fEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!IsFocus()) {
|
||||||
|
MakeFocus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
fDraggingStepIndex = _StepIndexFor(where);
|
||||||
|
|
||||||
|
if (fDraggingStepIndex >= 0)
|
||||||
|
SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS);
|
||||||
|
|
||||||
|
// handle double click
|
||||||
|
int32 clicks;
|
||||||
|
if (Window()->CurrentMessage()->FindInt32("clicks", &clicks) >= B_OK && clicks >= 2) {
|
||||||
|
if (fDraggingStepIndex < 0) {
|
||||||
|
// create a new offset at the click location that uses
|
||||||
|
// the interpolated color
|
||||||
|
float offset = _OffsetFor(where);
|
||||||
|
// create a clean gradient
|
||||||
|
uint32 width = fGradientBitmap->Bounds().IntegerWidth();
|
||||||
|
uint8* temp = new uint8[width * 4];
|
||||||
|
fGradient->MakeGradient((uint32*)temp, width);
|
||||||
|
// get the color at the offset
|
||||||
|
rgb_color color;
|
||||||
|
uint8* bits = temp;
|
||||||
|
bits += 4 * (uint32)((width - 1) * offset);
|
||||||
|
color.red = bits[2];
|
||||||
|
color.green = bits[1];
|
||||||
|
color.blue = bits[0];
|
||||||
|
color.alpha = bits[3];
|
||||||
|
fCurrentStepIndex = fGradient->AddColor(color, offset);
|
||||||
|
fDraggingStepIndex = -1;
|
||||||
|
_UpdateColors();
|
||||||
|
Invalidate();
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
delete[] temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fCurrentStepIndex != fDraggingStepIndex && fDraggingStepIndex >= 0) {
|
||||||
|
// start dragging this stop
|
||||||
|
fCurrentStepIndex = fDraggingStepIndex;
|
||||||
|
Invalidate();
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MouseUp
|
||||||
|
void
|
||||||
|
GradientControl::MouseUp(BPoint where)
|
||||||
|
{
|
||||||
|
fDraggingStepIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MouseMoved
|
||||||
|
void
|
||||||
|
GradientControl::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMessage)
|
||||||
|
{
|
||||||
|
if (!fEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float offset = _OffsetFor(where);
|
||||||
|
|
||||||
|
if (fDraggingStepIndex >= 0) {
|
||||||
|
color_step* step = fGradient->ColorAt(fDraggingStepIndex);
|
||||||
|
if (step) {
|
||||||
|
if (fGradient->SetOffset(fDraggingStepIndex, offset)) {
|
||||||
|
_UpdateColors();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int32 dropIndex = -1;
|
||||||
|
float dropOffset = -1.0;
|
||||||
|
if (dragMessage && (transit == B_INSIDE_VIEW || transit == B_ENTERED_VIEW)) {
|
||||||
|
rgb_color dragColor;
|
||||||
|
if (restore_color_from_message(dragMessage, dragColor, 0) >= B_OK) {
|
||||||
|
dropIndex = _StepIndexFor(where);
|
||||||
|
// fall back to inserting a color step if no direct hit on an existing step
|
||||||
|
if (dropIndex < 0)
|
||||||
|
dropOffset = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fDropOffset != dropOffset || fDropIndex != dropIndex) {
|
||||||
|
fDropOffset = dropOffset;
|
||||||
|
fDropIndex = dropIndex;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageReceived
|
||||||
|
void
|
||||||
|
GradientControl::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case B_PASTE:
|
||||||
|
if (fEnabled) {
|
||||||
|
rgb_color color;
|
||||||
|
if (restore_color_from_message(message, color, 0) >= B_OK) {
|
||||||
|
bool update = false;
|
||||||
|
if (fDropIndex >= 0) {
|
||||||
|
if (color_step* step = fGradient->ColorAt(fDropIndex)) {
|
||||||
|
color.alpha = step->color.alpha;
|
||||||
|
}
|
||||||
|
fGradient->SetColor(fDropIndex, color);
|
||||||
|
fCurrentStepIndex = fDropIndex;
|
||||||
|
fDropIndex = -1;
|
||||||
|
update = true;
|
||||||
|
} else if (fDropOffset >= 0.0) {
|
||||||
|
fCurrentStepIndex = fGradient->AddColor(color, fDropOffset);
|
||||||
|
fDropOffset = -1.0;
|
||||||
|
update = true;
|
||||||
|
}
|
||||||
|
if (update) {
|
||||||
|
_UpdateColors();
|
||||||
|
if (!IsFocus())
|
||||||
|
MakeFocus(true);
|
||||||
|
else
|
||||||
|
Invalidate();
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BView::MessageReceived(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyDown
|
||||||
|
void
|
||||||
|
GradientControl::KeyDown(const char* bytes, int32 numBytes)
|
||||||
|
{
|
||||||
|
bool handled = false;
|
||||||
|
bool update = false;
|
||||||
|
if (fEnabled) {
|
||||||
|
if (numBytes > 0) {
|
||||||
|
handled = true;
|
||||||
|
int32 count = fGradient->CountColors();
|
||||||
|
switch (bytes[0]) {
|
||||||
|
case B_DELETE:
|
||||||
|
// remove step
|
||||||
|
update = fGradient->RemoveColor(fCurrentStepIndex);
|
||||||
|
if (update) {
|
||||||
|
fCurrentStepIndex = max_c(0, fCurrentStepIndex - 1);
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case B_HOME:
|
||||||
|
case B_END:
|
||||||
|
case B_LEFT_ARROW:
|
||||||
|
case B_RIGHT_ARROW: {
|
||||||
|
if (color_step* step = fGradient->ColorAt(fCurrentStepIndex)) {
|
||||||
|
BRect r = _GradientBitmapRect();
|
||||||
|
float x = r.left + r.Width() * step->offset;
|
||||||
|
switch (bytes[0]) {
|
||||||
|
case B_LEFT_ARROW:
|
||||||
|
// move step to the left
|
||||||
|
x = max_c(r.left, x - 1.0);
|
||||||
|
break;
|
||||||
|
case B_RIGHT_ARROW:
|
||||||
|
// move step to the right
|
||||||
|
x = min_c(r.right, x + 1.0);
|
||||||
|
break;
|
||||||
|
case B_HOME:
|
||||||
|
// move step to the start
|
||||||
|
x = r.left;
|
||||||
|
break;
|
||||||
|
case B_END:
|
||||||
|
// move step to the start
|
||||||
|
x = r.right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
update = fGradient->SetOffset(fCurrentStepIndex, (x - r.left) / r.Width());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_UP_ARROW:
|
||||||
|
// previous step
|
||||||
|
fCurrentStepIndex--;
|
||||||
|
if (fCurrentStepIndex < 0) {
|
||||||
|
fCurrentStepIndex = count - 1;
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case B_DOWN_ARROW:
|
||||||
|
// next step
|
||||||
|
fCurrentStepIndex++;
|
||||||
|
if (fCurrentStepIndex >= count) {
|
||||||
|
fCurrentStepIndex = 0;
|
||||||
|
_UpdateCurrentColor();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
handled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!handled)
|
||||||
|
BView::KeyDown(bytes, numBytes);
|
||||||
|
else {
|
||||||
|
if (update)
|
||||||
|
_UpdateColors();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
void
|
||||||
|
GradientControl::Draw(BRect updateRect)
|
||||||
|
{
|
||||||
|
BRect b = _GradientBitmapRect();
|
||||||
|
b.InsetBy(-2.0, -2.0);
|
||||||
|
// background
|
||||||
|
// left of gradient rect
|
||||||
|
BRect lb(updateRect.left, updateRect.top, b.left - 1, b.bottom);
|
||||||
|
if (lb.IsValid())
|
||||||
|
FillRect(lb, B_SOLID_LOW);
|
||||||
|
// right of gradient rect
|
||||||
|
BRect rb(b.right + 1, updateRect.top, updateRect.right, b.bottom);
|
||||||
|
if (rb.IsValid())
|
||||||
|
FillRect(rb, B_SOLID_LOW);
|
||||||
|
// bottom of gradient rect
|
||||||
|
BRect bb(updateRect.left, b.bottom + 1, updateRect.right, updateRect.bottom);
|
||||||
|
if (bb.IsValid())
|
||||||
|
FillRect(bb, B_SOLID_LOW);
|
||||||
|
|
||||||
|
bool isFocus = IsFocus() && Window()->IsActive();
|
||||||
|
|
||||||
|
rgb_color bg = LowColor();
|
||||||
|
rgb_color shadow;
|
||||||
|
rgb_color darkShadow;
|
||||||
|
rgb_color light;
|
||||||
|
rgb_color black;
|
||||||
|
|
||||||
|
if (fEnabled) {
|
||||||
|
shadow = tint_color(bg, B_DARKEN_1_TINT);
|
||||||
|
darkShadow = tint_color(bg, B_DARKEN_3_TINT);
|
||||||
|
light = tint_color(bg, B_LIGHTEN_MAX_TINT);
|
||||||
|
black = tint_color(bg, B_DARKEN_MAX_TINT);
|
||||||
|
} else {
|
||||||
|
shadow = bg;
|
||||||
|
darkShadow = tint_color(bg, B_DARKEN_1_TINT);
|
||||||
|
light = tint_color(bg, B_LIGHTEN_2_TINT);
|
||||||
|
black = tint_color(bg, B_DARKEN_2_TINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
rgb_color focus = isFocus ? ui_color(B_KEYBOARD_NAVIGATION_COLOR)
|
||||||
|
: black;
|
||||||
|
|
||||||
|
stroke_frame(this, b, shadow, shadow, light, light);
|
||||||
|
b.InsetBy(1.0, 1.0);
|
||||||
|
if (isFocus)
|
||||||
|
stroke_frame(this, b, focus, focus, focus, focus);
|
||||||
|
else
|
||||||
|
stroke_frame(this, b, darkShadow, darkShadow, bg, bg);
|
||||||
|
b.InsetBy(1.0, 1.0);
|
||||||
|
|
||||||
|
// DrawBitmapAsync(fGradientBitmap, b.LeftTop());
|
||||||
|
// Sync();
|
||||||
|
DrawBitmap(fGradientBitmap, b.LeftTop());
|
||||||
|
|
||||||
|
// show drop offset
|
||||||
|
if (fDropOffset >= 0.0) {
|
||||||
|
SetHighColor(255, 0, 0, 255);
|
||||||
|
float x = b.left + b.Width() * fDropOffset;
|
||||||
|
StrokeLine(BPoint(x, b.top), BPoint(x, b.bottom));
|
||||||
|
}
|
||||||
|
|
||||||
|
BPoint markerPos;
|
||||||
|
markerPos.y = b.bottom + 4.0;
|
||||||
|
BPoint leftBottom(-6.0, 6.0);
|
||||||
|
BPoint rightBottom(6.0, 6.0);
|
||||||
|
for (int32 i = 0; color_step* step = fGradient->ColorAt(i); i++) {
|
||||||
|
markerPos.x = b.left + (b.Width() * step->offset);
|
||||||
|
|
||||||
|
if (i == fCurrentStepIndex) {
|
||||||
|
SetLowColor(focus);
|
||||||
|
if (isFocus) {
|
||||||
|
StrokeLine(markerPos + leftBottom + BPoint(1.0, 4.0),
|
||||||
|
markerPos + rightBottom + BPoint(-1.0, 4.0), B_SOLID_LOW);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SetLowColor(black);
|
||||||
|
}
|
||||||
|
|
||||||
|
// override in case this is the drop index step
|
||||||
|
if (i == fDropIndex)
|
||||||
|
SetLowColor(255, 0, 0, 255);
|
||||||
|
|
||||||
|
StrokeTriangle(markerPos,
|
||||||
|
markerPos + leftBottom,
|
||||||
|
markerPos + rightBottom, B_SOLID_LOW);
|
||||||
|
if (fEnabled) {
|
||||||
|
SetHighColor(step->color);
|
||||||
|
} else {
|
||||||
|
rgb_color c = step->color;
|
||||||
|
c.red = (uint8)(((uint32)bg.red + (uint32)c.red) / 2);
|
||||||
|
c.green = (uint8)(((uint32)bg.green + (uint32)c.green) / 2);
|
||||||
|
c.blue = (uint8)(((uint32)bg.blue + (uint32)c.blue) / 2);
|
||||||
|
SetHighColor(c);
|
||||||
|
}
|
||||||
|
FillTriangle(markerPos + BPoint(0.0, 1.0),
|
||||||
|
markerPos + leftBottom + BPoint(1.0, 0.0),
|
||||||
|
markerPos + rightBottom + BPoint(-1.0, 0.0));
|
||||||
|
StrokeLine(markerPos + leftBottom + BPoint(0.0, 1.0),
|
||||||
|
markerPos + rightBottom + BPoint(0.0, 1.0), B_SOLID_LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FrameResized
|
||||||
|
void
|
||||||
|
GradientControl::FrameResized(float width, float height)
|
||||||
|
{
|
||||||
|
BRect r = _GradientBitmapRect();
|
||||||
|
_AllocBitmap(r.IntegerWidth() + 1, r.IntegerHeight() + 1);
|
||||||
|
_UpdateColors();
|
||||||
|
Invalidate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGradient
|
||||||
|
void
|
||||||
|
GradientControl::SetGradient(const ::Gradient* gradient)
|
||||||
|
{
|
||||||
|
if (!gradient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*fGradient = *gradient;
|
||||||
|
_UpdateColors();
|
||||||
|
|
||||||
|
fDropOffset = -1.0;
|
||||||
|
fDropIndex = -1;
|
||||||
|
fDraggingStepIndex = -1;
|
||||||
|
fCurrentStepIndex = 0;
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCurrentStop
|
||||||
|
void
|
||||||
|
GradientControl::SetCurrentStop(const rgb_color& color)
|
||||||
|
{
|
||||||
|
if (fEnabled && fCurrentStepIndex >= 0) {
|
||||||
|
fGradient->SetColor(fCurrentStepIndex, color);
|
||||||
|
_UpdateColors();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCurrentStop
|
||||||
|
bool
|
||||||
|
GradientControl::GetCurrentStop(rgb_color* color) const
|
||||||
|
{
|
||||||
|
color_step* stop = fGradient->ColorAt(fCurrentStepIndex);
|
||||||
|
if (stop && color) {
|
||||||
|
*color = stop->color;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEnabled
|
||||||
|
void
|
||||||
|
GradientControl::SetEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (enabled == fEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fEnabled = enabled;
|
||||||
|
|
||||||
|
if (!fEnabled)
|
||||||
|
fDropIndex = -1;
|
||||||
|
|
||||||
|
_UpdateColors();
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// blend_colors
|
||||||
|
inline void
|
||||||
|
blend_colors(uint8* d, uint8 alpha, uint8 c1, uint8 c2, uint8 c3)
|
||||||
|
{
|
||||||
|
if (alpha > 0) {
|
||||||
|
if (alpha == 255) {
|
||||||
|
d[0] = c1;
|
||||||
|
d[1] = c2;
|
||||||
|
d[2] = c3;
|
||||||
|
} else {
|
||||||
|
d[0] += (uint8)(((c1 - d[0]) * alpha) >> 8);
|
||||||
|
d[1] += (uint8)(((c2 - d[1]) * alpha) >> 8);
|
||||||
|
d[2] += (uint8)(((c3 - d[2]) * alpha) >> 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _UpdateColors
|
||||||
|
void
|
||||||
|
GradientControl::_UpdateColors()
|
||||||
|
{
|
||||||
|
if (!fGradientBitmap || !fGradientBitmap->IsValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// fill in top row by gradient
|
||||||
|
uint8* topRow = (uint8*)fGradientBitmap->Bits();
|
||||||
|
uint32 width = fGradientBitmap->Bounds().IntegerWidth() + 1;
|
||||||
|
fGradient->MakeGradient((uint32*)topRow, width);
|
||||||
|
// flip colors, since they are the wrong endianess
|
||||||
|
// make colors the disabled look
|
||||||
|
// TODO: apply gamma lut
|
||||||
|
uint8* p = topRow;
|
||||||
|
if (!fEnabled) {
|
||||||
|
rgb_color bg = LowColor();
|
||||||
|
for (uint32 x = 0; x < width; x++) {
|
||||||
|
uint8 p0 = p[0];
|
||||||
|
p[0] = (uint8)(((uint32)bg.blue + (uint32)p[2]) / 2);
|
||||||
|
p[1] = (uint8)(((uint32)bg.green + (uint32)p[1]) / 2);
|
||||||
|
p[2] = (uint8)(((uint32)bg.red + (uint32)p0) / 2);
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (uint32 x = 0; x < width; x++) {
|
||||||
|
uint8 p0 = p[0];
|
||||||
|
p[0] = p[2];
|
||||||
|
p[2] = p0;
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copy top row to rest of bitmap
|
||||||
|
uint32 height = fGradientBitmap->Bounds().IntegerHeight() + 1;
|
||||||
|
uint32 bpr = fGradientBitmap->BytesPerRow();
|
||||||
|
uint8* dstRow = topRow + bpr;
|
||||||
|
for (uint32 i = 1; i < height; i++) {
|
||||||
|
memcpy(dstRow, topRow, bpr);
|
||||||
|
dstRow += bpr;
|
||||||
|
}
|
||||||
|
// post process bitmap to underlay it with a pattern
|
||||||
|
// in order to make gradient steps with alpha more visible!
|
||||||
|
uint8* row = topRow;
|
||||||
|
for (uint32 i = 0; i < height; i++) {
|
||||||
|
uint8* p = row;
|
||||||
|
for (uint32 x = 0; x < width; x++) {
|
||||||
|
uint8 alpha = p[3];
|
||||||
|
if (alpha < 255) {
|
||||||
|
p[3] = 255;
|
||||||
|
alpha = 255 - alpha;
|
||||||
|
if (x % 10 >= 5) {
|
||||||
|
if (i % 10 >= 5) {
|
||||||
|
blend_colors(p, alpha, kAlphaLow.blue, kAlphaLow.green, kAlphaLow.red);
|
||||||
|
} else {
|
||||||
|
blend_colors(p, alpha, kAlphaHigh.blue, kAlphaHigh.green, kAlphaHigh.red);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i % 10 >= 5) {
|
||||||
|
blend_colors(p, alpha, kAlphaHigh.blue, kAlphaHigh.green, kAlphaHigh.red);
|
||||||
|
} else {
|
||||||
|
blend_colors(p, alpha, kAlphaLow.blue, kAlphaLow.green, kAlphaLow.red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
row += bpr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _AllocBitmap
|
||||||
|
void
|
||||||
|
GradientControl::_AllocBitmap(int32 width, int32 height)
|
||||||
|
{
|
||||||
|
if (width < 2 || height < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete fGradientBitmap;
|
||||||
|
fGradientBitmap = new BBitmap(BRect(0, 0, width - 1, height - 1), 0, B_RGB32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// _GradientBitmapRect
|
||||||
|
BRect
|
||||||
|
GradientControl::_GradientBitmapRect() const
|
||||||
|
{
|
||||||
|
BRect r = Bounds();
|
||||||
|
r.left += 6.0;
|
||||||
|
r.top += 2.0;
|
||||||
|
r.right -= 6.0;
|
||||||
|
r.bottom -= 14.0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _StepIndexFor
|
||||||
|
int32
|
||||||
|
GradientControl::_StepIndexFor(BPoint where) const
|
||||||
|
{
|
||||||
|
int32 index = -1;
|
||||||
|
BRect r = _GradientBitmapRect();
|
||||||
|
BRect markerFrame(Bounds());
|
||||||
|
for (int32 i = 0; color_step* step = fGradient->ColorAt(i); i++) {
|
||||||
|
markerFrame.left = markerFrame.right = r.left + (r.Width() * step->offset);
|
||||||
|
markerFrame.InsetBy(-6.0, 0.0);
|
||||||
|
if (markerFrame.Contains(where)) {
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _OffsetFor
|
||||||
|
float
|
||||||
|
GradientControl::_OffsetFor(BPoint where) const
|
||||||
|
{
|
||||||
|
BRect r = _GradientBitmapRect();
|
||||||
|
float offset = (where.x - r.left) / r.Width();
|
||||||
|
offset = max_c(0.0, offset);
|
||||||
|
offset = min_c(1.0, offset);
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _UpdateCurrentColor
|
||||||
|
void
|
||||||
|
GradientControl::_UpdateCurrentColor() const
|
||||||
|
{
|
||||||
|
if (!fMessage || !fTarget || !fTarget->Looper())
|
||||||
|
// set the CanvasView current color
|
||||||
|
if (color_step* step = fGradient->ColorAt(fCurrentStepIndex)) {
|
||||||
|
BMessage message(*fMessage);
|
||||||
|
store_color_in_message(&message, step->color);
|
||||||
|
fTarget->Looper()->PostMessage(&message, fTarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRADIENT_CONTROL_H
|
||||||
|
#define GRADIENT_CONTROL_H
|
||||||
|
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#if LIB_LAYOUT
|
||||||
|
#include <layout.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Gradient;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_GRADIENT_CONTROL_FOCUS_CHANGED = 'gcfc',
|
||||||
|
};
|
||||||
|
|
||||||
|
class GradientControl :
|
||||||
|
#if LIB_LAYOUT
|
||||||
|
public MView,
|
||||||
|
#endif
|
||||||
|
public BView {
|
||||||
|
|
||||||
|
public:
|
||||||
|
GradientControl(BMessage* message = NULL,
|
||||||
|
BHandler* target = NULL);
|
||||||
|
virtual ~GradientControl();
|
||||||
|
|
||||||
|
// MView
|
||||||
|
#if LIB_LAYOUT
|
||||||
|
virtual minimax layoutprefs();
|
||||||
|
virtual BRect layout(BRect frame);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BView
|
||||||
|
virtual void WindowActivated(bool active);
|
||||||
|
virtual void MakeFocus(bool focus);
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
virtual void MouseUp(BPoint where);
|
||||||
|
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||||
|
const BMessage* dragMessage);
|
||||||
|
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
virtual void KeyDown(const char* bytes, int32 numBytes);
|
||||||
|
|
||||||
|
virtual void Draw(BRect updateRect);
|
||||||
|
virtual void FrameResized(float width, float height);
|
||||||
|
|
||||||
|
// GradientControl
|
||||||
|
void SetGradient(const ::Gradient* gradient);
|
||||||
|
::Gradient* Gradient() const
|
||||||
|
{ return fGradient; }
|
||||||
|
|
||||||
|
void SetCurrentStop(const rgb_color& color);
|
||||||
|
bool GetCurrentStop(rgb_color* color) const;
|
||||||
|
|
||||||
|
void SetEnabled(bool enabled);
|
||||||
|
bool IsEnabled() const
|
||||||
|
{ return fEnabled; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _UpdateColors();
|
||||||
|
void _AllocBitmap(int32 width, int32 height);
|
||||||
|
BRect _GradientBitmapRect() const;
|
||||||
|
int32 _StepIndexFor(BPoint where) const;
|
||||||
|
float _OffsetFor(BPoint where) const;
|
||||||
|
void _UpdateCurrentColor() const;
|
||||||
|
|
||||||
|
::Gradient* fGradient;
|
||||||
|
BBitmap* fGradientBitmap;
|
||||||
|
int32 fDraggingStepIndex;
|
||||||
|
int32 fCurrentStepIndex;
|
||||||
|
|
||||||
|
float fDropOffset;
|
||||||
|
int32 fDropIndex;
|
||||||
|
|
||||||
|
bool fEnabled;
|
||||||
|
|
||||||
|
BMessage* fMessage;
|
||||||
|
BHandler* fTarget;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GRADIENT_CONTROL_H
|
||||||
@@ -94,7 +94,7 @@ IconObjectListView::ObjectChanged(const Observable* object)
|
|||||||
_SetObject(dynamic_cast<IconObject*>(selected));
|
_SetObject(dynamic_cast<IconObject*>(selected));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object == fObject && !fIgnoreObjectChange) {
|
if (object == fObject/* && !fIgnoreObjectChange*/) {
|
||||||
printf("IconObjectListView::ObjectChanged(fObject)\n");
|
printf("IconObjectListView::ObjectChanged(fObject)\n");
|
||||||
SetTo(fObject->MakePropertyObject());
|
SetTo(fObject->MakePropertyObject());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,282 @@
|
|||||||
|
|
||||||
#include "StyleView.h"
|
#include "StyleView.h"
|
||||||
|
|
||||||
|
#include <Menu.h>
|
||||||
|
#include <MenuBar.h>
|
||||||
|
#include <MenuField.h>
|
||||||
|
#include <MenuItem.h>
|
||||||
|
#include <Message.h>
|
||||||
|
#include <PopUpMenu.h>
|
||||||
|
|
||||||
|
#include "CommandStack.h"
|
||||||
|
#include "Gradient.h"
|
||||||
|
#include "GradientControl.h"
|
||||||
|
#include "SetGradientCommand.h"
|
||||||
|
#include "Style.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MSG_SET_COLOR = 'stcl',
|
||||||
|
|
||||||
|
MSG_SET_STYLE_TYPE = 'stst',
|
||||||
|
MSG_SET_GRADIENT_TYPE = 'stgt',
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STYLE_TYPE_COLOR = 0,
|
||||||
|
STYLE_TYPE_GRADIENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
// constructor
|
||||||
StyleView::StyleView(BRect frame)
|
StyleView::StyleView(BRect frame)
|
||||||
: BView(frame, "style view", B_FOLLOW_NONE, 0)
|
: BView(frame, "style view", B_FOLLOW_LEFT | B_FOLLOW_TOP, 0),
|
||||||
|
fCommandStack(NULL),
|
||||||
|
fStyle(NULL),
|
||||||
|
fGradient(NULL)
|
||||||
{
|
{
|
||||||
|
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
|
||||||
|
|
||||||
|
frame.OffsetTo(B_ORIGIN);
|
||||||
|
frame.InsetBy(5, 5);
|
||||||
|
frame.bottom = frame.top + 15;
|
||||||
|
|
||||||
|
// style type
|
||||||
|
BMenu* menu = new BPopUpMenu("<unavailable>");
|
||||||
|
BMessage* message = new BMessage(MSG_SET_STYLE_TYPE);
|
||||||
|
message->AddInt32("type", STYLE_TYPE_COLOR);
|
||||||
|
menu->AddItem(new BMenuItem("Color", message));
|
||||||
|
message = new BMessage(MSG_SET_STYLE_TYPE);
|
||||||
|
message->AddInt32("type", STYLE_TYPE_GRADIENT);
|
||||||
|
menu->AddItem(new BMenuItem("Gradient", message));
|
||||||
|
fStyleType = new BMenuField(frame, "style type", "Style Type",
|
||||||
|
menu, true);
|
||||||
|
AddChild(fStyleType);
|
||||||
|
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
|
fStyleType->MenuBar()->GetPreferredSize(&width, &height);
|
||||||
|
fStyleType->MenuBar()->ResizeTo(width, height);
|
||||||
|
fStyleType->ResizeTo(frame.Width(), height + 6);
|
||||||
|
|
||||||
|
|
||||||
|
// gradient type
|
||||||
|
menu = new BPopUpMenu("<unavailable>");
|
||||||
|
message = new BMessage(MSG_SET_GRADIENT_TYPE);
|
||||||
|
message->AddInt32("type", GRADIENT_LINEAR);
|
||||||
|
menu->AddItem(new BMenuItem("Linear", message));
|
||||||
|
message = new BMessage(MSG_SET_GRADIENT_TYPE);
|
||||||
|
message->AddInt32("type", GRADIENT_CIRCULAR);
|
||||||
|
menu->AddItem(new BMenuItem("Radial", message));
|
||||||
|
message = new BMessage(MSG_SET_GRADIENT_TYPE);
|
||||||
|
message->AddInt32("type", GRADIENT_DIAMONT);
|
||||||
|
menu->AddItem(new BMenuItem("Diamont", message));
|
||||||
|
message = new BMessage(MSG_SET_GRADIENT_TYPE);
|
||||||
|
message->AddInt32("type", GRADIENT_CONIC);
|
||||||
|
menu->AddItem(new BMenuItem("Conic", message));
|
||||||
|
|
||||||
|
frame.OffsetBy(0, fStyleType->Frame().Height() + 6);
|
||||||
|
fGradientType = new BMenuField(frame, "gradient type", "Gradient Type",
|
||||||
|
menu, true);
|
||||||
|
AddChild(fGradientType);
|
||||||
|
|
||||||
|
fGradientType->MenuBar()->GetPreferredSize(&width, &height);
|
||||||
|
fGradientType->MenuBar()->ResizeTo(width, height);
|
||||||
|
fGradientType->ResizeTo(frame.Width(), height + 6);
|
||||||
|
|
||||||
|
// create gradient control
|
||||||
|
frame.top = fGradientType->Frame().bottom + 8;
|
||||||
|
frame.right = Bounds().right - 5;
|
||||||
|
fGradientControl = new GradientControl(new BMessage(MSG_SET_COLOR),
|
||||||
|
this);
|
||||||
|
|
||||||
|
width = max_c(fGradientControl->Frame().Width(), frame.Width());
|
||||||
|
height = max_c(fGradientControl->Frame().Height(), 30);
|
||||||
|
|
||||||
|
fGradientControl->ResizeTo(width, height);
|
||||||
|
fGradientControl->FrameResized(width, height);
|
||||||
|
fGradientControl->MoveTo(frame.left, frame.top);
|
||||||
|
|
||||||
|
AddChild(fGradientControl);
|
||||||
|
fGradientControl->SetEnabled(false);
|
||||||
|
|
||||||
|
fGradientControl->Gradient()->AddObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
StyleView::~StyleView()
|
StyleView::~StyleView()
|
||||||
{
|
{
|
||||||
|
SetStyle(NULL);
|
||||||
|
fGradientControl->Gradient()->RemoveObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AttachedToWindow
|
||||||
|
void
|
||||||
|
StyleView::AttachedToWindow()
|
||||||
|
{
|
||||||
|
fStyleType->Menu()->SetTargetForItems(this);
|
||||||
|
fGradientType->Menu()->SetTargetForItems(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageReceived
|
||||||
|
void
|
||||||
|
StyleView::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case MSG_SET_STYLE_TYPE: {
|
||||||
|
int32 type;
|
||||||
|
if (message->FindInt32("type", &type) == B_OK)
|
||||||
|
_SetStyleType(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MSG_SET_GRADIENT_TYPE: {
|
||||||
|
int32 type;
|
||||||
|
if (message->FindInt32("type", &type) == B_OK)
|
||||||
|
_SetGradientType(type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
BView::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// ObjectChanged
|
||||||
|
void
|
||||||
|
StyleView::ObjectChanged(const Observable* object)
|
||||||
|
{
|
||||||
|
if (!fStyle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Gradient* controlGradient = fGradientControl->Gradient();
|
||||||
|
|
||||||
|
// NOTE: it is important to compare the gradients
|
||||||
|
// before assignment, or we will get into an endless loop
|
||||||
|
if (object == controlGradient) {
|
||||||
|
if (fGradient && *fGradient != *controlGradient) {
|
||||||
|
if (fCommandStack) {
|
||||||
|
fCommandStack->Perform(
|
||||||
|
new (nothrow) SetGradientCommand(
|
||||||
|
fStyle, controlGradient));
|
||||||
|
} else {
|
||||||
|
*fGradient = *controlGradient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (object == fGradient) {
|
||||||
|
if (*fGradient != *controlGradient) {
|
||||||
|
fGradientControl->SetGradient(fGradient);
|
||||||
|
_MarkType(fGradientType->Menu(), fGradient->Type());
|
||||||
|
}
|
||||||
|
} else if (object == fStyle) {
|
||||||
|
// maybe the gradient was added or removed
|
||||||
|
_SetGradient(fStyle->Gradient());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// StyleView
|
||||||
|
void
|
||||||
|
StyleView::SetStyle(Style* style)
|
||||||
|
{
|
||||||
|
if (fStyle == style)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fStyle)
|
||||||
|
fStyle->RemoveObserver(this);
|
||||||
|
|
||||||
|
fStyle = style;
|
||||||
|
|
||||||
|
Gradient* gradient = NULL;
|
||||||
|
if (fStyle) {
|
||||||
|
fStyle->AddObserver(this);
|
||||||
|
gradient = fStyle->Gradient();
|
||||||
|
}
|
||||||
|
|
||||||
|
_SetGradient(gradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCommandStack
|
||||||
|
void
|
||||||
|
StyleView::SetCommandStack(CommandStack* stack)
|
||||||
|
{
|
||||||
|
fCommandStack = stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
// _SetGradient
|
||||||
|
void
|
||||||
|
StyleView::_SetGradient(Gradient* gradient)
|
||||||
|
{
|
||||||
|
if (fGradient == gradient)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fGradient)
|
||||||
|
fGradient->RemoveObserver(this);
|
||||||
|
|
||||||
|
fGradient = gradient;
|
||||||
|
|
||||||
|
if (fGradient)
|
||||||
|
fGradient->AddObserver(this);
|
||||||
|
|
||||||
|
if (fGradient) {
|
||||||
|
fGradientControl->SetEnabled(true);
|
||||||
|
fGradientControl->SetGradient(fGradient);
|
||||||
|
fGradientType->SetEnabled(true);
|
||||||
|
_MarkType(fStyleType->Menu(), STYLE_TYPE_GRADIENT);
|
||||||
|
_MarkType(fGradientType->Menu(), fGradient->Type());
|
||||||
|
} else {
|
||||||
|
fGradientControl->SetEnabled(false);
|
||||||
|
fGradientType->SetEnabled(false);
|
||||||
|
_MarkType(fStyleType->Menu(), STYLE_TYPE_COLOR);
|
||||||
|
_MarkType(fGradientType->Menu(), -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _MarkType
|
||||||
|
void
|
||||||
|
StyleView::_MarkType(BMenu* menu, int32 type) const
|
||||||
|
{
|
||||||
|
for (int32 i = 0; BMenuItem* item = menu->ItemAt(i); i++) {
|
||||||
|
BMessage* message = item->Message();
|
||||||
|
int32 t;
|
||||||
|
if (message->FindInt32("type", &t) == B_OK && t == type) {
|
||||||
|
item->SetMarked(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _SetStyleType
|
||||||
|
void
|
||||||
|
StyleView::_SetStyleType(int32 type)
|
||||||
|
{
|
||||||
|
if (!fStyle)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (type == STYLE_TYPE_COLOR) {
|
||||||
|
if (fCommandStack) {
|
||||||
|
fCommandStack->Perform(
|
||||||
|
new (nothrow) SetGradientCommand(fStyle, NULL));
|
||||||
|
} else {
|
||||||
|
fStyle->SetGradient(NULL);
|
||||||
|
}
|
||||||
|
} else if (type == STYLE_TYPE_GRADIENT) {
|
||||||
|
if (fCommandStack) {
|
||||||
|
fCommandStack->Perform(
|
||||||
|
new (nothrow) SetGradientCommand(
|
||||||
|
fStyle, fGradientControl->Gradient()));
|
||||||
|
} else {
|
||||||
|
fStyle->SetGradient(fGradientControl->Gradient());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _SetGradientType
|
||||||
|
void
|
||||||
|
StyleView::_SetGradientType(int32 type)
|
||||||
|
{
|
||||||
|
fGradientControl->Gradient()->SetType((gradient_type)type);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,12 +11,49 @@
|
|||||||
|
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
class StyleView : public {
|
#include "Observer.h"
|
||||||
|
|
||||||
|
class BMenuField;
|
||||||
|
class CommandStack;
|
||||||
|
class Gradient;
|
||||||
|
class GradientControl;
|
||||||
|
class Style;
|
||||||
|
|
||||||
|
// TODO: write lock the document when changing something...
|
||||||
|
|
||||||
|
class StyleView : public BView,
|
||||||
|
public Observer {
|
||||||
public:
|
public:
|
||||||
StyleView(BRect frame);
|
StyleView(BRect frame);
|
||||||
virtual ~StyleView();
|
virtual ~StyleView();
|
||||||
|
|
||||||
|
// BView interface
|
||||||
|
virtual void AttachedToWindow();
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
// Observer interface
|
||||||
|
virtual void ObjectChanged(const Observable* object);
|
||||||
|
|
||||||
|
// StyleView
|
||||||
|
void SetStyle(Style* style);
|
||||||
|
void SetCommandStack(CommandStack* stack);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _SetGradient(Gradient* gradient);
|
||||||
|
void _MarkType(BMenu* menu,
|
||||||
|
int32 type) const;
|
||||||
|
void _SetStyleType(int32 type);
|
||||||
|
void _SetGradientType(int32 type);
|
||||||
|
|
||||||
|
|
||||||
|
CommandStack* fCommandStack;
|
||||||
|
|
||||||
|
Style* fStyle;
|
||||||
|
Gradient* fGradient;
|
||||||
|
|
||||||
|
GradientControl* fGradientControl;
|
||||||
|
BMenuField* fStyleType;
|
||||||
|
BMenuField* fGradientType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // STYLE_VIEW_H
|
#endif // STYLE_VIEW_H
|
||||||
|
|||||||
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "SetGradientCommand.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "Gradient.h"
|
||||||
|
#include "Style.h"
|
||||||
|
|
||||||
|
using std::nothrow;
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
SetGradientCommand::SetGradientCommand(Style* style,
|
||||||
|
const Gradient* gradient)
|
||||||
|
: Command(),
|
||||||
|
fStyle(style),
|
||||||
|
fGradient(gradient ? new (nothrow) Gradient(*gradient) : NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
SetGradientCommand::~SetGradientCommand()
|
||||||
|
{
|
||||||
|
delete fGradient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitCheck
|
||||||
|
status_t
|
||||||
|
SetGradientCommand::InitCheck()
|
||||||
|
{
|
||||||
|
return fStyle ? B_OK : B_NO_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform
|
||||||
|
status_t
|
||||||
|
SetGradientCommand::Perform()
|
||||||
|
{
|
||||||
|
// clone the new gradient for handling over to the style
|
||||||
|
Gradient* clone = NULL;
|
||||||
|
if (fGradient) {
|
||||||
|
clone = new (nothrow) Gradient(*fGradient);
|
||||||
|
if (!clone)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fStyle->Gradient()) {
|
||||||
|
// remember the current gradient of the style
|
||||||
|
if (fGradient)
|
||||||
|
*fGradient = *fStyle->Gradient();
|
||||||
|
else {
|
||||||
|
fGradient = new (nothrow) Gradient(*fStyle->Gradient());
|
||||||
|
if (!fGradient)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// the style didn't have a gradient set
|
||||||
|
delete fGradient;
|
||||||
|
fGradient = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the gradient or set the new one
|
||||||
|
fStyle->SetGradient(clone);
|
||||||
|
delete clone;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Undo
|
||||||
|
status_t
|
||||||
|
SetGradientCommand::Undo()
|
||||||
|
{
|
||||||
|
return Perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName
|
||||||
|
void
|
||||||
|
SetGradientCommand::GetName(BString& name)
|
||||||
|
{
|
||||||
|
name << _GetString(/*EDIT_GRADIENT*/0, "Edit Gradient");
|
||||||
|
}
|
||||||
|
|
||||||
|
// CombineWithNext
|
||||||
|
bool
|
||||||
|
SetGradientCommand::CombineWithNext(const Command* command)
|
||||||
|
{
|
||||||
|
const SetGradientCommand* next
|
||||||
|
= dynamic_cast<const SetGradientCommand*>(command);
|
||||||
|
|
||||||
|
if (next && next->fTimeStamp - fTimeStamp < 1000000) {
|
||||||
|
fTimeStamp = next->fTimeStamp;
|
||||||
|
// NOTE: next was already performed, but
|
||||||
|
// when undoing, we want to use our
|
||||||
|
// remembered gradient
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Stephan Aßmus <[email protected]>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SET_GRADIENT_COMMAND_H
|
||||||
|
#define SET_GRADIENT_COMMAND_H
|
||||||
|
|
||||||
|
#include "Command.h"
|
||||||
|
|
||||||
|
class Gradient;
|
||||||
|
class Style;
|
||||||
|
|
||||||
|
class SetGradientCommand : public Command {
|
||||||
|
public:
|
||||||
|
SetGradientCommand(Style* style,
|
||||||
|
const Gradient* gradient);
|
||||||
|
virtual ~SetGradientCommand();
|
||||||
|
|
||||||
|
virtual status_t InitCheck();
|
||||||
|
|
||||||
|
virtual status_t Perform();
|
||||||
|
virtual status_t Undo();
|
||||||
|
|
||||||
|
virtual void GetName(BString& name);
|
||||||
|
|
||||||
|
virtual bool CombineWithNext(const Command* next);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Style* fStyle;
|
||||||
|
Gradient* fGradient;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHANGE_GRADIENT_COMMAND_H
|
||||||
@@ -8,8 +8,12 @@
|
|||||||
|
|
||||||
#include "Style.h"
|
#include "Style.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include "Gradient.h"
|
#include "Gradient.h"
|
||||||
|
|
||||||
|
using std::nothrow;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Style::Style()
|
Style::Style()
|
||||||
: IconObject("<style>"),
|
: IconObject("<style>"),
|
||||||
@@ -52,23 +56,31 @@ Style::SetColor(const rgb_color& color)
|
|||||||
|
|
||||||
// SetGradient
|
// SetGradient
|
||||||
void
|
void
|
||||||
Style::SetGradient(::Gradient* gradient)
|
Style::SetGradient(const ::Gradient* gradient)
|
||||||
{
|
{
|
||||||
if (fGradient) {
|
if (!fGradient && !gradient)
|
||||||
fGradient->RemoveObserver(this);
|
return;
|
||||||
delete fGradient;
|
|
||||||
}
|
|
||||||
|
|
||||||
fGradient = gradient;
|
if (gradient) {
|
||||||
|
if (!fGradient) {
|
||||||
if (fGradient) {
|
fGradient = new (nothrow) ::Gradient(*gradient);
|
||||||
fGradient->AddObserver(this);
|
if (fGradient) {
|
||||||
// generate gradient
|
fGradient->AddObserver(this);
|
||||||
if (!fColors)
|
// generate gradient
|
||||||
fColors = new agg::rgba8[256];
|
fColors = new agg::rgba8[256];
|
||||||
fGradient->MakeGradient((uint32*)fColors, 256);
|
fGradient->MakeGradient((uint32*)fColors, 256);
|
||||||
|
Notify();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (*fGradient != *gradient) {
|
||||||
|
*fGradient = *gradient;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
fGradient->RemoveObserver(this);
|
||||||
delete[] fColors;
|
delete[] fColors;
|
||||||
fColors = NULL;
|
fColors = NULL;
|
||||||
|
fGradient = NULL;
|
||||||
|
Notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class Style : public IconObject,
|
|||||||
inline rgb_color Color() const
|
inline rgb_color Color() const
|
||||||
{ return fColor; }
|
{ return fColor; }
|
||||||
|
|
||||||
void SetGradient(::Gradient* gradient);
|
void SetGradient(const ::Gradient* gradient);
|
||||||
::Gradient* Gradient() const
|
::Gradient* Gradient() const
|
||||||
{ return fGradient; }
|
{ return fGradient; }
|
||||||
|
|
||||||
|
|||||||
@@ -93,8 +93,10 @@ StrokeTransformer::MakePropertyObject() const
|
|||||||
object->AddProperty(property);
|
object->AddProperty(property);
|
||||||
|
|
||||||
// miter limit
|
// miter limit
|
||||||
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
|
if (line_join() == agg::miter_join) {
|
||||||
miter_limit()));
|
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
|
||||||
|
miter_limit()));
|
||||||
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user