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:
Stefano Ceccherini
2005-06-30 09:11:59 +00:00
parent 0d1adad317
commit f939937950
+126 -116
View File
@@ -28,9 +28,9 @@
// System Includes -------------------------------------------------------------
#include <Button.h>
#include <Font.h>
#include <String.h>
#include <Window.h>
#include <Errors.h>
#include <stdio.h>
// Project Includes ------------------------------------------------------------
@@ -91,145 +91,134 @@ void BButton::Draw(BRect updateRect)
font_height fh;
GetFontHeight(&fh);
BRect bounds(Bounds());
const BRect bounds = Bounds();
BRect rect = bounds;
// If the focus is changing, just redraw the focus indicator
if (IsFocusChanging())
{
float x = (bounds.right - StringWidth(Label())) / 2.0f;
float y = bounds.top + ((bounds.Height() - fh.ascent - fh.descent) / 2.0f) + fh.ascent + fh.descent + 1;
const bool enabled = IsEnabled();
const bool pushed = Value() == B_CONTROL_ON;
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));
// Default indicator
if (IsDefault())
rect = DrawDefault(rect,enabled);
else
rect.InsetBy(1.0f,1.0f);
// 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));
BRect fillArea = rect;
fillArea.InsetBy(3.0f,3.0f);
BString text = Label();
#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());
return;
}
rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR),
lighten1 = tint_color(no_tint, B_LIGHTEN_1_TINT),
lighten2 = tint_color(no_tint, B_LIGHTEN_2_TINT),
lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT),
darkenmax = tint_color(no_tint, B_DARKEN_MAX_TINT);
// Colors
const rgb_color panelBgColor = ui_color(B_PANEL_BACKGROUND_COLOR);
const rgb_color buttonBgColor=tint_color(panelBgColor, B_LIGHTEN_1_TINT);
const rgb_color maxLightColor=tint_color(panelBgColor, B_LIGHTEN_MAX_TINT);
const rgb_color maxShadowColor=tint_color(panelBgColor, B_DARKEN_MAX_TINT);
const rgb_color darkBorderColor = tint_color(panelBgColor,
enabled ? B_DARKEN_4_TINT : B_DARKEN_2_TINT);
const rgb_color firstBevelColor = enabled ? tint_color(panelBgColor, B_DARKEN_2_TINT)
: panelBgColor;
const rgb_color cornerColor = IsDefault() ? firstBevelColor : panelBgColor;
BRect rect(bounds);
bool bEnabled = IsEnabled();
// Fill the button area
SetHighColor(buttonBgColor);
FillRect(fillArea);
if (IsDefault())
rect = DrawDefault(rect, bEnabled);
else
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);
BeginLineArray(8);
BeginLineArray(14);
// Corners
rgb_color cornerColor = no_tint;
if (IsDefault())
cornerColor = lighten1;
AddLine(rect.LeftBottom(), rect.LeftBottom(), cornerColor);
AddLine(rect.LeftTop(), rect.LeftTop(), cornerColor);
AddLine(rect.LeftBottom(), rect.LeftBottom(), cornerColor);
AddLine(rect.RightTop(), rect.RightTop(), 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);
// 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);
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);
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();
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);
// Filling
rect.left += 1.0f;
rect.top += 1.0f;
SetHighColor(lighten1);
FillRect(rect);
if (bEnabled && Value())
{
// Invert
rect.left -= 3;
rect.top -= 3;
rect.right += 2;
rect.bottom += 2;
// Invert if clicked
if (enabled && pushed) {
rect.InsetBy(-2.0f,-2.0f);
InvertRect(rect);
}
// Label
float x = (bounds.right - StringWidth(Label())) / 2.0f;
float y = bounds.top + ((bounds.Height() - fh.ascent - fh.descent) / 2.0f) + fh.ascent + 1;
if (bEnabled && Value())
{
SetHighColor(lightenmax);
SetLowColor(darkenmax);
}
else
{
if (bEnabled)
SetHighColor(darkenmax);
else
SetHighColor(tint_color(no_tint, B_DISABLED_LABEL_TINT));
SetLowColor(lighten2);
// Label color
if (enabled) {
if (pushed) {
SetHighColor(maxLightColor);
SetLowColor(maxShadowColor);
} else {
SetHighColor(maxShadowColor);
SetLowColor(tint_color(panelBgColor, B_LIGHTEN_2_TINT));
}
} else {
SetHighColor(tint_color(panelBgColor, B_DISABLED_LABEL_TINT));
SetLowColor(tint_color(panelBgColor, B_LIGHTEN_2_TINT));
}
// Draw the label
DrawString(Label(), BPoint(x, y));
DrawString(text.String(), BPoint(x, labelY));
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));
// Focus line
if (enabled && IsFocus() && Window()->IsActive() && !pushed)
DrawFocusLine(x,focusLineY,stringWidth,true);
}
}
//------------------------------------------------------------------------------
@@ -503,13 +492,19 @@ BRect BButton::DrawDefault(BRect bounds, bool enabled)
bounds.InsetBy(1.0f, 1.0f);
// Filling
float inset = enabled? 2.0f : 3.0f;
SetHighColor(lighten1);
FillRect(bounds);
if (enabled)
bounds.InsetBy(2.0f, 2.0f);
else
bounds.InsetBy(3.0f, 3.0f);
FillRect(BRect(bounds.left, bounds.top,
bounds.right, bounds.top+inset-1.0f));
FillRect(BRect(bounds.left, bounds.bottom-inset+1.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;
}
@@ -523,7 +518,22 @@ status_t BButton::Execute()
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 $
*