GUI_Status GfxWidget::Select( short item ) { if ( item < 0 ) item = -1; else if ( item >= items ) item = items - 1; if ( item != current ) { short newtop = toprow; current = item; if ( current >= 0 ) { short selrow = (current/gfx_per_row) * ItemHeight(); if ( selrow < toprow ) newtop = selrow; else if ( selrow + ItemHeight() >= newtop + visrows ) newtop = selrow - visrows + ItemHeight(); } if ( toprow != newtop ) { static_cast<SliderWidget *>( GetWidget(0) )->ScrollTo( newtop ); } else { DrawItems(); Show(); } } if ( hook ) return hook->WidgetActivated( this, surface ); return GUI_OK; }
void GfxWidget::DrawItems( void ) { unsigned short row = toprow / ItemHeight(); unsigned short num = row * gfx_per_row; // first visible item short xoff = bounds.x, yoff = bounds.y + row * ItemHeight() - toprow, img; surface->DrawBack( bounds ); while ( (img = GetImage(num)) != -1 ) { if ( num == current ) { Rect hilite( xoff, yoff, gfx_w, ItemHeight() ); hilite.Clip( bounds ); surface->FillRectAlpha( hilite, surface->GetFGPen() ); } DrawItem( img, xoff, yoff ); xoff += gfx_w; if ( xoff + gfx_w >= bounds.x + bounds.w ) { xoff = bounds.x; yoff += ItemHeight(); if ( yoff >= bounds.y + bounds.h ) break; } ++num; } }
void GfxWidget::Init( unsigned short gfxw, unsigned short gfxh, unsigned short items ) { this->items = items; gfx_w = gfxw; gfx_h = gfxh; gfx_per_row = MAX( bounds.w/gfxw, 1 ); toprow = 0; rows = (items + gfx_per_row - 1) / gfx_per_row * ItemHeight(); visrows = MIN( bounds.h, rows ); current = -1; SliderWidget *slider = static_cast<SliderWidget *>( GetWidget(0) ); if ( slider ) { slider->Adjust( 0, rows - visrows, visrows ); slider->ScrollTo( 0 ); } else { // create the corresponding slider widget slider = new SliderWidget( 0, x + w - DEFAULT_SLIDER_SIZE, y, DEFAULT_SLIDER_SIZE, h, 0, rows - visrows, toprow, visrows, WIDGET_VSCROLL|WIDGET_COMPOSITE, NULL, surface ); slider->SetHook( this ); AddWidget( slider ); } init = true; }
GUI_Status GfxWidget::MouseDown( const SDL_MouseButtonEvent &button ) { SDL_MouseButtonEvent mybutton = button; if ( ((button.button == SDL_BUTTON_WHEELUP) || (button.button == SDL_BUTTON_WHEELDOWN)) && Contains( button.x - surface->LeftEdge(), button.y - surface->TopEdge() ) ) { // reroute all wheel events to the scroller SliderWidget *s = static_cast<SliderWidget *>( GetWidget(0) ); if ( s ) { mybutton.x = s->LeftEdge() + surface->LeftEdge(); mybutton.y = s->TopEdge() + surface->TopEdge(); } } GUI_Status rc = CompositeWidget::MouseDown( mybutton ); if ( (rc == GUI_OK) && (button.button == SDL_BUTTON_LEFT) ) { short mx = button.x - surface->LeftEdge(); short my = button.y - surface->TopEdge(); if ( bounds.Contains( mx, my ) && (mx < bounds.x + gfx_per_row * gfx_w) ) { short col = (mx - bounds.x) / gfx_w; short row = (my - bounds.y + toprow) / ItemHeight(); short item = row * gfx_per_row + col; if ( item < items ) return Select( item ); } } return rc; }
void ScrolledListView::Draw(BRect updateRect) { // figure out which items we're drawing float itemHeight = ItemHeight(); int32 firstItem = (int) (updateRect.top / itemHeight); if (firstItem < 0) firstItem = 0; int32 lastItem = (int) ((updateRect.bottom + itemHeight - 1) / itemHeight); int32 numItems = NumItems(); if (lastItem >= numItems) lastItem = numItems - 1; // draw BRect itemRect = Bounds(); itemRect.top = firstItem * itemHeight; itemRect.bottom = itemRect.top + itemHeight - 1; for (int32 i=firstItem; i <= lastItem; i++) { // draw item DrawItem(i, itemRect, i == selection); // bump itemRect itemRect.top = itemRect.bottom + 1; itemRect.bottom = itemRect.top + itemHeight - 1; } // clear any left-over area if (itemRect.top < updateRect.bottom) { itemRect.bottom = updateRect.bottom; FillRect(itemRect, B_SOLID_LOW); } }
GUI_Status ListWidget::MouseDown( const SDL_MouseButtonEvent &button ) { SDL_MouseButtonEvent mybutton = button; if ( ((button.button == SDL_BUTTON_WHEELUP) || (button.button == SDL_BUTTON_WHEELDOWN)) && Contains( button.x - surface->LeftEdge(), button.y - surface->TopEdge() ) ) { // reroute all wheel events to the scroller SliderWidget *s = static_cast<SliderWidget *>( GetWidget(0) ); if ( s ) { mybutton.x = s->LeftEdge() + surface->LeftEdge(); mybutton.y = s->TopEdge() + surface->TopEdge(); } } GUI_Status rc = CompositeWidget::MouseDown( mybutton ); if ( (rc == GUI_OK) && (button.button == SDL_BUTTON_LEFT) ) { short mx = button.x - surface->LeftEdge(); short my = button.y - surface->TopEdge(); Rect sensitive( x + 2, y + spacing, listboxw - 4, h - 2 * spacing ); if ( sensitive.Contains( mx, my ) ) { short item = (my - y - spacing - 1 + toprow) / ItemHeight(); if ( (item < nodes) ) return Select( item ); } } return rc; }
void ScrolledListView::DrawItemAt(int32 index) { float itemHeight = ItemHeight(); BRect itemRect = Bounds(); itemRect.top = index * itemHeight; itemRect.bottom = itemRect.top + itemHeight - 1; DrawItem(index, itemRect, (index == selection)); }
void ScrolledListView::InvalidateItem(int index) { float itemHeight = ItemHeight(); BRect itemRect = Bounds(); itemRect.top = index * itemHeight; itemRect.bottom = itemRect.top + itemHeight - 1; Invalidate(itemRect); }
int ScrolledListView::TrackInsertionStep(BPoint point, int prevInsertionIndex) { BRect bounds = Bounds(); float itemHeight = ItemHeight(); int32 numItems = NumItems(); // autoscroll if (point.y < bounds.top) { if (bounds.top > 0) { ScrollBy(0, -itemHeight); bounds.OffsetBy(0, -itemHeight); } point.y = bounds.top; } else if (point.y > bounds.bottom) { if (bounds.bottom < numItems * itemHeight - 1) { ScrollBy(0, itemHeight); bounds.OffsetBy(0, itemHeight); } point.y = bounds.bottom + 1; // need the +1 to let it get beyond the last item } // figure out where it is now int32 curInsertionIndex = (int) (point.y / itemHeight); if (curInsertionIndex < 0) curInsertionIndex = 0; else if (curInsertionIndex > numItems) // can move beyond the last item curInsertionIndex = numItems; // draw if (curInsertionIndex != prevInsertionIndex) { // redraw items bordering old indicator, to clear it if (prevInsertionIndex >= 0) { if (prevInsertionIndex > 0) DrawItemAt(prevInsertionIndex - 1); if (prevInsertionIndex < numItems) DrawItemAt(prevInsertionIndex); else { // need to clean up bottom BRect bottomRect = bounds; bottomRect.top = prevInsertionIndex * itemHeight; FillRect(bottomRect, B_SOLID_LOW); } } // draw new indicator SetHighColor(insertionIndicatorColor); SetPenSize(2.0); float indicatorY = curInsertionIndex * itemHeight; StrokeLine(BPoint(bounds.left, indicatorY), BPoint(bounds.right, indicatorY)); SetPenSize(1.0); } Flush(); return curInsertionIndex; }
void ListWidget::Update( void ) { nodes = list->CountNodes(); if ( current >= nodes ) { current = nodes - 1; if ( hook ) hook->WidgetActivated( this, surface ); } rows = ItemHeight() * nodes + 2 * spacing + 2; visrows = h - 2 * spacing - 2; if ( visrows > rows ) { visrows = rows; toprow = 0; } else if ( visrows > rows - toprow ) { toprow = rows - visrows; } else if ( current != -1 ) { short selrow = 1 + spacing + current * ItemHeight(); if ( selrow < toprow ) toprow = selrow; else if ( selrow + ItemHeight() >= toprow + visrows ) toprow = selrow - visrows + ItemHeight(); } SliderWidget *slider = static_cast<SliderWidget *>( GetWidget(0) ); if ( rows > visrows ) { if ( slider ) slider->Adjust( 0, rows - visrows, visrows ); else { // create the corresponding slider widget slider = new SliderWidget( 0, x + w - DEFAULT_SLIDER_SIZE, y, DEFAULT_SLIDER_SIZE, h, 0, rows - visrows, toprow, visrows, WIDGET_VSCROLL | WIDGET_COMPOSITE | (flags & WIDGET_HSCROLLKEY ? 0 : WIDGET_HSCROLLKEY) | (flags & WIDGET_VSCROLLKEY ? 0 : WIDGET_VSCROLLKEY), NULL, surface ); slider->SetHook( this ); listboxw = w - DEFAULT_SLIDER_SIZE; // adjust list box size AddWidget( slider ); } } else if ( slider ) { // delete the slider; we don't need it any more listboxw += slider->Width(); // adjust list box size RemoveWidget( slider ); delete slider; } }
FileList::FileList() { iconwidth = DPI(16); ItemHeight(max(Draw::GetStdFontCy(), DPI(17))); Ctrl::Add(edit); edit.Hide(); edit.SetFrame(BlackFrame()); renaming = false; justname = false; accelkey = false; selectdir = false; SetDisplay(*this); }
void ScrolledListView::ScrollToSelection() { if (selection < 0) return; // see if the selected item is already visible float itemHeight = ItemHeight(); BRect bounds = Bounds(); int32 firstItem = (int) (bounds.top / itemHeight); int32 lastItem = (int) (bounds.bottom / itemHeight); if (selection >= firstItem && selection <= lastItem) return; // scroll ScrollTo(0, selection * itemHeight); }
void ScrolledListView::UpdateScrollBar() { // sanity clause if (scroller == NULL) return; BScrollBar* scrollBar = scroller->ScrollBar(B_VERTICAL); float itemHeight = ItemHeight(); float visibleHeight = Bounds().Height() + 1; float dataHeight = NumItems() * itemHeight; float scrollMax = dataHeight - visibleHeight; if (scrollMax < 0) scrollMax = 0; scrollBar->SetRange(0, scrollMax); scrollBar->SetSteps(itemHeight, visibleHeight - itemHeight); }
void ScrolledListView::MouseDown(BPoint point) { int32 clicks; Window()->CurrentMessage()->FindInt32("clicks", &clicks); Activate(); if (!IsFocus()) MakeFocus(); int32 newSelection = (int) (point.y / ItemHeight()); if (newSelection < 0 || newSelection >= NumItems()) newSelection = -1; // double-click opens if (selection == newSelection && selection >= 0 && clicks > 1) OpenSelectedItem(selection); // first click selects, maybe moves else { Select(newSelection); if (CanRearrange()) TrackRearrangement(point); } }
void ScrolledListView::KeyDown(const char* bytes, int32 numBytes) { switch (bytes[0]) { case B_ENTER: case ' ': if (selection >= 0) OpenSelectedItem(selection); break; case B_UP_ARROW: int32 newSelection; if (selection < 0) newSelection = NumItems() - 1; else if (selection > 0) newSelection = selection - 1; else newSelection = selection; Select(newSelection); ScrollToSelection(); break; case B_DOWN_ARROW: if (selection < NumItems() - 1) Select(selection + 1); ScrollToSelection(); break; case B_PAGE_UP: { float itemHeight = ItemHeight(); float visibleHeight = Bounds().Height() + 1; ScrollBy(0, -(visibleHeight - itemHeight)); } break; case B_PAGE_DOWN: { float itemHeight = ItemHeight(); float visibleHeight = Bounds().Height() + 1; ScrollBy(0, visibleHeight - itemHeight); } break; case B_HOME: ScrollTo(0, 0); break; case B_END: { float visibleHeight = Bounds().Height(); ScrollTo(0, NumItems() * ItemHeight() - visibleHeight); } break; case B_BACKSPACE: case B_DELETE: if (selection >= 0) RemoveSelectedItem(selection); break; default: BView::KeyDown(bytes, numBytes); break; } }