6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
36 // ListView title drawing and mouse manipulation classes
39 #include "TitleView.h"
42 #include <Application.h>
43 #include <ControlLook.h>
45 #include <PopUpMenu.h>
54 #include "ContainerWindow.h"
56 #include "Utilities.h"
59 #define APP_SERVER_CLEARS_BACKGROUND 1
62 static const float kMinFontSize
= 8.0f
;
63 static const float kMinTitleHeight
= 13.0f
;
64 static const float kTitleSpacing
= 1.4f
;
68 _DrawLine(BPoseView
* view
, BPoint from
, BPoint to
)
70 float tint
= B_NO_TINT
;
71 color_which highColor
= view
->HighUIColor(&tint
);
72 view
->SetHighUIColor(view
->LowUIColor(), B_DARKEN_1_TINT
);
73 view
->StrokeLine(from
, to
);
74 view
->SetHighUIColor(highColor
, tint
);
79 _UndrawLine(BPoseView
* view
, BPoint from
, BPoint to
)
81 view
->StrokeLine(from
, to
, B_SOLID_LOW
);
86 _DrawOutline(BView
* view
, BRect where
)
90 float tint
= B_NO_TINT
;
91 color_which highColor
= view
->HighUIColor(&tint
);
92 view
->SetHighUIColor(B_CONTROL_HIGHLIGHT_COLOR
);
93 view
->StrokeRect(where
);
94 view
->SetHighUIColor(highColor
, tint
);
98 // #pragma mark - BTitleView
101 BTitleView::BTitleView(BPoseView
* view
)
103 BView("TitleView", B_WILL_DRAW
),
105 fTitleList(10, true),
106 fHorizontalResizeCursor(B_CURSOR_ID_RESIZE_EAST_WEST
),
107 fPreviouslyClickedColumnTitle(0),
108 fPreviousLeftClickTime(0),
111 SetHighUIColor(B_PANEL_BACKGROUND_COLOR
);
112 SetLowUIColor(B_PANEL_BACKGROUND_COLOR
);
113 #if APP_SERVER_CLEARS_BACKGROUND
114 SetViewUIColor(B_PANEL_BACKGROUND_COLOR
);
116 SetViewColor(B_TRANSPARENT_COLOR
);
119 float fontSize
= std::max(kMinFontSize
,
120 floorf(be_plain_font
->Size() * 0.75f
));
122 BFont
font(be_plain_font
);
123 font
.SetSize(fontSize
);
126 fPreferredHeight
= std::max(kMinTitleHeight
,
127 ceilf(fontSize
* kTitleSpacing
));
133 BTitleView::~BTitleView()
135 delete fTrackingState
;
142 fTitleList
.MakeEmpty();
144 for (int32 index
= 0; ; index
++) {
145 BColumn
* column
= fPoseView
->ColumnAt(index
);
148 fTitleList
.AddItem(new BColumnTitle(this, column
));
155 BTitleView::AddTitle(BColumn
* column
, const BColumn
* after
)
157 int32 count
= fTitleList
.CountItems();
160 for (index
= 0; index
< count
; index
++) {
161 BColumn
* titleColumn
= fTitleList
.ItemAt(index
)->Column();
163 if (after
== titleColumn
) {
171 fTitleList
.AddItem(new BColumnTitle(this, column
), index
);
177 BTitleView::RemoveTitle(BColumn
* column
)
179 int32 count
= fTitleList
.CountItems();
180 for (int32 index
= 0; index
< count
; index
++) {
181 BColumnTitle
* title
= fTitleList
.ItemAt(index
);
182 if (title
->Column() == column
) {
183 fTitleList
.RemoveItem(title
);
193 BTitleView::MinSize()
195 return BSize(16, fPreferredHeight
);
200 BTitleView::MaxSize()
202 return BSize(B_SIZE_UNLIMITED
, fPreferredHeight
);
207 BTitleView::Draw(BRect rect
)
214 BTitleView::Draw(BRect
/*updateRect*/, bool useOffscreen
, bool updateOnly
,
215 const BColumnTitle
* pressedColumn
,
216 void (*trackRectBlitter
)(BView
*, BRect
), BRect passThru
)
218 BRect
bounds(Bounds());
224 frame
.right
+= frame
.left
;
225 // ToDo: this is kind of messy way of avoiding being clipped
226 // by the amount the title is scrolled to the left
227 view
= sOffscreen
->BeginUsing(frame
);
228 view
->SetOrigin(-bounds
.left
, 0);
229 view
->SetLowColor(LowColor());
230 view
->SetHighColor(HighColor());
233 view
->SetFont(&font
);
237 view
->SetHighUIColor(B_PANEL_BACKGROUND_COLOR
, B_DARKEN_2_TINT
);
238 view
->StrokeLine(bounds
.LeftBottom(), bounds
.RightBottom());
241 rgb_color baseColor
= ui_color(B_PANEL_BACKGROUND_COLOR
);
242 be_control_look
->DrawButtonBackground(view
, bounds
, bounds
, baseColor
, 0,
243 BControlLook::B_TOP_BORDER
| BControlLook::B_BOTTOM_BORDER
);
245 int32 count
= fTitleList
.CountItems();
246 float minx
= bounds
.right
;
247 float maxx
= bounds
.left
;
248 for (int32 index
= 0; index
< count
; index
++) {
249 BColumnTitle
* title
= fTitleList
.ItemAt(index
);
250 title
->Draw(view
, title
== pressedColumn
);
251 BRect
titleBounds(title
->Bounds());
252 if (titleBounds
.left
< minx
)
253 minx
= titleBounds
.left
;
254 if (titleBounds
.right
> maxx
)
255 maxx
= titleBounds
.right
;
260 view
->SetHighUIColor(B_PANEL_BACKGROUND_COLOR
, B_DARKEN_1_TINT
);
261 view
->StrokeLine(BPoint(minx
, bounds
.top
),
262 BPoint(minx
, bounds
.bottom
- 1));
264 #if !(APP_SERVER_CLEARS_BACKGROUND)
265 FillRect(BRect(bounds
.left
, bounds
.top
+ 1, minx
- 1, bounds
.bottom
- 1),
267 FillRect(BRect(maxx
+ 1, bounds
.top
+ 1, bounds
.right
, bounds
.bottom
- 1),
272 if (trackRectBlitter
)
273 (trackRectBlitter
)(view
, passThru
);
276 DrawBitmap(sOffscreen
->Bitmap());
277 sOffscreen
->DoneUsing();
278 } else if (trackRectBlitter
)
279 (trackRectBlitter
)(view
, passThru
);
284 BTitleView::MouseDown(BPoint where
)
286 BContainerWindow
* window
= dynamic_cast<BContainerWindow
*>(Window());
290 if (!window
->IsActive()) {
291 // window wasn't active, activate it and bail
296 // finish any pending edits
297 fPoseView
->CommitActivePose();
299 BColumnTitle
* title
= FindColumnTitle(where
);
300 BColumnTitle
* resizedTitle
= InColumnResizeArea(where
);
303 GetMouse(&where
, &buttons
);
305 // Check if the user clicked the secondary mouse button.
306 // if so, display the attribute menu:
308 if (SecondaryMouseButtonDown(modifiers(), buttons
)) {
309 BPopUpMenu
* menu
= new BPopUpMenu("Attributes", false, false);
310 menu
->SetFont(be_plain_font
);
311 window
->NewAttributeMenu(menu
);
312 window
->AddMimeTypesToMenu(menu
);
313 window
->MarkAttributeMenu(menu
);
314 menu
->SetTargetForItems(window
->PoseView());
315 menu
->Go(ConvertToScreen(where
), true, false);
319 bigtime_t doubleClickSpeed
;
320 get_click_speed(&doubleClickSpeed
);
323 bool force
= static_cast<bool>(buttons
& B_TERTIARY_MOUSE_BUTTON
);
324 if (force
|| buttons
& B_PRIMARY_MOUSE_BUTTON
) {
325 if (force
|| fPreviouslyClickedColumnTitle
!= 0) {
326 if (force
|| system_time() - fPreviousLeftClickTime
327 < doubleClickSpeed
) {
329 ResizeColumnToWidest(resizedTitle
->Column())) {
335 fPreviousLeftClickTime
= system_time();
336 fPreviouslyClickedColumnTitle
= resizedTitle
;
341 SetMouseEventMask(B_POINTER_EVENTS
,
342 B_NO_POINTER_HISTORY
| B_LOCK_WINDOW_FOCUS
);
346 fTrackingState
= new ColumnResizeState(this, resizedTitle
, where
,
347 system_time() + doubleClickSpeed
);
349 fTrackingState
= new ColumnDragState(this, title
, where
,
350 system_time() + doubleClickSpeed
);
356 BTitleView::MouseUp(BPoint where
)
358 if (fTrackingState
== NULL
)
361 fTrackingState
->MouseUp(where
);
363 delete fTrackingState
;
364 fTrackingState
= NULL
;
369 BTitleView::MouseMoved(BPoint where
, uint32 code
, const BMessage
* dragMessage
)
371 BContainerWindow
* window
= dynamic_cast<BContainerWindow
*>(Window());
375 if (fTrackingState
!= NULL
) {
377 if (Looper() != NULL
&& Looper()->CurrentMessage() != NULL
)
378 Looper()->CurrentMessage()->FindInt32("buttons", &buttons
);
379 fTrackingState
->MouseMoved(where
, buttons
);
385 if (InColumnResizeArea(where
) && window
->IsActive())
386 SetViewCursor(&fHorizontalResizeCursor
);
388 SetViewCursor(B_CURSOR_SYSTEM_DEFAULT
);
392 SetViewCursor(B_CURSOR_SYSTEM_DEFAULT
);
396 _inherited::MouseMoved(where
, code
, dragMessage
);
401 BTitleView::InColumnResizeArea(BPoint where
) const
403 int32 count
= fTitleList
.CountItems();
404 for (int32 index
= 0; index
< count
; index
++) {
405 BColumnTitle
* title
= fTitleList
.ItemAt(index
);
406 if (title
->InColumnResizeArea(where
))
415 BTitleView::FindColumnTitle(BPoint where
) const
417 int32 count
= fTitleList
.CountItems();
418 for (int32 index
= 0; index
< count
; index
++) {
419 BColumnTitle
* title
= fTitleList
.ItemAt(index
);
420 if (title
->Bounds().Contains(where
))
429 BTitleView::FindColumnTitle(const BColumn
* column
) const
431 int32 count
= fTitleList
.CountItems();
432 for (int32 index
= 0; index
< count
; index
++) {
433 BColumnTitle
* title
= fTitleList
.ItemAt(index
);
434 if (title
->Column() == column
)
442 // #pragma mark - BColumnTitle
445 BColumnTitle::BColumnTitle(BTitleView
* view
, BColumn
* column
)
454 BColumnTitle::InColumnResizeArea(BPoint where
) const
456 BRect
edge(Bounds());
457 edge
.left
= edge
.right
- kEdgeSize
;
458 edge
.right
+= kEdgeSize
;
460 return edge
.Contains(where
);
465 BColumnTitle::Bounds() const
467 BRect
bounds(fColumn
->Offset() - kTitleColumnLeftExtraMargin
, 0, 0,
468 fParent
->Bounds().Height());
469 bounds
.right
= bounds
.left
+ fColumn
->Width() + kTitleColumnExtraMargin
;
476 BColumnTitle::Draw(BView
* view
, bool pressed
)
478 BRect
bounds(Bounds());
480 font_height fontHeight
;
481 view
->GetFontHeight(&fontHeight
);
483 float baseline
= floor(bounds
.top
+ fontHeight
.ascent
484 + (bounds
.Height() + 1 - (fontHeight
.ascent
+ fontHeight
.descent
)) / 2);
485 BPoint
titleLocation(0, baseline
);
487 rgb_color baseColor
= ui_color(B_PANEL_BACKGROUND_COLOR
);
493 baseColor
= tint_color(baseColor
, B_DARKEN_1_TINT
);
495 be_control_look
->DrawButtonBackground(view
, rect
, rect
, baseColor
, 0,
496 BControlLook::B_TOP_BORDER
| BControlLook::B_BOTTOM_BORDER
);
499 BString
titleString(fColumn
->Title());
500 view
->TruncateString(&titleString
, B_TRUNCATE_END
,
501 bounds
.Width() - kTitleColumnExtraMargin
);
502 float resultingWidth
= view
->StringWidth(titleString
.String());
504 switch (fColumn
->Alignment()) {
507 titleLocation
.x
= bounds
.left
+ 1 + kTitleColumnLeftExtraMargin
;
511 titleLocation
.x
= bounds
.left
+ (bounds
.Width() / 2)
512 - (resultingWidth
/ 2);
516 titleLocation
.x
= bounds
.right
- resultingWidth
517 - kTitleColumnRightExtraMargin
;
521 view
->SetHighUIColor(B_PANEL_TEXT_COLOR
, pressed
? B_DARKEN_1_TINT
: 1.0f
);
522 view
->SetLowColor(baseColor
);
523 view
->DrawString(titleString
.String(), titleLocation
);
527 = (fColumn
->AttrHash() == fParent
->PoseView()->SecondarySort());
529 || (fColumn
->AttrHash() == fParent
->PoseView()->PrimarySort())) {
531 BPoint
center(titleLocation
.x
- 6,
532 roundf((bounds
.top
+ bounds
.bottom
) / 2.0));
534 if (fParent
->PoseView()->ReverseSort()) {
535 triangle
[0] = center
+ BPoint(-3.5, 1.5);
536 triangle
[1] = center
+ BPoint(3.5, 1.5);
537 triangle
[2] = center
+ BPoint(0.0, -2.0);
539 triangle
[0] = center
+ BPoint(-3.5, -1.5);
540 triangle
[1] = center
+ BPoint(3.5, -1.5);
541 triangle
[2] = center
+ BPoint(0.0, 2.0);
544 uint32 flags
= view
->Flags();
545 view
->SetFlags(flags
| B_SUBPIXEL_PRECISE
);
548 view
->SetHighUIColor(B_PANEL_BACKGROUND_COLOR
, 1.3);
549 view
->FillTriangle(triangle
[0], triangle
[1], triangle
[2]);
551 view
->SetHighUIColor(B_PANEL_BACKGROUND_COLOR
, 1.6);
552 view
->FillTriangle(triangle
[0], triangle
[1], triangle
[2]);
555 view
->SetFlags(flags
);
558 view
->SetHighUIColor(B_PANEL_BACKGROUND_COLOR
, B_DARKEN_1_TINT
);
559 view
->StrokeLine(bounds
.RightTop(), bounds
.RightBottom());
563 // #pragma mark - ColumnTrackState
566 ColumnTrackState::ColumnTrackState(BTitleView
* view
, BColumnTitle
* title
,
567 BPoint where
, bigtime_t pastClickTime
)
571 fFirstClickPoint(where
),
572 fPastClickTime(pastClickTime
),
579 ColumnTrackState::MouseUp(BPoint where
)
581 // if it is pressed shortly and not moved, it is a click
582 // else it is a track
583 if (system_time() <= fPastClickTime
&& !fHasMoved
)
591 ColumnTrackState::MouseMoved(BPoint where
, uint32 buttons
)
593 if (!fHasMoved
&& system_time() < fPastClickTime
) {
594 BRect
moveMargin(fFirstClickPoint
, fFirstClickPoint
);
595 moveMargin
.InsetBy(-1, -1);
597 if (moveMargin
.Contains(where
))
601 Moved(where
, buttons
);
606 // #pragma mark - ColumnResizeState
609 ColumnResizeState::ColumnResizeState(BTitleView
* view
, BColumnTitle
* title
,
610 BPoint where
, bigtime_t pastClickTime
)
612 ColumnTrackState(view
, title
, where
, pastClickTime
),
613 fLastLineDrawPos(-1),
614 fInitialTrackOffset((title
->fColumn
->Offset() + title
->fColumn
->Width())
622 ColumnResizeState::ValueChanged(BPoint where
)
624 float newWidth
= where
.x
+ fInitialTrackOffset
625 - fTitle
->fColumn
->Offset();
626 if (newWidth
< kMinColumnWidth
)
627 newWidth
= kMinColumnWidth
;
629 return newWidth
!= fTitle
->fColumn
->Width();
634 ColumnResizeState::Moved(BPoint where
, uint32
)
636 float newWidth
= where
.x
+ fInitialTrackOffset
637 - fTitle
->fColumn
->Offset();
638 if (newWidth
< kMinColumnWidth
)
639 newWidth
= kMinColumnWidth
;
641 BPoseView
* poseView
= fTitleView
->PoseView();
643 //bool shrink = (newWidth < fTitle->fColumn->Width());
646 poseView
->ResizeColumn(fTitle
->fColumn
, newWidth
, &fLastLineDrawPos
,
647 _DrawLine
, _UndrawLine
);
649 BRect
bounds(fTitleView
->Bounds());
650 bounds
.left
= fTitle
->fColumn
->Offset();
652 // force title redraw
653 fTitleView
->Draw(bounds
, true, false);
658 ColumnResizeState::Done(BPoint
/*where*/)
665 ColumnResizeState::Clicked(BPoint
/*where*/)
672 ColumnResizeState::DrawLine()
674 BPoseView
* poseView
= fTitleView
->PoseView();
675 ASSERT(!poseView
->IsDesktopWindow());
677 BRect
poseViewBounds(poseView
->Bounds());
678 // remember the line location
679 poseViewBounds
.left
= fTitle
->Bounds().right
;
680 fLastLineDrawPos
= poseViewBounds
.left
;
682 // draw the line in the new location
683 _DrawLine(poseView
, poseViewBounds
.LeftTop(),
684 poseViewBounds
.LeftBottom());
689 ColumnResizeState::UndrawLine()
691 if (fLastLineDrawPos
< 0)
694 BRect
poseViewBounds(fTitleView
->PoseView()->Bounds());
695 poseViewBounds
.left
= fLastLineDrawPos
;
697 _UndrawLine(fTitleView
->PoseView(), poseViewBounds
.LeftTop(),
698 poseViewBounds
.LeftBottom());
702 // #pragma mark - ColumnDragState
705 ColumnDragState::ColumnDragState(BTitleView
* view
, BColumnTitle
* columnTitle
,
706 BPoint where
, bigtime_t pastClickTime
)
708 ColumnTrackState(view
, columnTitle
, where
, pastClickTime
),
709 fInitialMouseTrackOffset(where
.x
),
710 fTrackingRemovedColumn(false)
714 ASSERT(fTitle
->Column());
715 DrawPressNoOutline();
720 // Autoscroll when dragging column left/right
721 // fix dragging back a column before the first column (now adds as last)
722 // make column swaps/adds not invalidate/redraw columns to the left
724 ColumnDragState::Moved(BPoint where
, uint32
)
726 // figure out where we are with the mouse
727 BRect
titleBounds(fTitleView
->Bounds());
728 bool overTitleView
= titleBounds
.Contains(where
);
729 BColumnTitle
* overTitle
= overTitleView
730 ? fTitleView
->FindColumnTitle(where
) : 0;
731 BRect
titleBoundsWithMargin(titleBounds
);
732 titleBoundsWithMargin
.InsetBy(0, -kRemoveTitleMargin
);
733 bool inMarginRect
= overTitleView
734 || titleBoundsWithMargin
.Contains(where
);
736 bool drawOutline
= false;
737 bool undrawOutline
= false;
739 if (fTrackingRemovedColumn
) {
741 // tracked back with a removed title into the title bar, add it
743 fTitleView
->EndRectTracking();
744 fColumnArchive
.Seek(0, SEEK_SET
);
745 BColumn
* column
= BColumn::InstantiateFromStream(&fColumnArchive
);
747 const BColumn
* after
= NULL
;
749 after
= overTitle
->Column();
751 fTitleView
->PoseView()->AddColumn(column
, after
);
752 fTrackingRemovedColumn
= false;
753 fTitle
= fTitleView
->FindColumnTitle(column
);
754 fInitialMouseTrackOffset
+= fTitle
->Bounds().left
;
759 // dragged a title out of the hysteresis margin around the
760 // title bar - remove it and start dragging it as a dotted outline
762 BRect
rect(fTitle
->Bounds());
763 rect
.OffsetBy(where
.x
- fInitialMouseTrackOffset
, where
.y
- 5);
764 fColumnArchive
.Seek(0, SEEK_SET
);
765 fTitle
->Column()->ArchiveToStream(&fColumnArchive
);
766 fInitialMouseTrackOffset
-= fTitle
->Bounds().left
;
767 if (fTitleView
->PoseView()->RemoveColumn(fTitle
->Column(),
770 fTitleView
->BeginRectTracking(rect
);
771 fTrackingRemovedColumn
= true;
772 undrawOutline
= true;
774 } else if (overTitle
&& overTitle
!= fTitle
775 // over a different column
776 && (overTitle
->Bounds().left
>= fTitle
->Bounds().right
777 // over the one to the right
778 || where
.x
< overTitle
->Bounds().left
779 + fTitle
->Bounds().Width())) {
780 // over the one to the left, far enough to not snap
783 BColumn
* column
= fTitle
->Column();
784 fInitialMouseTrackOffset
-= fTitle
->Bounds().left
;
786 fTitleView
->PoseView()->MoveColumnTo(column
, overTitle
->Column());
787 // re-grab the title object looking it up by the column
788 fTitle
= fTitleView
->FindColumnTitle(column
);
789 // recalc initialMouseTrackOffset
790 fInitialMouseTrackOffset
+= fTitle
->Bounds().left
;
797 DrawOutline(where
.x
- fInitialMouseTrackOffset
);
798 else if (undrawOutline
)
804 ColumnDragState::Done(BPoint
/*where*/)
806 if (fTrackingRemovedColumn
)
807 fTitleView
->EndRectTracking();
813 ColumnDragState::Clicked(BPoint
/*where*/)
815 BPoseView
* poseView
= fTitleView
->PoseView();
816 uint32 hash
= fTitle
->Column()->AttrHash();
817 uint32 primarySort
= poseView
->PrimarySort();
818 uint32 secondarySort
= poseView
->SecondarySort();
819 bool shift
= (modifiers() & B_SHIFT_KEY
) != 0;
822 // if we hit the primary sort field again
823 // then if shift key was down, switch primary and secondary
824 if (hash
== primarySort
) {
825 if (shift
&& secondarySort
) {
826 poseView
->SetPrimarySort(secondarySort
);
827 poseView
->SetSecondarySort(primarySort
);
829 poseView
->SetReverseSort(!poseView
->ReverseSort());
831 // hit secondary sort column with shift key, disable
832 if (hash
== secondarySort
)
833 poseView
->SetSecondarySort(0);
835 poseView
->SetSecondarySort(hash
);
837 poseView
->SetPrimarySort(hash
);
838 poseView
->SetReverseSort(false);
841 if (poseView
->PrimarySort() == poseView
->SecondarySort())
842 poseView
->SetSecondarySort(0);
846 poseView
->SortPoses();
847 poseView
->Invalidate();
852 ColumnDragState::ValueChanged(BPoint
)
859 ColumnDragState::DrawPressNoOutline()
861 fTitleView
->Draw(fTitleView
->Bounds(), true, false, fTitle
);
866 ColumnDragState::DrawOutline(float pos
)
868 BRect
outline(fTitle
->Bounds());
869 outline
.OffsetBy(pos
, 0);
870 fTitleView
->Draw(fTitleView
->Bounds(), true, false, fTitle
, _DrawOutline
,
876 ColumnDragState::UndrawOutline()
878 fTitleView
->Draw(fTitleView
->Bounds(), true, false);
882 OffscreenBitmap
* BTitleView::sOffscreen
= new OffscreenBitmap
;