BColumnTitle * BTitleView::FindColumnTitle(BPoint where) const { int32 count = fTitleList.CountItems(); for (int32 index = 0; index < count; index++) { BColumnTitle *title = fTitleList.ItemAt(index); if (title->Bounds().Contains(where)) return title; } return NULL; }
// ToDo: // Autoscroll when dragging column left/right // fix dragging back a column before the first column (now adds as last) // make column swaps/adds not invalidate/redraw columns to the left void ColumnDragState::Moved(BPoint where, uint32) { // figure out where we are with the mouse BRect titleBounds(fTitleView->Bounds()); bool overTitleView = titleBounds.Contains(where); BColumnTitle *overTitle = overTitleView ? fTitleView->FindColumnTitle(where) : 0; BRect titleBoundsWithMargin(titleBounds); titleBoundsWithMargin.InsetBy(0, -kRemoveTitleMargin); bool inMarginRect = overTitleView || titleBoundsWithMargin.Contains(where); bool drawOutline = false; bool undrawOutline = false; if (fTrackingRemovedColumn) { if (overTitleView) { // tracked back with a removed title into the title bar, add it // back fTitleView->EndRectTracking(); fColumnArchive.Seek(0, SEEK_SET); BColumn *column = BColumn::InstantiateFromStream(&fColumnArchive); ASSERT(column); const BColumn *after = NULL; if (overTitle) after = overTitle->Column(); fTitleView->PoseView()->AddColumn(column, after); fTrackingRemovedColumn = false; fTitle = fTitleView->FindColumnTitle(column); fInitialMouseTrackOffset += fTitle->Bounds().left; drawOutline = true; } } else { if (!inMarginRect) { // dragged a title out of the hysteresis margin around the // title bar - remove it and start dragging it as a dotted outline BRect rect(fTitle->Bounds()); rect.OffsetBy(where.x - fInitialMouseTrackOffset, where.y - 5); fColumnArchive.Seek(0, SEEK_SET); fTitle->Column()->ArchiveToStream(&fColumnArchive); fInitialMouseTrackOffset -= fTitle->Bounds().left; if (fTitleView->PoseView()->RemoveColumn(fTitle->Column(), false)) { fTitle = 0; fTitleView->BeginRectTracking(rect); fTrackingRemovedColumn = true; undrawOutline = true; } } else if (overTitle && overTitle != fTitle // over a different column && (overTitle->Bounds().left >= fTitle->Bounds().right // over the one to the right || where.x < overTitle->Bounds().left + fTitle->Bounds().Width())){ // over the one to the left, far enough to not snap right back BColumn *column = fTitle->Column(); fInitialMouseTrackOffset -= fTitle->Bounds().left; // swap the columns fTitleView->PoseView()->MoveColumnTo(column, overTitle->Column()); // re-grab the title object looking it up by the column fTitle = fTitleView->FindColumnTitle(column); // recalc initialMouseTrackOffset fInitialMouseTrackOffset += fTitle->Bounds().left; drawOutline = true; } else drawOutline = true; } if (drawOutline) DrawOutline(where.x - fInitialMouseTrackOffset); else if (undrawOutline) UndrawOutline(); }
void BTitleView::Draw(BRect /*updateRect*/, bool useOffscreen, bool updateOnly, const BColumnTitle *pressedColumn, void (*trackRectBlitter)(BView *, BRect), BRect passThru) { BRect bounds(Bounds()); BView *view; if (useOffscreen) { ASSERT(sOffscreen); BRect frame(bounds); frame.right += frame.left; // this is kind of messy way of avoiding being clipped by the ammount the // title is scrolled to the left // ToDo: fix this view = sOffscreen->BeginUsing(frame); view->SetOrigin(-bounds.left, 0); view->SetLowColor(LowColor()); view->SetHighColor(HighColor()); BFont font(be_plain_font); font.SetSize(9); view->SetFont(&font); } else view = this; if (be_control_look != NULL) { rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); view->SetHighColor(tint_color(base, B_DARKEN_2_TINT)); view->StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); bounds.bottom--; be_control_look->DrawButtonBackground(view, bounds, bounds, base, 0, BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER); } else { // fill background with light gray background if (!updateOnly) view->FillRect(bounds, B_SOLID_LOW); view->BeginLineArray(4); view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShadowColor); view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sShadowColor); // draw lighter gray and white inset lines bounds.InsetBy(0, 1); view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sLightShadowColor); view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShineColor); view->EndLineArray(); } int32 count = fTitleList.CountItems(); float minx = bounds.right; float maxx = bounds.left; for (int32 index = 0; index < count; index++) { BColumnTitle *title = fTitleList.ItemAt(index); title->Draw(view, title == pressedColumn); BRect titleBounds(title->Bounds()); if (titleBounds.left < minx) minx = titleBounds.left; if (titleBounds.right > maxx) maxx = titleBounds.right; } if (be_control_look != NULL) { bounds = Bounds(); minx--; view->SetHighColor(sLightShadowColor); view->StrokeLine(BPoint(minx, bounds.top), BPoint(minx, bounds.bottom - 1)); } else { // first and last shades before and after first column maxx++; minx--; view->BeginLineArray(2); view->AddLine(BPoint(minx, bounds.top), BPoint(minx, bounds.bottom), sShadowColor); view->AddLine(BPoint(maxx, bounds.top), BPoint(maxx, bounds.bottom), sShineColor); view->EndLineArray(); } #if !(APP_SERVER_CLEARS_BACKGROUND) FillRect(BRect(bounds.left, bounds.top + 1, minx - 1, bounds.bottom - 1), B_SOLID_LOW); FillRect(BRect(maxx + 1, bounds.top + 1, bounds.right, bounds.bottom - 1), B_SOLID_LOW); #endif if (useOffscreen) { if (trackRectBlitter) (trackRectBlitter)(view, passThru); view->Sync(); DrawBitmap(sOffscreen->Bitmap()); sOffscreen->DoneUsing(); } else if (trackRectBlitter) (trackRectBlitter)(view, passThru); }
void BTitleView::Draw(BRect /*updateRect*/, bool useOffscreen, bool updateOnly, const BColumnTitle* pressedColumn, void (*trackRectBlitter)(BView*, BRect), BRect passThru) { BRect bounds(Bounds()); BView* view; if (useOffscreen) { ASSERT(sOffscreen); BRect frame(bounds); frame.right += frame.left; // ToDo: this is kind of messy way of avoiding being clipped // by the amount the title is scrolled to the left view = sOffscreen->BeginUsing(frame); view->SetOrigin(-bounds.left, 0); view->SetLowColor(LowColor()); view->SetHighColor(HighColor()); BFont font; GetFont(&font); view->SetFont(&font); } else view = this; view->SetHighUIColor(B_PANEL_BACKGROUND_COLOR, B_DARKEN_2_TINT); view->StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); bounds.bottom--; rgb_color baseColor = ui_color(B_PANEL_BACKGROUND_COLOR); be_control_look->DrawButtonBackground(view, bounds, bounds, baseColor, 0, BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER); int32 count = fTitleList.CountItems(); float minx = bounds.right; float maxx = bounds.left; for (int32 index = 0; index < count; index++) { BColumnTitle* title = fTitleList.ItemAt(index); title->Draw(view, title == pressedColumn); BRect titleBounds(title->Bounds()); if (titleBounds.left < minx) minx = titleBounds.left; if (titleBounds.right > maxx) maxx = titleBounds.right; } bounds = Bounds(); minx--; view->SetHighUIColor(B_PANEL_BACKGROUND_COLOR, B_DARKEN_1_TINT); view->StrokeLine(BPoint(minx, bounds.top), BPoint(minx, bounds.bottom - 1)); #if !(APP_SERVER_CLEARS_BACKGROUND) FillRect(BRect(bounds.left, bounds.top + 1, minx - 1, bounds.bottom - 1), B_SOLID_LOW); FillRect(BRect(maxx + 1, bounds.top + 1, bounds.right, bounds.bottom - 1), B_SOLID_LOW); #endif if (useOffscreen) { if (trackRectBlitter) (trackRectBlitter)(view, passThru); view->Sync(); DrawBitmap(sOffscreen->Bitmap()); sOffscreen->DoneUsing(); } else if (trackRectBlitter) (trackRectBlitter)(view, passThru); }