Refactored BButton::Draw(), fixed some small glitches, visible when the focus was changing. Moved drawing of the focus line to its own method.
Patch contributed by Ivan Tonizza. Note that BControl::IsFocusChanging() seems to always return false under haiku. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13362 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+133
-123
@@ -28,9 +28,9 @@
|
|||||||
|
|
||||||
// System Includes -------------------------------------------------------------
|
// System Includes -------------------------------------------------------------
|
||||||
#include <Button.h>
|
#include <Button.h>
|
||||||
|
#include <Font.h>
|
||||||
|
#include <String.h>
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
#include <Errors.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// Project Includes ------------------------------------------------------------
|
// Project Includes ------------------------------------------------------------
|
||||||
|
|
||||||
@@ -90,146 +90,135 @@ void BButton::Draw(BRect updateRect)
|
|||||||
{
|
{
|
||||||
font_height fh;
|
font_height fh;
|
||||||
GetFontHeight(&fh);
|
GetFontHeight(&fh);
|
||||||
|
|
||||||
|
const BRect bounds = Bounds();
|
||||||
|
BRect rect = bounds;
|
||||||
|
|
||||||
|
const bool enabled = IsEnabled();
|
||||||
|
const bool pushed = Value() == B_CONTROL_ON;
|
||||||
|
|
||||||
BRect bounds(Bounds());
|
// Default indicator
|
||||||
|
if (IsDefault())
|
||||||
|
rect = DrawDefault(rect,enabled);
|
||||||
|
else
|
||||||
|
rect.InsetBy(1.0f,1.0f);
|
||||||
|
|
||||||
// If the focus is changing, just redraw the focus indicator
|
BRect fillArea = rect;
|
||||||
if (IsFocusChanging())
|
fillArea.InsetBy(3.0f,3.0f);
|
||||||
{
|
|
||||||
float x = (bounds.right - StringWidth(Label())) / 2.0f;
|
BString text = Label();
|
||||||
float y = bounds.top + ((bounds.Height() - fh.ascent - fh.descent) / 2.0f) + fh.ascent + fh.descent + 1;
|
|
||||||
|
#if 1
|
||||||
|
// Label truncation
|
||||||
|
BFont font;
|
||||||
|
GetFont(&font);
|
||||||
|
font.TruncateString(&text, B_TRUNCATE_END, fillArea.Width());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Label position
|
||||||
|
const float stringWidth = StringWidth(text.String());
|
||||||
|
const float x = (bounds.right - stringWidth) / 2.0f;
|
||||||
|
const float labelY = bounds.top
|
||||||
|
+ ((bounds.Height() - fh.ascent - fh.descent) / 2.0f)
|
||||||
|
+ fh.ascent + 1.0f;
|
||||||
|
const float focusLineY = labelY + fh.descent;
|
||||||
|
|
||||||
|
/* speed trick:
|
||||||
|
if the focus changes but the button is not pressed then we can
|
||||||
|
redraw only the focus line,
|
||||||
|
if the focus changes and the button is pressed invert the internal rect
|
||||||
|
this block takes care of all the focus changes
|
||||||
|
*/
|
||||||
|
if (IsFocusChanging()) {
|
||||||
|
if (pushed) {
|
||||||
|
rect.InsetBy(2.0,2.0);
|
||||||
|
InvertRect(rect);
|
||||||
|
} else
|
||||||
|
DrawFocusLine(x, focusLineY, stringWidth, IsFocus() && Window()->IsActive());
|
||||||
|
|
||||||
bool bDrawFocusLine = IsFocus() && Window()->IsActive();
|
|
||||||
if (bDrawFocusLine)
|
|
||||||
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
|
|
||||||
else
|
|
||||||
SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
|
|
||||||
B_LIGHTEN_1_TINT));
|
|
||||||
|
|
||||||
// Blue Line
|
|
||||||
StrokeLine(BPoint(x, y), BPoint(x + StringWidth(Label()), y));
|
|
||||||
if (bDrawFocusLine)
|
|
||||||
SetHighColor(255, 255, 255);
|
|
||||||
// White Line
|
|
||||||
StrokeLine(BPoint(x, y + 1), BPoint(x + StringWidth(Label()), y + 1));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
|
// Colors
|
||||||
lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT),
|
const rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||||
lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT),
|
const rgb_color buttonBgColor=tint_color(panelBgColor, B_LIGHTEN_1_TINT);
|
||||||
lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT),
|
const rgb_color maxLightColor=tint_color(panelBgColor, B_LIGHTEN_MAX_TINT);
|
||||||
darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
|
const rgb_color maxShadowColor=tint_color(panelBgColor, B_DARKEN_MAX_TINT);
|
||||||
|
const rgb_color darkBorderColor = tint_color(panelBgColor,
|
||||||
BRect rect(bounds);
|
enabled ? B_DARKEN_4_TINT : B_DARKEN_2_TINT);
|
||||||
bool bEnabled = IsEnabled();
|
const rgb_color firstBevelColor = enabled ? tint_color(panelBgColor, B_DARKEN_2_TINT)
|
||||||
|
: panelBgColor;
|
||||||
|
const rgb_color cornerColor = IsDefault() ? firstBevelColor : panelBgColor;
|
||||||
|
|
||||||
if (IsDefault())
|
// Fill the button area
|
||||||
rect = DrawDefault(rect, bEnabled);
|
SetHighColor(buttonBgColor);
|
||||||
else
|
FillRect(fillArea);
|
||||||
rect.InsetBy(1,1);
|
|
||||||
|
|
||||||
// This can be set outside draw
|
|
||||||
if (bEnabled)
|
|
||||||
SetHighColor(tint_color(no_tint, B_DARKEN_4_TINT));
|
|
||||||
else
|
|
||||||
SetHighColor(tint_color(no_tint, B_DARKEN_2_TINT));
|
|
||||||
|
|
||||||
// Dark border
|
// external border
|
||||||
|
SetHighColor(darkBorderColor);
|
||||||
StrokeRect(rect);
|
StrokeRect(rect);
|
||||||
|
|
||||||
|
BeginLineArray(14);
|
||||||
|
|
||||||
BeginLineArray(8);
|
|
||||||
|
|
||||||
// Corners
|
// Corners
|
||||||
rgb_color cornerColor = no_tint;
|
|
||||||
if (IsDefault())
|
|
||||||
cornerColor = lighten1;
|
|
||||||
AddLine(rect.LeftBottom(), rect.LeftBottom(), cornerColor);
|
|
||||||
AddLine(rect.LeftTop(), rect.LeftTop(), cornerColor);
|
AddLine(rect.LeftTop(), rect.LeftTop(), cornerColor);
|
||||||
|
AddLine(rect.LeftBottom(), rect.LeftBottom(), cornerColor);
|
||||||
AddLine(rect.RightTop(), rect.RightTop(), cornerColor);
|
AddLine(rect.RightTop(), rect.RightTop(), cornerColor);
|
||||||
AddLine(rect.RightBottom(), rect.RightBottom(), cornerColor);
|
AddLine(rect.RightBottom(), rect.RightBottom(), cornerColor);
|
||||||
|
|
||||||
rect.InsetBy(1, 1);
|
rect.InsetBy(1.0f,1.0f);
|
||||||
|
|
||||||
// First bevel
|
|
||||||
rgb_color firstBevelColor;
|
|
||||||
if (bEnabled)
|
|
||||||
firstBevelColor = tint_color(no_tint, B_DARKEN_2_TINT);
|
|
||||||
else
|
|
||||||
firstBevelColor = no_tint;
|
|
||||||
AddLine(BPoint(rect.left + 1.0f, rect.bottom),
|
|
||||||
BPoint(rect.right, rect.bottom), firstBevelColor);
|
|
||||||
AddLine(BPoint(rect.right, rect.bottom - 1.0f),
|
|
||||||
BPoint(rect.right, rect.top + 1.0f), firstBevelColor);
|
|
||||||
|
|
||||||
AddLine(BPoint(rect.left, rect.top),
|
|
||||||
BPoint(rect.left, rect.bottom), lighten1);
|
|
||||||
AddLine(BPoint(rect.left + 1.0f, rect.top),
|
|
||||||
BPoint(rect.right, rect.top), lighten1);
|
|
||||||
|
|
||||||
EndLineArray();
|
|
||||||
|
|
||||||
rect.InsetBy(1, 1);
|
|
||||||
|
|
||||||
// Second bevel
|
|
||||||
SetHighColor(lightenmax);
|
|
||||||
FillRect(rect);
|
|
||||||
|
|
||||||
SetHighColor(no_tint);
|
|
||||||
StrokeLine(BPoint(rect.right, rect.top + 1.0f),
|
|
||||||
BPoint(rect.right, rect.bottom));
|
|
||||||
StrokeLine(BPoint(rect.left + 1.0f, rect.bottom));
|
|
||||||
|
|
||||||
rect.InsetBy(1, 1);
|
// Shadow
|
||||||
|
AddLine(rect.LeftBottom(), rect.RightBottom(), firstBevelColor);
|
||||||
|
AddLine(rect.RightBottom(), rect.RightTop(), firstBevelColor);
|
||||||
|
// Light
|
||||||
|
AddLine(rect.LeftTop(), rect.LeftBottom(),buttonBgColor);
|
||||||
|
AddLine(rect.LeftTop(), rect.RightTop(), buttonBgColor);
|
||||||
|
|
||||||
|
rect.InsetBy(1.0f, 1.0f);
|
||||||
|
|
||||||
|
// Shadow
|
||||||
|
AddLine(rect.LeftBottom(), rect.RightBottom(), panelBgColor);
|
||||||
|
AddLine(rect.RightBottom(), rect.RightTop(), panelBgColor);
|
||||||
|
// Light
|
||||||
|
AddLine(rect.LeftTop(), rect.LeftBottom(),maxLightColor);
|
||||||
|
AddLine(rect.LeftTop(), rect.RightTop(), maxLightColor);
|
||||||
|
|
||||||
|
rect.InsetBy(1.0f,1.0f);
|
||||||
|
|
||||||
|
// Light
|
||||||
|
AddLine(rect.LeftTop(), rect.LeftBottom(),maxLightColor);
|
||||||
|
AddLine(rect.LeftTop(), rect.RightTop(), maxLightColor);
|
||||||
|
|
||||||
|
EndLineArray();
|
||||||
|
|
||||||
// Filling
|
// Invert if clicked
|
||||||
rect.left += 1.0f;
|
if (enabled && pushed) {
|
||||||
rect.top += 1.0f;
|
rect.InsetBy(-2.0f,-2.0f);
|
||||||
SetHighColor(lighten1);
|
|
||||||
FillRect(rect);
|
|
||||||
|
|
||||||
if (bEnabled && Value())
|
|
||||||
{
|
|
||||||
// Invert
|
|
||||||
rect.left -= 3;
|
|
||||||
rect.top -= 3;
|
|
||||||
rect.right += 2;
|
|
||||||
rect.bottom += 2;
|
|
||||||
InvertRect(rect);
|
InvertRect(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label
|
// Label color
|
||||||
float x = (bounds.right - StringWidth(Label())) / 2.0f;
|
if (enabled) {
|
||||||
float y = bounds.top + ((bounds.Height() - fh.ascent - fh.descent) / 2.0f) + fh.ascent + 1;
|
if (pushed) {
|
||||||
|
SetHighColor(maxLightColor);
|
||||||
if (bEnabled && Value())
|
SetLowColor(maxShadowColor);
|
||||||
{
|
} else {
|
||||||
SetHighColor(lightenmax);
|
SetHighColor(maxShadowColor);
|
||||||
SetLowColor(darkenmax);
|
SetLowColor(tint_color(panelBgColor, B_LIGHTEN_2_TINT));
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
{
|
SetHighColor(tint_color(panelBgColor, B_DISABLED_LABEL_TINT));
|
||||||
if (bEnabled)
|
SetLowColor(tint_color(panelBgColor, B_LIGHTEN_2_TINT));
|
||||||
SetHighColor(darkenmax);
|
|
||||||
else
|
|
||||||
SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT));
|
|
||||||
SetLowColor(lighten2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw the label
|
// Draw the label
|
||||||
DrawString(Label(), BPoint(x, y));
|
DrawString(text.String(), BPoint(x, labelY));
|
||||||
|
|
||||||
|
// Focus line
|
||||||
|
if (enabled && IsFocus() && Window()->IsActive() && !pushed)
|
||||||
|
DrawFocusLine(x,focusLineY,stringWidth,true);
|
||||||
|
|
||||||
if (bEnabled && IsFocus() && Window()->IsActive())
|
|
||||||
{
|
|
||||||
// Draw focus line
|
|
||||||
y += fh.descent;
|
|
||||||
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
|
|
||||||
StrokeLine(BPoint(x, y), BPoint(x + StringWidth(Label()), y));
|
|
||||||
SetHighColor(255, 255, 255);
|
|
||||||
StrokeLine(BPoint(x, y + 1), BPoint(x + StringWidth(Label()), y + 1));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -503,13 +492,19 @@ BRect BButton::DrawDefault(BRect bounds, bool enabled)
|
|||||||
bounds.InsetBy(1.0f, 1.0f);
|
bounds.InsetBy(1.0f, 1.0f);
|
||||||
|
|
||||||
// Filling
|
// Filling
|
||||||
|
float inset = enabled? 2.0f : 3.0f;
|
||||||
SetHighColor(lighten1);
|
SetHighColor(lighten1);
|
||||||
FillRect(bounds);
|
|
||||||
|
|
||||||
if (enabled)
|
FillRect(BRect(bounds.left, bounds.top,
|
||||||
bounds.InsetBy(2.0f, 2.0f);
|
bounds.right, bounds.top+inset-1.0f));
|
||||||
else
|
FillRect(BRect(bounds.left, bounds.bottom-inset+1.0f,
|
||||||
bounds.InsetBy(3.0f, 3.0f);
|
bounds.right, bounds.bottom));
|
||||||
|
FillRect(BRect(bounds.left, bounds.top+inset-1.0f,
|
||||||
|
bounds.left+inset-1.0f, bounds.bottom-inset+1.0f));
|
||||||
|
FillRect(BRect(bounds.right-inset+1.0f, bounds.top+inset-1.0f,
|
||||||
|
bounds.right, bounds.bottom-inset+1.0f));
|
||||||
|
|
||||||
|
bounds.InsetBy(inset,inset);
|
||||||
|
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
@@ -523,7 +518,22 @@ status_t BButton::Execute()
|
|||||||
return Invoke();
|
return Invoke();
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
void BButton::DrawFocusLine(float x, float y, float width, bool visible)
|
||||||
|
{
|
||||||
|
if (visible)
|
||||||
|
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR));
|
||||||
|
else
|
||||||
|
SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR),
|
||||||
|
B_LIGHTEN_1_TINT));
|
||||||
|
// Blue Line
|
||||||
|
StrokeLine(BPoint(x, y), BPoint(x + width, y));
|
||||||
|
|
||||||
|
if (visible)
|
||||||
|
SetHighColor(255, 255, 255);
|
||||||
|
// White Line
|
||||||
|
StrokeLine(BPoint(x, y + 1.0f), BPoint(x + width, y + 1.0f));
|
||||||
|
}
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
* $Log $
|
* $Log $
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user