Open suhr opened 7 years ago
Ping. If conrod doesn't have this, tell at least how should I do scrolling for now.
Calling Widget::scroll_kids
, Widget::scroll_kids_vertically
or Widget::scroll_kids_horizontally
on a widget will make that widget into a scrollable view for all children of that widget. E.g.
widget::Canvas::new().scroll_kids_vertically().set(CANVAS, ui);
widget::Button::new().parent(CANVAS).set(BUTTON, ui);
// other child widgets
This would create a Canvas
which acts as a scrollable container for the Button
and other child widgets.
You can also instantiate a Scrollbar
widget for manually scrolling widgets that have scrolling enabled:
widget::Scrollbar::y_axis(CANVAS).autohide(true).set(SCROLLBAR, ui);
The canvas.rs
example demonstrates these parts of scrolling.
I'm still not sure if I'm happy with the current design for scrolling, as allowing any widget to opt-in to scrolling can seem quite ambiguous. I've been wondering if we should instead create a ScrollArea
/ScrollView
widget which returns a widget::Id
for a surface upon which child widgets can be placed and scrolled. Something like this might allow scrolling to be moved out of conrod's core and into the widget space, and would also make the widget::CommonBuilder
state a little lighter.
Anyway, hope this helps!
PS: it would be nice to have it scaleable, so when the view becomes smaller, displayed widgets become larger/more spaced.
This has crossed my mind too and would certainly be nice. I don't have any plans to implement this myself, but would be happy to see it implemented and will keep it in mind.
To be honest, I don't quite understand how exactly Scrollbar
scrolls Canvas
.
I want to scroll my piano roll by dragging it, not by using scrollbars.
@suhr when setting a Scrollbar
, a widget::Id
of a scrollable widget must be given. The scrollbar is then able to scroll that widget by calling the Ui::scroll_widget method.
If you'd prefer to scroll your timeline by dragging it, you could check for left mouse button drag events on your timeline and scroll the scrollable parent widget accordingly via the Ui::scroll_widget method.
Does this help?
Does this help?
Will try it out.
Well, for some reason this doesn't seem to work:
fn update(mut self, args: widget::UpdateArgs<Self>) -> Self::Event {
let widget::UpdateArgs { id, state, rect, mut ui, style, .. } = args;
widget::Canvas::new()
.color(color::rgb_bytes(0x26, 0x32, 0x38))
.scroll_kids()
.set(state.ids.canvas, ui);
let (y0, dy) = (rect.y.start, (rect.y.end - rect.y.start) / 93.0);
let (x0, x1) = (rect.x.start, rect.x.end);
if state.ids.lines.len() < 248 {
state.update(|state| state.ids.lines.resize(248, &mut ui.widget_id_generator()));
}
for (i, &line_id) in state.ids.lines.iter().enumerate() {
let y = y0 + (i as f64) * dy;
widget::Line::new([x0, y], [x1, y])
.solid()
.thickness(1.0)
.color(color::rgb_bytes(0x54, 0x6E, 0x7A))
.middle_of(state.ids.canvas)
.graphics_for(id)
.set(line_id, ui);
}
let mut scroll_dxy = [0.0, 0.0];
for ev in ui.widget_input(id).events() {
use conrod::{event, input};
match ev {
event::Widget::Drag(drag) if drag.button == input::MouseButton::Left => {
scroll_dxy[0] += drag.delta_xy[0];
scroll_dxy[1] += drag.delta_xy[1];
},
_ => (),
}
}
if scroll_dxy != [0.0, 0.0] {
self.scroll[0] += scroll_dxy[0];
self.scroll[1] += scroll_dxy[1];
ui.scroll_widget(state.ids.canvas, self.scroll)
}
}
Even though ui.scroll_widget
is called, lines doesn't move on drag.
Like in SFML.
I found conrod::widget::scroll, but it is not quite clear how to use it.
PS: it would be nice to have it scaleable, so when the view becomes smaller, displayed widgets become larger/more spaced.