ZipOMatic: modernize barberpole widget
* Use the code/graphic of the new barberpole (Haikudepot) * See #13808 * I hope soon we will have a system standard widget
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "ZipOMaticActivity.h"
|
||||
|
||||
#include <ControlLook.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
@@ -16,17 +18,15 @@ Activity::Activity(const char* name)
|
||||
:
|
||||
BView(name, B_WILL_DRAW | B_FRAME_EVENTS),
|
||||
fIsRunning(false),
|
||||
fBitmap(NULL)
|
||||
fBitmap(NULL),
|
||||
fSpinSpeed(0.15),
|
||||
fColors(NULL),
|
||||
fNumColors(0),
|
||||
fScrollOffset(0.0),
|
||||
fStripeWidth(0.0),
|
||||
fNumStripes(0)
|
||||
{
|
||||
fPattern.data[0] = 0x0f;
|
||||
fPattern.data[1] = 0x1e;
|
||||
fPattern.data[2] = 0x3c;
|
||||
fPattern.data[3] = 0x78;
|
||||
fPattern.data[4] = 0xf0;
|
||||
fPattern.data[5] = 0xe1;
|
||||
fPattern.data[6] = 0xc3;
|
||||
fPattern.data[7] = 0x87;
|
||||
|
||||
_InactiveColors();
|
||||
SetExplicitMinSize(BSize(17, 17));
|
||||
SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, 17));
|
||||
};
|
||||
@@ -35,14 +35,15 @@ Activity::Activity(const char* name)
|
||||
Activity::~Activity()
|
||||
{
|
||||
delete fBitmap;
|
||||
delete[] fColors;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Activity::AllAttached()
|
||||
{
|
||||
SetViewColor(B_TRANSPARENT_COLOR);
|
||||
_CreateBitmap();
|
||||
FrameResized(Bounds().Width(), Bounds().Height());
|
||||
}
|
||||
|
||||
|
||||
@@ -50,6 +51,7 @@ void
|
||||
Activity::Start()
|
||||
{
|
||||
fIsRunning = true;
|
||||
_ActiveColors();
|
||||
Window()->SetPulseRate(100000);
|
||||
SetFlags(Flags() | B_PULSE_NEEDED);
|
||||
Invalidate();
|
||||
@@ -69,6 +71,7 @@ void
|
||||
Activity::Stop()
|
||||
{
|
||||
fIsRunning = false;
|
||||
_InactiveColors();
|
||||
Window()->SetPulseRate(500000);
|
||||
SetFlags(Flags() & (~B_PULSE_NEEDED));
|
||||
Invalidate();
|
||||
@@ -85,17 +88,28 @@ Activity::IsRunning()
|
||||
void
|
||||
Activity::Pulse()
|
||||
{
|
||||
uchar tmp = fPattern.data[7];
|
||||
|
||||
for (int j = 7; j > 0; --j)
|
||||
fPattern.data[j] = fPattern.data[j - 1];
|
||||
|
||||
fPattern.data[0] = tmp;
|
||||
|
||||
fScrollOffset += fStripeWidth / (1.0f / fSpinSpeed);
|
||||
if (fScrollOffset >= fStripeWidth * fNumColors) {
|
||||
// Cycle completed, jump back to where we started
|
||||
fScrollOffset = 0;
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Activity::SetColors(const rgb_color* colors, uint32 numColors)
|
||||
{
|
||||
delete[] fColors;
|
||||
rgb_color* colorsCopy = new rgb_color[numColors];
|
||||
for (uint32 i = 0; i < numColors; i++)
|
||||
colorsCopy[i] = colors[i];
|
||||
|
||||
fColors = colorsCopy;
|
||||
fNumColors = numColors;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Activity::Draw(BRect rect)
|
||||
{
|
||||
@@ -118,97 +132,43 @@ Activity::_DrawOnBitmap(bool running)
|
||||
{
|
||||
if (fBitmap->Lock())
|
||||
{
|
||||
BRect rect = fBitmap->Bounds();
|
||||
BRect bounds = fBitmap->Bounds();
|
||||
|
||||
fBitmapView->SetDrawingMode(B_OP_COPY);
|
||||
|
||||
rgb_color color;
|
||||
color.red = 0;
|
||||
color.green = 0;
|
||||
color.blue = 0;
|
||||
color.alpha = 255;
|
||||
|
||||
if (running)
|
||||
color.blue = 200;
|
||||
|
||||
fBitmapView->SetHighColor(color);
|
||||
// Draw color stripes
|
||||
float position = -fStripeWidth * (fNumColors + 0.5) + fScrollOffset;
|
||||
// Starting position: beginning of the second color cycle
|
||||
// The + 0.5 is so we start out without a partially visible stripe
|
||||
// on the left side (makes it simpler to loop)
|
||||
BRect innerFrame = bounds;
|
||||
innerFrame.InsetBy(-2, -2);
|
||||
|
||||
// draw the pole
|
||||
rect.InsetBy(2, 2);
|
||||
fBitmapView->FillRect(rect, fPattern);
|
||||
|
||||
// draw frame
|
||||
be_control_look->DrawStatusBar(fBitmapView, innerFrame, innerFrame,
|
||||
ui_color(B_PANEL_BACKGROUND_COLOR),
|
||||
running ? ui_color(B_STATUS_BAR_COLOR)
|
||||
: ui_color(B_PANEL_BACKGROUND_COLOR),
|
||||
bounds.Width());
|
||||
fBitmapView->SetDrawingMode(B_OP_ALPHA);
|
||||
uint32 colorIndex = 0;
|
||||
for (uint32 i = 0; i < fNumStripes; i++) {
|
||||
fBitmapView->SetHighColor(fColors[colorIndex]);
|
||||
colorIndex++;
|
||||
if (colorIndex >= fNumColors)
|
||||
colorIndex = 0;
|
||||
|
||||
// left
|
||||
color.red = 150;
|
||||
color.green = 150;
|
||||
color.blue = 150;
|
||||
fBitmapView->SetHighColor(color);
|
||||
fBitmapView->SetDrawingMode(B_OP_OVER);
|
||||
BPoint point_a = fBitmap->Bounds().LeftTop();
|
||||
BPoint point_b = fBitmap->Bounds().LeftBottom();
|
||||
point_b.y -= 1;
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
point_a.x += 1;
|
||||
point_b.x += 1;
|
||||
point_b.y -= 1;
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
BRect stripeFrame = fStripe.Frame();
|
||||
fStripe.MapTo(stripeFrame,
|
||||
stripeFrame.OffsetToCopy(position, 0.0));
|
||||
fBitmapView->FillPolygon(&fStripe);
|
||||
|
||||
// top
|
||||
point_a = fBitmap->Bounds().LeftTop();
|
||||
point_b = fBitmap->Bounds().RightTop();
|
||||
point_b.x -= 1;
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
point_a.y += 1;
|
||||
point_b.y += 1;
|
||||
point_b.x -= 1;
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
position += fStripeWidth;
|
||||
}
|
||||
|
||||
// right
|
||||
color.red = 255;
|
||||
color.green = 255;
|
||||
color.blue = 255;
|
||||
fBitmapView->SetHighColor(color);
|
||||
point_a = fBitmap->Bounds().RightTop();
|
||||
point_b = fBitmap->Bounds().RightBottom();
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
point_a.y += 1;
|
||||
point_a.x -= 1;
|
||||
point_b.x -= 1;
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
|
||||
// bottom
|
||||
point_a = fBitmap->Bounds().LeftBottom();
|
||||
point_b = fBitmap->Bounds().RightBottom();
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
point_a.x += 1;
|
||||
point_a.y -= 1;
|
||||
point_b.y -= 1;
|
||||
fBitmapView->StrokeLine(point_a, point_b);
|
||||
|
||||
// some blending
|
||||
color.red = 150;
|
||||
color.green = 150;
|
||||
color.blue = 150;
|
||||
fBitmapView->SetHighColor(color);
|
||||
fBitmapView->SetDrawingMode(B_OP_SUBTRACT);
|
||||
fBitmapView->StrokeRect(rect);
|
||||
|
||||
rect.InsetBy(1, 1);
|
||||
_LightenBitmapHighColor(& color);
|
||||
fBitmapView->StrokeRect(rect);
|
||||
|
||||
rect.InsetBy(1, 1);
|
||||
_LightenBitmapHighColor(& color);
|
||||
fBitmapView->StrokeRect(rect);
|
||||
|
||||
rect.InsetBy(1, 1);
|
||||
_LightenBitmapHighColor(& color);
|
||||
fBitmapView->StrokeRect(rect);
|
||||
|
||||
rect.InsetBy(1, 1);
|
||||
_LightenBitmapHighColor(& color);
|
||||
fBitmapView->StrokeRect(rect);
|
||||
fBitmapView->SetDrawingMode(B_OP_COPY);
|
||||
// Draw box around it
|
||||
be_control_look->DrawTextControlBorder(fBitmapView, bounds, bounds,
|
||||
ui_color(B_PANEL_BACKGROUND_COLOR), B_PLAIN_BORDER);
|
||||
|
||||
fBitmapView->Sync();
|
||||
fBitmap->Unlock();
|
||||
@@ -216,22 +176,11 @@ Activity::_DrawOnBitmap(bool running)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Activity::_LightenBitmapHighColor(rgb_color* color)
|
||||
{
|
||||
color->red -= 30;
|
||||
color->green -= 30;
|
||||
color->blue -= 30;
|
||||
|
||||
fBitmapView->SetHighColor(*color);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Activity::_CreateBitmap(void)
|
||||
{
|
||||
BRect rect = Bounds();
|
||||
fBitmap = new BBitmap(rect, B_CMAP8, true);
|
||||
fBitmap = new BBitmap(rect, B_RGBA32, true);
|
||||
fBitmapView = new BView(Bounds(), "buffer", B_FOLLOW_NONE, 0);
|
||||
fBitmap->AddChild(fBitmapView);
|
||||
}
|
||||
@@ -242,6 +191,62 @@ Activity::FrameResized(float width, float height)
|
||||
{
|
||||
delete fBitmap;
|
||||
_CreateBitmap();
|
||||
// Choose stripe width so that at least 2 full stripes fit into the view,
|
||||
// but with a minimum of 5px. Larger views get wider stripes, but they
|
||||
// grow slower than the view and are capped to a maximum of 200px.
|
||||
fStripeWidth = (width / (fIsRunning ? 4 : 6)) + 5;
|
||||
if (fStripeWidth > 200)
|
||||
fStripeWidth = 200;
|
||||
|
||||
BPoint stripePoints[4];
|
||||
stripePoints[0].Set(fStripeWidth * 0.5, 0.0); // top left
|
||||
stripePoints[1].Set(fStripeWidth * 1.5, 0.0); // top right
|
||||
stripePoints[2].Set(fStripeWidth, height); // bottom right
|
||||
stripePoints[3].Set(0.0, height); // bottom left
|
||||
|
||||
fStripe = BPolygon(stripePoints, 4);
|
||||
|
||||
fNumStripes = (int32)ceilf((width) / fStripeWidth) + 1 + fNumColors;
|
||||
// Number of color stripes drawn in total for the barber pole, the
|
||||
// user-visible part is a "window" onto the complete pole. We need
|
||||
// as many stripes as are visible, an extra one on the right side
|
||||
// (will be partially visible, that's the + 1); and then a whole color
|
||||
// cycle of strips extra which we scroll into until we loop.
|
||||
//
|
||||
// Example with 3 colors and a visible area of 2*fStripeWidth (which means
|
||||
// that 2 will be fully visible, and a third one partially):
|
||||
// ........
|
||||
// X___________v______v___
|
||||
// / 1 / 2 / 3 / 1 / 2 / 3 /
|
||||
// `````````````````````````
|
||||
// Pole is scrolled to the right into the visible region, which is marked
|
||||
// between the two 'v'. Once the left edge of the visible area reaches
|
||||
// point X, we can jump back to the initial region position.
|
||||
Invalidate();
|
||||
}
|
||||
|
||||
void
|
||||
Activity::_ActiveColors()
|
||||
{
|
||||
// Default colors, chosen from system color scheme
|
||||
rgb_color defaultColors[2];
|
||||
rgb_color otherColor = tint_color(ui_color(B_STATUS_BAR_COLOR), 1.3);
|
||||
otherColor.alpha = 50;
|
||||
defaultColors[0] = otherColor;
|
||||
defaultColors[1] = B_TRANSPARENT_COLOR;
|
||||
SetColors(defaultColors, 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Activity::_InactiveColors()
|
||||
{
|
||||
// Default colors, chosen from system color scheme
|
||||
rgb_color defaultColors[2];
|
||||
rgb_color otherColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.7);
|
||||
otherColor.alpha = 50;
|
||||
defaultColors[0] = otherColor;
|
||||
defaultColors[1] = B_TRANSPARENT_COLOR;
|
||||
SetColors(defaultColors, 2);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <Box.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Polygon.h>
|
||||
#include <View.h>
|
||||
#include <Window.h>
|
||||
|
||||
@@ -23,16 +24,28 @@ public:
|
||||
virtual void Pulse();
|
||||
virtual void Draw(BRect draw);
|
||||
virtual void FrameResized(float width, float height);
|
||||
void SetColors(const rgb_color* colors,
|
||||
uint32 numColors);
|
||||
|
||||
private:
|
||||
void _CreateBitmap();
|
||||
void _LightenBitmapHighColor(rgb_color* color);
|
||||
void _DrawOnBitmap(bool running);
|
||||
void _ActiveColors();
|
||||
void _InactiveColors();
|
||||
|
||||
bool fIsRunning;
|
||||
pattern fPattern;
|
||||
BBitmap* fBitmap;
|
||||
BView* fBitmapView;
|
||||
|
||||
float fSpinSpeed;
|
||||
const rgb_color* fColors;
|
||||
uint32 fNumColors;
|
||||
|
||||
float fScrollOffset;
|
||||
BPolygon fStripe;
|
||||
float fStripeWidth;
|
||||
uint32 fNumStripes;
|
||||
};
|
||||
|
||||
#endif // _ACTIVITY_H_
|
||||
|
||||
Reference in New Issue
Block a user