* 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_ui.cpp
|
||||
# gui
|
||||
GradientControl.cpp
|
||||
IconObjectListView.cpp
|
||||
PathListView.cpp
|
||||
ShapeListView.cpp
|
||||
StyleListView.cpp
|
||||
StyleView.cpp
|
||||
SwatchGroup.cpp
|
||||
TransformerListView.cpp
|
||||
# shape
|
||||
@@ -133,6 +135,7 @@ Application Icon-O-Matic :
|
||||
# style
|
||||
CurrentColor.cpp
|
||||
Gradient.cpp
|
||||
SetGradientCommand.cpp
|
||||
Style.cpp
|
||||
StyleManager.cpp
|
||||
# transformer
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "ScrollView.h"
|
||||
#include "ShapeListView.h"
|
||||
#include "StyleListView.h"
|
||||
#include "StyleView.h"
|
||||
#include "SwatchGroup.h"
|
||||
#include "TransformerFactory.h"
|
||||
#include "TransformerListView.h"
|
||||
@@ -127,6 +128,7 @@ case MSG_STYLE_SELECTED: {
|
||||
if (message->FindPointer("style", (void**)&style) < B_OK)
|
||||
style = NULL;
|
||||
fSwatchGroup->SetCurrentStyle(style);
|
||||
fStyleView->SetStyle(style);
|
||||
break;
|
||||
}
|
||||
// TODO: use an AddShapeCommand
|
||||
@@ -237,6 +239,8 @@ MainWindow::_Init()
|
||||
// fStyleListView->SetCommandStack(fDocument->CommandStack());
|
||||
fStyleListView->SetSelection(fDocument->Selection());
|
||||
|
||||
fStyleView->SetCommandStack(fDocument->CommandStack());
|
||||
|
||||
fShapeListView->SetShapeContainer(fDocument->Icon()->Shapes());
|
||||
fShapeListView->SetCommandStack(fDocument->CommandStack());
|
||||
fShapeListView->SetSelection(fDocument->Selection());
|
||||
@@ -271,11 +275,11 @@ MainWindow::_Init()
|
||||
StyleManager::Default()->AddStyle(style1);
|
||||
|
||||
Style* style2 = new Style();
|
||||
Gradient* gradient = new Gradient(true);
|
||||
gradient->AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0);
|
||||
gradient->AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5);
|
||||
gradient->AddColor((rgb_color){ 208, 43, 92, 255 }, 1.0);
|
||||
style2->SetGradient(gradient);
|
||||
Gradient gradient(true);
|
||||
gradient.AddColor((rgb_color){ 255, 211, 6, 255 }, 0.0);
|
||||
gradient.AddColor((rgb_color){ 255, 238, 160, 255 }, 0.5);
|
||||
gradient.AddColor((rgb_color){ 208, 43, 92, 255 }, 1.0);
|
||||
style2->SetGradient(&gradient);
|
||||
|
||||
StyleManager::Default()->AddStyle(style2);
|
||||
|
||||
@@ -407,6 +411,14 @@ MainWindow::_CreateGUI(BRect bounds)
|
||||
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
|
||||
bounds.left = 0;
|
||||
bounds.right = fCanvasView->Frame().left - 1;
|
||||
|
||||
@@ -23,6 +23,7 @@ class IconView;
|
||||
class PathListView;
|
||||
class ShapeListView;
|
||||
class StyleListView;
|
||||
class StyleView;
|
||||
class SwatchGroup;
|
||||
class TransformerListView;
|
||||
|
||||
@@ -62,6 +63,7 @@ class MainWindow : public BWindow,
|
||||
|
||||
CanvasView* fCanvasView;
|
||||
SwatchGroup* fSwatchGroup;
|
||||
StyleView* fStyleView;
|
||||
|
||||
IconView* fIconPreview16;
|
||||
IconView* fIconPreview32;
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
|
||||
* implement commands for the newly added editing features
|
||||
|
||||
* built-in transformation for Gradient and Shape?
|
||||
|
||||
* Transformation manipulator
|
||||
|
||||
|
||||
--------- user interface
|
||||
|
||||
@@ -45,7 +49,7 @@
|
||||
|
||||
* 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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
if (object == fObject && !fIgnoreObjectChange) {
|
||||
if (object == fObject/* && !fIgnoreObjectChange*/) {
|
||||
printf("IconObjectListView::ObjectChanged(fObject)\n");
|
||||
SetTo(fObject->MakePropertyObject());
|
||||
}
|
||||
|
||||
@@ -8,13 +8,282 @@
|
||||
|
||||
#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)
|
||||
: 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()
|
||||
{
|
||||
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>
|
||||
|
||||
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:
|
||||
StyleView(BRect frame);
|
||||
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:
|
||||
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
|
||||
|
||||
@@ -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 <new>
|
||||
|
||||
#include "Gradient.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// constructor
|
||||
Style::Style()
|
||||
: IconObject("<style>"),
|
||||
@@ -52,23 +56,31 @@ Style::SetColor(const rgb_color& color)
|
||||
|
||||
// SetGradient
|
||||
void
|
||||
Style::SetGradient(::Gradient* gradient)
|
||||
Style::SetGradient(const ::Gradient* gradient)
|
||||
{
|
||||
if (fGradient) {
|
||||
fGradient->RemoveObserver(this);
|
||||
delete fGradient;
|
||||
}
|
||||
if (!fGradient && !gradient)
|
||||
return;
|
||||
|
||||
fGradient = gradient;
|
||||
|
||||
if (fGradient) {
|
||||
fGradient->AddObserver(this);
|
||||
// generate gradient
|
||||
if (!fColors)
|
||||
fColors = new agg::rgba8[256];
|
||||
fGradient->MakeGradient((uint32*)fColors, 256);
|
||||
if (gradient) {
|
||||
if (!fGradient) {
|
||||
fGradient = new (nothrow) ::Gradient(*gradient);
|
||||
if (fGradient) {
|
||||
fGradient->AddObserver(this);
|
||||
// generate gradient
|
||||
fColors = new agg::rgba8[256];
|
||||
fGradient->MakeGradient((uint32*)fColors, 256);
|
||||
Notify();
|
||||
}
|
||||
} else {
|
||||
if (*fGradient != *gradient) {
|
||||
*fGradient = *gradient;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fGradient->RemoveObserver(this);
|
||||
delete[] fColors;
|
||||
fColors = NULL;
|
||||
fGradient = NULL;
|
||||
Notify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class Style : public IconObject,
|
||||
inline rgb_color Color() const
|
||||
{ return fColor; }
|
||||
|
||||
void SetGradient(::Gradient* gradient);
|
||||
void SetGradient(const ::Gradient* gradient);
|
||||
::Gradient* Gradient() const
|
||||
{ return fGradient; }
|
||||
|
||||
|
||||
@@ -93,8 +93,10 @@ StrokeTransformer::MakePropertyObject() const
|
||||
object->AddProperty(property);
|
||||
|
||||
// miter limit
|
||||
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
|
||||
miter_limit()));
|
||||
if (line_join() == agg::miter_join) {
|
||||
object->AddProperty(new FloatProperty(PROPERTY_MITER_LIMIT,
|
||||
miter_limit()));
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user