* drawing is on the road to perfection

* uses another virtual to implement WindowActivated() and draw itself in
  disabled look just like in R5
* fixed _ButtonRectFor() off by one errors
* tiny problems remain when clicking on the ScrollBar (it is shifted)
* the _ValueFor() might not be perfect


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14929 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2005-11-15 00:23:03 +00:00
parent a2236c14c0
commit db3c2e1e8e
2 changed files with 209 additions and 54 deletions
+16 -1
View File
@@ -24,6 +24,8 @@
#define SCROLL_BAR_MAXIMUM_KNOB_SIZE 50 #define SCROLL_BAR_MAXIMUM_KNOB_SIZE 50
#define SCROLL_BAR_MINIMUM_KNOB_SIZE 9 #define SCROLL_BAR_MINIMUM_KNOB_SIZE 9
#define DISABLES_ON_WINDOW_DEACTIVATION 1
//---------------------------------------------------------------- //----------------------------------------------------------------
//----- BScrollBar class ----------------------------------------- //----- BScrollBar class -----------------------------------------
@@ -83,13 +85,21 @@ virtual status_t GetSupportedSuites(BMessage *data);
//----- Private or reserved ----------------------------------------- //----- Private or reserved -----------------------------------------
virtual status_t Perform(perform_code d, void *arg); virtual status_t Perform(perform_code d, void *arg);
// NOTE: this takes up another virtual slot compared to R5
#if DISABLES_ON_WINDOW_DEACTIVATION
virtual void WindowActivated(bool active);
#endif
private: private:
class Private; class Private;
friend class Private; friend class Private;
friend status_t control_scrollbar(scroll_bar_info *info, BScrollBar *bar); // for use within the preflet friend status_t control_scrollbar(scroll_bar_info *info, BScrollBar *bar); // for use within the preflet
#if !DISABLES_ON_WINDOW_DEACTIVATION
virtual void _ReservedScrollBar1(); virtual void _ReservedScrollBar1();
#endif
virtual void _ReservedScrollBar2(); virtual void _ReservedScrollBar2();
virtual void _ReservedScrollBar3(); virtual void _ReservedScrollBar3();
virtual void _ReservedScrollBar4(); virtual void _ReservedScrollBar4();
@@ -103,10 +113,15 @@ virtual void _ReservedScrollBar4();
BRect _ButtonRectFor(int32 button) const; BRect _ButtonRectFor(int32 button) const;
void _UpdateTargetValue(BPoint where); void _UpdateTargetValue(BPoint where);
void _UpdateArrowButtons(); void _UpdateArrowButtons();
void _DrawDisabledBackground(BRect area,
const rgb_color& light,
const rgb_color& dark,
const rgb_color& fill);
void _DrawArrowButton(int32 direction, void _DrawArrowButton(int32 direction,
bool doubleArrows,
BRect frame, BRect frame,
const BRect& updateRect, const BRect& updateRect,
bool down); bool enabled, bool down);
float fMin; float fMin;
float fMax; float fMax;
+193 -53
View File
@@ -467,7 +467,7 @@ BScrollBar::MouseDown(BPoint where)
Invalidate(fPrivateData->fThumbFrame); Invalidate(fPrivateData->fThumbFrame);
return; return;
} }
printf("check\n");
// hit test for arrows or empty area // hit test for arrows or empty area
float scrollValue = 0.0; float scrollValue = 0.0;
fPrivateData->fButtonDown = _ButtonFor(where); fPrivateData->fButtonDown = _ButtonFor(where);
@@ -534,7 +534,7 @@ BScrollBar::MouseUp(BPoint pt)
void void
BScrollBar::MouseMoved(BPoint where, uint32 transit, const BMessage* message) BScrollBar::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
{ {
if (!fPrivateData->fEnabled || fMin == fMax) if (!fPrivateData->fEnabled || fMin >= fMax || fProportion >= 1.0)
return; return;
if (fPrivateData->fButtonDown != NOARROW) { if (fPrivateData->fButtonDown != NOARROW) {
@@ -589,8 +589,10 @@ BScrollBar::Draw(BRect updateRect)
StrokeRect(bounds); StrokeRect(bounds);
bounds.InsetBy(1.0, 1.0); bounds.InsetBy(1.0, 1.0);
bool enabled = fPrivateData->fEnabled && fMin < fMax && fProportion < 1.0;
rgb_color light, light1, dark, dark1, dark2, dark4; rgb_color light, light1, dark, dark1, dark2, dark4;
if (fPrivateData->fEnabled) { if (enabled) {
light = tint_color(normal, B_LIGHTEN_MAX_TINT); light = tint_color(normal, B_LIGHTEN_MAX_TINT);
light1 = tint_color(normal, B_LIGHTEN_1_TINT); light1 = tint_color(normal, B_LIGHTEN_1_TINT);
dark = tint_color(normal, B_DARKEN_3_TINT); dark = tint_color(normal, B_DARKEN_3_TINT);
@@ -598,33 +600,34 @@ BScrollBar::Draw(BRect updateRect)
dark2 = tint_color(normal, B_DARKEN_2_TINT); dark2 = tint_color(normal, B_DARKEN_2_TINT);
dark4 = tint_color(normal, B_DARKEN_4_TINT); dark4 = tint_color(normal, B_DARKEN_4_TINT);
} else { } else {
light = tint_color(normal, B_LIGHTEN_1_TINT); light = tint_color(normal, B_LIGHTEN_MAX_TINT);
light1 = normal; light1 = normal;
dark = tint_color(normal, B_DARKEN_2_TINT); dark = tint_color(normal, B_DARKEN_2_TINT);
dark1 = normal; dark1 = tint_color(normal, B_LIGHTEN_2_TINT);
dark2 = tint_color(normal, B_DARKEN_1_TINT); dark2 = tint_color(normal, B_LIGHTEN_1_TINT);
dark4 = tint_color(normal, B_DARKEN_3_TINT); dark4 = tint_color(normal, B_DARKEN_3_TINT);
} }
SetDrawingMode(B_OP_OVER); SetDrawingMode(B_OP_OVER);
BRect thumbBG = bounds; BRect thumbBG = bounds;
bool doubleArrows = _DoubleArrows();
// Draw arrows // Draw arrows
if (fOrientation == B_HORIZONTAL) { if (fOrientation == B_HORIZONTAL) {
BRect buttonFrame(bounds.left, bounds.top, bounds.left + bounds.Height(), bounds.bottom); BRect buttonFrame(bounds.left, bounds.top, bounds.left + bounds.Height(), bounds.bottom);
_DrawArrowButton(ARROW_LEFT, buttonFrame, updateRect, _DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW1); enabled, fPrivateData->fButtonDown == ARROW1);
if (_DoubleArrows()) { if (doubleArrows) {
buttonFrame.OffsetBy(bounds.Height() + 1, 0.0); buttonFrame.OffsetBy(bounds.Height() + 1, 0.0);
_DrawArrowButton(ARROW_RIGHT, buttonFrame, updateRect, _DrawArrowButton(ARROW_RIGHT, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW2); enabled, fPrivateData->fButtonDown == ARROW2);
buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), bounds.top); buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), bounds.top);
_DrawArrowButton(ARROW_LEFT, buttonFrame, updateRect, _DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW3); enabled, fPrivateData->fButtonDown == ARROW3);
thumbBG.left += bounds.Height() * 2 + 2; thumbBG.left += bounds.Height() * 2 + 2;
thumbBG.right -= bounds.Height() * 2 + 2; thumbBG.right -= bounds.Height() * 2 + 2;
@@ -634,22 +637,22 @@ BScrollBar::Draw(BRect updateRect)
} }
buttonFrame.OffsetTo(bounds.right - bounds.Height(), bounds.top); buttonFrame.OffsetTo(bounds.right - bounds.Height(), bounds.top);
_DrawArrowButton(ARROW_RIGHT, buttonFrame, updateRect, _DrawArrowButton(ARROW_RIGHT, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW4); enabled, fPrivateData->fButtonDown == ARROW4);
} else { } else {
BRect buttonFrame(bounds.left, bounds.top, bounds.right, bounds.top + bounds.Width()); BRect buttonFrame(bounds.left, bounds.top, bounds.right, bounds.top + bounds.Width());
_DrawArrowButton(ARROW_UP, buttonFrame, updateRect, _DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW1); enabled, fPrivateData->fButtonDown == ARROW1);
if (_DoubleArrows()) { if (doubleArrows) {
buttonFrame.OffsetBy(0.0, bounds.Width() + 1); buttonFrame.OffsetBy(0.0, bounds.Width() + 1);
_DrawArrowButton(ARROW_DOWN, buttonFrame, updateRect, _DrawArrowButton(ARROW_DOWN, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW2); enabled, fPrivateData->fButtonDown == ARROW2);
buttonFrame.OffsetTo(bounds.left, bounds.bottom - ((bounds.Width() * 2) + 1)); buttonFrame.OffsetTo(bounds.left, bounds.bottom - ((bounds.Width() * 2) + 1));
_DrawArrowButton(ARROW_UP, buttonFrame, updateRect, _DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW3); enabled, fPrivateData->fButtonDown == ARROW3);
thumbBG.top += bounds.Width() * 2 + 2; thumbBG.top += bounds.Width() * 2 + 2;
thumbBG.bottom -= bounds.Width() * 2 + 2; thumbBG.bottom -= bounds.Width() * 2 + 2;
@@ -659,8 +662,8 @@ BScrollBar::Draw(BRect updateRect)
} }
buttonFrame.OffsetTo(bounds.left, bounds.bottom - bounds.Width()); buttonFrame.OffsetTo(bounds.left, bounds.bottom - bounds.Width());
_DrawArrowButton(ARROW_DOWN, buttonFrame, updateRect, _DrawArrowButton(ARROW_DOWN, doubleArrows, buttonFrame, updateRect,
fPrivateData->fButtonDown == ARROW4); enabled, fPrivateData->fButtonDown == ARROW4);
} }
SetDrawingMode(B_OP_COPY); SetDrawingMode(B_OP_COPY);
@@ -753,12 +756,12 @@ BScrollBar::Draw(BRect updateRect)
} }
} }
thumbBG.InsetBy(1.0, 1.0);
SetHighColor(dark1); SetHighColor(dark1);
// Draw scroll thumb // Draw scroll thumb
if (fPrivateData->fEnabled) { if (enabled) {
// fill and additional dark lines // fill and additional dark lines
thumbBG.InsetBy(1.0, 1.0);
if (fOrientation == B_HORIZONTAL) { if (fOrientation == B_HORIZONTAL) {
BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, thumbBG.bottom); BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, thumbBG.bottom);
if (leftOfThumb.IsValid()) if (leftOfThumb.IsValid())
@@ -819,7 +822,46 @@ BScrollBar::Draw(BRect updateRect)
// TODO: Add the other thumb styles - dots and lines // TODO: Add the other thumb styles - dots and lines
} else { } else {
FillRect(thumbBG); if (fMin >= fMax || fProportion >= 1.0) {
// we cannot scroll at all
_DrawDisabledBackground(thumbBG, light, dark, dark1);
} else {
// we could scroll, but we're simply disabled
if (fOrientation == B_HORIZONTAL) {
// left of thumb
BRect besidesThumb(thumbBG);
besidesThumb.right = rect.left - 1;
_DrawDisabledBackground(besidesThumb, light, dark, dark1);
// right of thumb
besidesThumb.left = rect.right + 1;
besidesThumb.right = thumbBG.right;
_DrawDisabledBackground(besidesThumb, light, dark, dark1);
} else {
// above thumb
BRect besidesThumb(thumbBG);
besidesThumb.bottom = rect.top - 1;
_DrawDisabledBackground(besidesThumb, light, dark, dark1);
// below thumb
besidesThumb.top = rect.bottom + 1;
besidesThumb.bottom = thumbBG.bottom;
_DrawDisabledBackground(besidesThumb, light, dark, dark1);
}
// thumb
BeginLineArray(4);
AddLine(BPoint(rect.left, rect.bottom),
BPoint(rect.left, rect.top), light);
AddLine(BPoint(rect.left + 1, rect.top),
BPoint(rect.right, rect.top), light);
AddLine(BPoint(rect.right, rect.top + 1),
BPoint(rect.right, rect.bottom), dark2);
AddLine(BPoint(rect.right - 1, rect.bottom),
BPoint(rect.left + 1, rect.bottom), dark2);
EndLineArray();
// fill thumb
rect.InsetBy(1.0, 1.0);
SetHighColor(dark1);
FillRect(rect);
}
} }
} }
@@ -849,7 +891,7 @@ BScrollBar::ResolveSpecifier(BMessage *msg,int32 index,
void void
BScrollBar::ResizeToPreferred() BScrollBar::ResizeToPreferred()
{ {
// TODO: Implement BView::ResizeToPreferred();
} }
// GetPreferredSize // GetPreferredSize
@@ -900,8 +942,18 @@ BScrollBar::Perform(perform_code d, void *arg)
return BView::Perform(d, arg); return BView::Perform(d, arg);
} }
#if DISABLES_ON_WINDOW_DEACTIVATION
void
BScrollBar::WindowActivated(bool active)
{
fPrivateData->fEnabled = active;
Invalidate();
}
#endif // DISABLES_ON_WINDOW_DEACTIVATION
#if !DISABLES_ON_WINDOW_DEACTIVATION
void BScrollBar::_ReservedScrollBar1() {} void BScrollBar::_ReservedScrollBar1() {}
#endif
void BScrollBar::_ReservedScrollBar2() {} void BScrollBar::_ReservedScrollBar2() {}
void BScrollBar::_ReservedScrollBar3() {} void BScrollBar::_ReservedScrollBar3() {}
void BScrollBar::_ReservedScrollBar4() {} void BScrollBar::_ReservedScrollBar4() {}
@@ -961,8 +1013,11 @@ BScrollBar::_UpdateThumbFrame()
maxSize--; maxSize--;
float thumbSize = minSize; float thumbSize = minSize;
float proportion = fProportion;
if (fMin == fMax)
proportion = 1.0;
if (fPrivateData->fScrollBarInfo.proportional) if (fPrivateData->fScrollBarInfo.proportional)
thumbSize += (maxSize - minSize) * fProportion; thumbSize += (maxSize - minSize) * proportion;
thumbSize = floorf(thumbSize + 0.5); thumbSize = floorf(thumbSize + 0.5);
thumbSize--; thumbSize--;
@@ -1117,10 +1172,10 @@ BScrollBar::_ButtonRectFor(int32 button) const
rect.OffsetBy(0.0, buttonSize); rect.OffsetBy(0.0, buttonSize);
break; break;
case ARROW3: case ARROW3:
rect.OffsetTo(bounds.left, bounds.bottom - 2 * buttonSize); rect.OffsetTo(bounds.left, bounds.bottom - 2 * buttonSize + 1);
break; break;
case ARROW4: case ARROW4:
rect.OffsetTo(bounds.left, bounds.bottom - buttonSize); rect.OffsetTo(bounds.left, bounds.bottom - buttonSize + 1);
break; break;
} }
} else { } else {
@@ -1131,10 +1186,10 @@ BScrollBar::_ButtonRectFor(int32 button) const
rect.OffsetBy(buttonSize, 0.0); rect.OffsetBy(buttonSize, 0.0);
break; break;
case ARROW3: case ARROW3:
rect.OffsetTo(bounds.right - 2 * buttonSize, bounds.top); rect.OffsetTo(bounds.right - 2 * buttonSize + 1, bounds.top);
break; break;
case ARROW4: case ARROW4:
rect.OffsetTo(bounds.right - buttonSize, bounds.top); rect.OffsetTo(bounds.right - buttonSize + 1, bounds.top);
break; break;
} }
} }
@@ -1210,25 +1265,90 @@ control_scrollbar(scroll_bar_info *info, BScrollBar *bar)
return B_OK; return B_OK;
} }
// _DrawDisabledBackground
void
BScrollBar::_DrawDisabledBackground(BRect area,
const rgb_color& light, const rgb_color& dark,
const rgb_color& fill)
{
if (!area.IsValid())
return;
if (fOrientation == B_VERTICAL) {
int32 height = area.IntegerHeight();
if (height == 0) {
SetHighColor(dark);
StrokeLine(area.LeftTop(), area.RightTop());
} else if (height == 1) {
SetHighColor(dark);
FillRect(area);
} else {
BeginLineArray(4);
AddLine(BPoint(area.left, area.top),
BPoint(area.right, area.top), dark);
AddLine(BPoint(area.left, area.bottom - 1),
BPoint(area.left, area.top + 1), light);
AddLine(BPoint(area.left + 1, area.top + 1),
BPoint(area.right, area.top + 1), light);
AddLine(BPoint(area.right, area.bottom),
BPoint(area.left, area.bottom), dark);
EndLineArray();
area.left++;
area.top += 2;
area.bottom--;
if (area.IsValid()) {
SetHighColor(fill);
FillRect(area);
}
}
} else {
int32 width = area.IntegerWidth();
if (width == 0) {
SetHighColor(dark);
StrokeLine(area.LeftBottom(), area.LeftTop());
} else if (width == 1) {
SetHighColor(dark);
FillRect(area);
} else {
BeginLineArray(4);
AddLine(BPoint(area.left, area.bottom),
BPoint(area.left, area.top), dark);
AddLine(BPoint(area.left + 1, area.bottom),
BPoint(area.left + 1, area.top + 1), light);
AddLine(BPoint(area.left + 1, area.top),
BPoint(area.right - 1, area.top), light);
AddLine(BPoint(area.right, area.top),
BPoint(area.right, area.bottom), dark);
EndLineArray();
area.left += 2;
area.top ++;
area.right--;
if (area.IsValid()) {
SetHighColor(fill);
FillRect(area);
}
}
}
}
// _DrawArrowButton // _DrawArrowButton
void void
BScrollBar::_DrawArrowButton(int32 direction, BRect r, const BRect& updateRect, bool down) BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect r,
const BRect& updateRect, bool enabled, bool down)
{ {
if (!updateRect.Intersects(r)) if (!updateRect.Intersects(r))
return; return;
rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color light, dark, normal,arrow,arrow2; rgb_color light, dark, darker, normal, arrow;
if (down && fPrivateData->fDoRepeat) { if (down && fPrivateData->fDoRepeat) {
light = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0); light = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0);
arrow2 = dark = tint_color(c, B_LIGHTEN_1_TINT); dark = darker = c;
normal = tint_color(c, B_DARKEN_1_TINT); normal = tint_color(c, B_DARKEN_1_TINT);
arrow = tint_color(c, B_DARKEN_MAX_TINT); arrow = tint_color(c, B_DARKEN_MAX_TINT);
} else { } else {
bool use_enabled_colors = fPrivateData->fEnabled;
// Add a usability perk - disable buttons if they would not do anything - // Add a usability perk - disable buttons if they would not do anything -
// like a left arrow if the value==fMin // like a left arrow if the value==fMin
// NOTE: disabled because of too much visual noise/distraction // NOTE: disabled because of too much visual noise/distraction
@@ -1237,15 +1357,17 @@ BScrollBar::_DrawArrowButton(int32 direction, BRect r, const BRect& updateRect,
else if ((direction == ARROW_RIGHT || direction == ARROW_DOWN) && (fValue == fMax) ) else if ((direction == ARROW_RIGHT || direction == ARROW_DOWN) && (fValue == fMax) )
use_enabled_colors = false;*/ use_enabled_colors = false;*/
if (use_enabled_colors) { if (enabled) {
arrow2 = light = tint_color(c, B_LIGHTEN_MAX_TINT); light = tint_color(c, B_LIGHTEN_MAX_TINT);
dark = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0); dark = tint_color(c, B_DARKEN_1_TINT);
darker = tint_color(c, B_DARKEN_2_TINT);
normal = c; normal = c;
arrow = tint_color(c, (B_DARKEN_MAX_TINT + B_DARKEN_4_TINT) / 2.0); arrow = tint_color(c, (B_DARKEN_MAX_TINT + B_DARKEN_4_TINT) / 2.0);
} else { } else {
arrow2 = light = tint_color(c, B_LIGHTEN_1_TINT); light = tint_color(c, B_LIGHTEN_MAX_TINT);
dark = tint_color(c, B_DARKEN_1_TINT); dark = tint_color(c, B_LIGHTEN_1_TINT);
normal = c; darker = tint_color(c, B_DARKEN_2_TINT);
normal = tint_color(c, B_LIGHTEN_2_TINT);
arrow = tint_color(c, B_DARKEN_1_TINT); arrow = tint_color(c, B_DARKEN_1_TINT);
} }
} }
@@ -1301,24 +1423,42 @@ BScrollBar::_DrawArrowButton(int32 direction, BRect r, const BRect& updateRect,
BeginLineArray(4); BeginLineArray(4);
if (direction == ARROW_LEFT || direction == ARROW_RIGHT) { if (direction == ARROW_LEFT || direction == ARROW_RIGHT) {
// horizontal // horizontal
if (doubleArrows && direction == ARROW_LEFT) {
// draw in such a way that the arrows are
// more visually separated
AddLine(BPoint(r.left + 1, r.top),
BPoint(r.right - 1, r.top), light);
AddLine(BPoint(r.right, r.top),
BPoint(r.right, r.bottom), darker);
} else {
AddLine(BPoint(r.left + 1, r.top),
BPoint(r.right, r.top), light);
AddLine(BPoint(r.right, r.top + 1),
BPoint(r.right, r.bottom), dark);
}
AddLine(BPoint(r.left, r.bottom), AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.top), light); BPoint(r.left, r.top), light);
AddLine(BPoint(r.left + 1, r.top),
BPoint(r.right - 1, r.top), light);
AddLine(BPoint(r.right, r.top),
BPoint(r.right, r.bottom), dark);
AddLine(BPoint(r.right - 1, r.bottom), AddLine(BPoint(r.right - 1, r.bottom),
BPoint(r.left + 1, r.bottom), dark); BPoint(r.left + 1, r.bottom), dark);
} else { } else {
// vertical // vertical
AddLine(BPoint(r.left, r.bottom - 1), if (doubleArrows && direction == ARROW_UP) {
BPoint(r.left, r.top), light); // draw in such a way that the arrows are
// more visually separated
AddLine(BPoint(r.left, r.bottom - 1),
BPoint(r.left, r.top), light);
AddLine(BPoint(r.right, r.bottom),
BPoint(r.left, r.bottom), darker);
} else {
AddLine(BPoint(r.left, r.bottom),
BPoint(r.left, r.top), light);
AddLine(BPoint(r.right, r.bottom),
BPoint(r.left + 1, r.bottom), dark);
}
AddLine(BPoint(r.left + 1, r.top), AddLine(BPoint(r.left + 1, r.top),
BPoint(r.right, r.top), light); BPoint(r.right, r.top), light);
AddLine(BPoint(r.right, r.top + 1), AddLine(BPoint(r.right, r.top + 1),
BPoint(r.right, r.bottom), dark); BPoint(r.right, r.bottom - 1), dark);
AddLine(BPoint(r.right - 1, r.bottom),
BPoint(r.left, r.bottom), dark);
} }
EndLineArray(); EndLineArray();
} }