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
+124 -114
View File
@@ -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 ------------------------------------------------------------
@@ -91,145 +91,134 @@ void BButton::Draw(BRect updateRect)
font_height fh; font_height fh;
GetFontHeight(&fh); GetFontHeight(&fh);
BRect bounds(Bounds()); const BRect bounds = Bounds();
BRect rect = bounds;
// If the focus is changing, just redraw the focus indicator const bool enabled = IsEnabled();
if (IsFocusChanging()) const bool pushed = Value() == B_CONTROL_ON;
{
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;
bool bDrawFocusLine = IsFocus() && Window()->IsActive(); // Default indicator
if (bDrawFocusLine) if (IsDefault())
SetHighColor(ui_color(B_KEYBOARD_NAVIGATION_COLOR)); rect = DrawDefault(rect,enabled);
else else
SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), rect.InsetBy(1.0f,1.0f);
B_LIGHTEN_1_TINT));
// Blue Line BRect fillArea = rect;
StrokeLine(BPoint(x, y), BPoint(x + StringWidth(Label()), y)); fillArea.InsetBy(3.0f,3.0f);
if (bDrawFocusLine)
SetHighColor(255, 255, 255); BString text = Label();
// White Line
StrokeLine(BPoint(x, y + 1), BPoint(x + StringWidth(Label()), y + 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());
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,
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); // Fill the button area
bool bEnabled = IsEnabled(); SetHighColor(buttonBgColor);
FillRect(fillArea);
if (IsDefault()) // external border
rect = DrawDefault(rect, bEnabled); SetHighColor(darkBorderColor);
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
StrokeRect(rect); StrokeRect(rect);
BeginLineArray(8); BeginLineArray(14);
// 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 // Shadow
rgb_color firstBevelColor; AddLine(rect.LeftBottom(), rect.RightBottom(), firstBevelColor);
if (bEnabled) AddLine(rect.RightBottom(), rect.RightTop(), firstBevelColor);
firstBevelColor = tint_color(no_tint, B_DARKEN_2_TINT); // Light
else AddLine(rect.LeftTop(), rect.LeftBottom(),buttonBgColor);
firstBevelColor = no_tint; AddLine(rect.LeftTop(), rect.RightTop(), buttonBgColor);
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), rect.InsetBy(1.0f, 1.0f);
BPoint(rect.left, rect.bottom), lighten1);
AddLine(BPoint(rect.left + 1.0f, rect.top), // Shadow
BPoint(rect.right, rect.top), lighten1); 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(); EndLineArray();
rect.InsetBy(1, 1); // Invert if clicked
if (enabled && pushed) {
// Second bevel rect.InsetBy(-2.0f,-2.0f);
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;
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));
if (bEnabled && IsFocus() && Window()->IsActive()) // Focus line
{ if (enabled && IsFocus() && Window()->IsActive() && !pushed)
// Draw focus line DrawFocusLine(x,focusLineY,stringWidth,true);
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 $
* *