/src/

hl opt">.GUIEvent.Element = nullptr; e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; Parent->OnEvent(e); return true; } break; case EMIE_LMOUSE_PRESSED_DOWN: { if (is_inside) { is_dragging = true; dragged_by_slider = slider_rect.isPointInside(p); core::vector2di corner = slider_rect.UpperLeftCorner; drag_offset = is_horizontal ? p.X - corner.X : p.Y - corner.Y; tray_clicked = !dragged_by_slider; if (tray_clicked) { const s32 new_pos = getPosFromMousePos(p); const s32 old_pos = scroll_pos; setPos(new_pos); // drag in the middle drag_offset = thumb_size / 2; // report the scroll event if (scroll_pos != old_pos && Parent) { SEvent e; e.EventType = EET_GUI_EVENT; e.GUIEvent.Caller = this; e.GUIEvent.Element = nullptr; e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; Parent->OnEvent(e); } } Environment->setFocus(this); return true; } break; } case EMIE_LMOUSE_LEFT_UP: case EMIE_MOUSE_MOVED: { if (!event.MouseInput.isLeftPressed()) is_dragging = false; if (!is_dragging) { if (event.MouseInput.Event == EMIE_MOUSE_MOVED) break; return is_inside; } if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) is_dragging = false; // clang-format off if (!dragged_by_slider) { if (is_inside) { dragged_by_slider = slider_rect.isPointInside(p); tray_clicked = !dragged_by_slider; } if (!dragged_by_slider) { tray_clicked = false; if (event.MouseInput.Event == EMIE_MOUSE_MOVED) return is_inside; } } // clang-format on const s32 new_pos = getPosFromMousePos(p); const s32 old_pos = scroll_pos; setPos(new_pos); if (scroll_pos != old_pos && Parent) { SEvent e; e.EventType = EET_GUI_EVENT; e.GUIEvent.Caller = this; e.GUIEvent.Element = nullptr; e.GUIEvent.EventType = EGET_SCROLL_BAR_CHANGED; Parent->OnEvent(e); } return is_inside; } default: break; } } break; default: break; } } return IGUIElement::OnEvent(event); } void GUIScrollBar::draw() { if (!IsVisible) return; IGUISkin *skin = Environment->getSkin(); if (!skin) return; video::SColor icon_color = skin->getColor( isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); if (icon_color != current_icon_color) refreshControls(); slider_rect = AbsoluteRect; skin->draw2DRectangle(this, skin->getColor(EGDC_SCROLLBAR), slider_rect, &AbsoluteClippingRect); if (core::isnotzero(range())) { if (is_horizontal) { slider_rect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + draw_center - thumb_size / 2; slider_rect.LowerRightCorner.X = slider_rect.UpperLeftCorner.X + thumb_size; } else { slider_rect.UpperLeftCorner.Y = AbsoluteRect.UpperLeftCorner.Y + draw_center - thumb_size / 2; slider_rect.LowerRightCorner.Y = slider_rect.UpperLeftCorner.Y + thumb_size; } skin->draw3DButtonPaneStandard(this, slider_rect, &AbsoluteClippingRect); } IGUIElement::draw(); } void GUIScrollBar::updateAbsolutePosition() { IGUIElement::updateAbsolutePosition(); refreshControls(); setPos(scroll_pos); } s32 GUIScrollBar::getPosFromMousePos(const core::position2di &pos) const { s32 w, p; s32 offset = dragged_by_slider ? drag_offset : thumb_size / 2; if (is_horizontal) { w = RelativeRect.getWidth() - border_size * 2 - thumb_size; p = pos.X - AbsoluteRect.UpperLeftCorner.X - border_size - offset; } else { w = RelativeRect.getHeight() - border_size * 2 - thumb_size; p = pos.Y - AbsoluteRect.UpperLeftCorner.Y - border_size - offset; } return core::isnotzero(range()) ? s32(f32(p) / f32(w) * range() + 0.5f) + min_pos : 0; } void GUIScrollBar::setPos(const s32 &pos) { s32 thumb_area = 0; s32 thumb_min = 0; if (is_horizontal) { thumb_min = RelativeRect.getHeight(); thumb_area = RelativeRect.getWidth() - border_size * 2; } else { thumb_min = RelativeRect.getWidth(); thumb_area = RelativeRect.getHeight() - border_size * 2; } if (is_auto_scaling) thumb_size = s32(thumb_area / (f32(page_size) / f32(thumb_area + border_size * 2))); thumb_size = core::s32_clamp(thumb_size, thumb_min, thumb_area); scroll_pos = core::s32_clamp(pos, min_pos, max_pos); f32 f = core::isnotzero(range()) ? (f32(thumb_area) - f32(thumb_size)) / range() : 1.0f; draw_center = s32((f32(scroll_pos - min_pos) * f) + (f32(thumb_size) * 0.5f)) + border_size; } void GUIScrollBar::setSmallStep(const s32 &step) { small_step = step > 0 ? step : 10; } void GUIScrollBar::setLargeStep(const s32 &step) { large_step = step > 0 ? step : 50; } void GUIScrollBar::setMax(const s32 &max) { max_pos = max; if (min_pos > max_pos) min_pos = max_pos; bool enable = core::isnotzero(range()); up_button->setEnabled(enable); down_button->setEnabled(enable); setPos(scroll_pos); } void GUIScrollBar::setMin(const s32 &min) { min_pos = min; if (max_pos < min_pos) max_pos = min_pos; bool enable = core::isnotzero(range()); up_button->setEnabled(enable); down_button->setEnabled(enable); setPos(scroll_pos); } void GUIScrollBar::setPageSize(const s32 &size) { page_size = size; setPos(scroll_pos); } void GUIScrollBar::setArrowsVisible(ArrowVisibility visible) { arrow_visibility = visible; refreshControls(); } s32 GUIScrollBar::getPos() const { return scroll_pos; } void GUIScrollBar::refreshControls() { IGUISkin *skin = Environment->getSkin(); IGUISpriteBank *sprites = nullptr; current_icon_color = video::SColor(255, 255, 255, 255); if (skin) { sprites = skin->getSpriteBank(); current_icon_color = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL); } if (is_horizontal) { s32 h = RelativeRect.getHeight(); border_size = RelativeRect.getWidth() < h * 4 ? 0 : h; if (!up_button) { up_button = Environment->addButton( core::rect<s32>(0, 0, h, h), this); up_button->setSubElement(true); up_button->setTabStop(false); } if (sprites) { up_button->setSpriteBank(sprites); up_button->setSprite(EGBS_BUTTON_UP, s32(skin->getIcon(EGDI_CURSOR_LEFT)), current_icon_color); up_button->setSprite(EGBS_BUTTON_DOWN, s32(skin->getIcon(EGDI_CURSOR_LEFT)), current_icon_color); } up_button->setRelativePosition(core::rect<s32>(0, 0, h, h)); up_button->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); if (!down_button) { down_button = Environment->addButton( core::rect<s32>(RelativeRect.getWidth() - h, 0, RelativeRect.getWidth(), h), this); down_button->setSubElement(true); down_button->setTabStop(false); } if (sprites) { down_button->setSpriteBank(sprites); down_button->setSprite(EGBS_BUTTON_UP, s32(skin->getIcon(EGDI_CURSOR_RIGHT)), current_icon_color); down_button->setSprite(EGBS_BUTTON_DOWN, s32(skin->getIcon(EGDI_CURSOR_RIGHT)), current_icon_color); } down_button->setRelativePosition( core::rect<s32>(RelativeRect.getWidth() - h, 0, RelativeRect.getWidth(), h)); down_button->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT); } else { s32 w = RelativeRect.getWidth();