Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scrolling refactoring and Bug fixes. Add Axis enum arg to Edge::Position in graph. #662

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b7951c9
Begin simplifcation of scroll.rs module. WIP (only implemented Y axis…
mitchmindtree Jan 8, 2016
e748f56
Update graph modules to store a Position edge for relative positionin…
mitchmindtree Jan 8, 2016
0cfefb7
Add Axis enum with X and Y variants, used within the graph Position e…
mitchmindtree Jan 8, 2016
edbb8c6
Update widget modules to simplification of scroll module. Change scro…
mitchmindtree Jan 8, 2016
e740795
Update backend/graphics draw_scrolling function to latest WIP scroll …
mitchmindtree Jan 8, 2016
cd274ee
Export new Axis position type
mitchmindtree Jan 8, 2016
37350e8
Provide methods for viewing the currently updated and previously upda…
mitchmindtree Jan 8, 2016
8e4e16b
Update examples to latest scroll method name changes, i.e. scrolling …
mitchmindtree Jan 8, 2016
18fa077
Re-add support for interactive scroll handle and track. Make Scroll g…
mitchmindtree Jan 9, 2016
d78fcfd
Fix doc so that rustc doesn't try to compile scroll ascii art
mitchmindtree Jan 9, 2016
ba9f464
Remove unnecessary scroll Interaction import
mitchmindtree Jan 9, 2016
0c37be0
Vastly simplify bounding_box calculation algorithm, refining the nece…
mitchmindtree Jan 9, 2016
9c7f08d
Update to newer, simplified kids_bounding_box graph algorithm
mitchmindtree Jan 9, 2016
69d5270
Use kid_area of previous update so that the bounding box calculated f…
mitchmindtree Jan 9, 2016
64a217e
Update scrolling ascii art docs with offset_bounds example. Add docs …
mitchmindtree Jan 9, 2016
46bd030
Attempt to build all_widgets example successfully on nightly by using…
mitchmindtree Jan 9, 2016
45594c5
Increment crates.io version for breaking changes.
mitchmindtree Jan 9, 2016
9e11a0b
Have scroll offset_bounds allow for the padding specified by the KidA…
mitchmindtree Jan 9, 2016
d7dbfea
Update all_widgets example to take advantage of new scroll offset_bou…
mitchmindtree Jan 9, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]

name = "conrod"
version = "0.28.0"
version = "0.29.0"
authors = [
"Mitchell Nordine <mitchell.nordine@gmail.com>",
"Sven Nilsen <bvssvni@gmail.com>"
Expand Down
32 changes: 25 additions & 7 deletions examples/all_widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use conrod::{
};
use conrod::color::{self, rgb};
use piston_window::{EventLoop, Glyphs, PistonWindow, UpdateEvent, WindowSettings};
use std::sync::mpsc;


type Ui = conrod::Ui<Glyphs>;
Expand Down Expand Up @@ -76,12 +77,16 @@ struct DemoApp {
circle_pos: Point,
/// Envelope for demonstration of EnvelopeEditor.
envelopes: Vec<(Vec<Point>, String)>,
/// A channel for sending results from the `WidgetMatrix`.
elem_sender: mpsc::Sender<(usize, usize, bool)>,
elem_receiver: mpsc::Receiver<(usize, usize, bool)>,
}

impl DemoApp {

/// Constructor for the Demonstration Application model.
fn new() -> DemoApp {
let (elem_sender, elem_receiver) = mpsc::channel();
DemoApp {
bg_color: rgb(0.2, 0.35, 0.45),
show_button: false,
Expand Down Expand Up @@ -114,6 +119,8 @@ impl DemoApp {
[0.3, 0.2],
[0.6, 0.6],
[1.0, 0.0], ], "Envelope B".to_string())],
elem_sender: elem_sender,
elem_receiver: elem_receiver,
}
}

Expand Down Expand Up @@ -173,11 +180,16 @@ fn main() {
fn set_widgets(ui: &mut Ui, app: &mut DemoApp) {

// We can use this `Canvas` as a parent Widget upon which we can place other widgets.
Canvas::new().frame(app.frame_width).color(app.bg_color).scrolling(true).set(CANVAS, ui);
Canvas::new()
.frame(app.frame_width)
.pad(30.0)
.color(app.bg_color)
.scroll_kids()
.set(CANVAS, ui);

// Text example.
Text::new("Widget Demonstration")
.top_left_with_margins_on(CANVAS, 25.0, app.title_pad)
.top_left_with_margins_on(CANVAS, 0.0, app.title_pad)
.font_size(32)
.color(app.bg_color.plain_contrast())
.set(TITLE, ui);
Expand All @@ -187,7 +199,7 @@ fn set_widgets(ui: &mut Ui, app: &mut DemoApp) {
// Button widget example button.
Button::new()
.w_h(200.0, 50.0)
.mid_left_with_margin_on(CANVAS, 30.0)
.mid_left_of(CANVAS)
.down_from(TITLE, 45.0)
.rgb(0.4, 0.75, 0.6)
.frame(app.frame_width)
Expand All @@ -212,7 +224,7 @@ fn set_widgets(ui: &mut Ui, app: &mut DemoApp) {
// Slider widget example slider(value, min, max).
Slider::new(pad as f32, 30.0, 700.0)
.w_h(200.0, 50.0)
.mid_left_with_margin_on(CANVAS, 30.0)
.mid_left_of(CANVAS)
.down_from(TITLE, 45.0)
.rgb(0.5, 0.3, 0.6)
.frame(app.frame_width)
Expand Down Expand Up @@ -327,14 +339,20 @@ fn set_widgets(ui: &mut Ui, app: &mut DemoApp) {
// You can return any type that implements `Widget`.
// The returned widget will automatically be positioned and sized to the matrix
// element's rectangle.
let elem = &mut app.bool_matrix[col][row];
Toggle::new(*elem)
let elem = app.bool_matrix[col][row];
let elem_sender = app.elem_sender.clone();
Toggle::new(elem)
.rgba(r, g, b, a)
.frame(app.frame_width)
.react(move |new_val: bool| *elem = new_val)
.react(move |new_val: bool| elem_sender.send((col, row, new_val)).unwrap())
})
.set(TOGGLE_MATRIX, ui);

// Receive updates to the matrix from the `WidgetMatrix`.
while let Ok((col, row, value)) = app.elem_receiver.try_recv() {
app.bool_matrix[col][row] = value;
}

// A demonstration using a DropDownList to select its own color.
let mut ddl_color = app.ddl_color;
DropDownList::new(&mut app.ddl_colors, &mut app.selected_idx)
Expand Down
2 changes: 1 addition & 1 deletion examples/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ fn set_widgets(ui: &mut Ui) {
(MIDDLE_COLUMN, Canvas::new().color(color::ORANGE)),
(RIGHT_COLUMN, Canvas::new().color(color::DARK_ORANGE).pad(20.0)),
])),
(FOOTER, Canvas::new().color(color::BLUE).vertical_scrolling(true)),
(FOOTER, Canvas::new().color(color::BLUE).scroll_kids_vertically()),
]).set(MASTER, ui);

// Now we'll make a couple floating `Canvas`ses.
Expand Down
93 changes: 48 additions & 45 deletions src/backend/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,29 @@ pub fn draw_from_graph<G, C>(context: Context,

// If the current widget is some scrollable widget, we need to add a context
// for it to the top of the stack.
if let Some(scrolling) = container.maybe_scrolling {
let context = crop_context(context, scrolling.visible);
//
// TODO: Make this more generic than just "if scrolling crop to kid_area".
if container.maybe_x_scroll_state.is_some()
|| container.maybe_y_scroll_state.is_some() {
let context = crop_context(context, container.kid_area.rect);
scroll_stack.push(context);
}
}
},

Visitable::Scrollbar(idx) => {
if let Some(scrolling) = graph.widget_scroll_state(idx) {
if let Some(widget) = graph.widget(idx) {

// Now that we've come across a scrollbar, we'll pop its Context from the
// scroll_stack and draw it if necessary.
let context = scroll_stack.pop().unwrap_or(context);

// Draw the scrollbar(s)!
draw_scrolling(&context, graphics, scrolling);
draw_scrolling(&context,
graphics,
widget.kid_area.rect,
widget.maybe_x_scroll_state,
widget.maybe_y_scroll_state);
}
}

Expand Down Expand Up @@ -174,10 +181,6 @@ pub fn draw_from_container<G, C>(context: &Context,
ShapeStyle::Fill(_) => {
let color = rectangle.style.get_color(theme);
draw_rectangle(context, graphics, container.rect, color);
// let (l, b, w, h) = container.rect.l_b_w_h();
// let lbwh = [l, b, w, h];
// let rectangle = graphics::Rectangle::new(color);
// rectangle.draw(lbwh, &context.draw_state, context.transform, graphics);
},
ShapeStyle::Outline(line_style) => {
let (l, r, b, t) = container.rect.l_r_b_t();
Expand Down Expand Up @@ -350,48 +353,48 @@ pub fn draw_lines<G, I>(context: &Context,
/// Draw the scroll bars (if necessary) for the given widget's scroll state.
pub fn draw_scrolling<G>(context: &Context,
graphics: &mut G,
scroll_state: &widget::scroll::State)
kid_area_rect: Rect,
maybe_x_scroll_state: Option<widget::scroll::StateX>,
maybe_y_scroll_state: Option<widget::scroll::StateY>)
where G: Graphics,
{
use widget::scroll;

let color = scroll_state.color;
let track_color = color.alpha(0.2);
let thickness = scroll_state.thickness;
let visible = scroll_state.visible;

let draw_bar = |g: &mut G, bar: scroll::Bar, track: Rect, handle: Rect| {
// We only want to see the scrollbar if it's highlighted or clicked.
if let scroll::Interaction::Normal = bar.interaction {
return;
}
let color = bar.interaction.color(color);
draw_rectangle(context, g, track, track_color);
draw_rectangle(context, g, handle, color);
};

// The element for a vertical scroll Bar.
let vertical = |g: &mut G, bar: scroll::Bar| {
let track = scroll::vertical_track(visible, thickness);
let handle = scroll::vertical_handle(&bar, track, scroll_state.total_dim[1]);
draw_bar(g, bar, track, handle);
};
fn draw_axis<G, A>(context: &Context,
graphics: &mut G,
kid_area_rect: Rect,
scroll_state: &scroll::State<A>)
where G: Graphics,
A: scroll::Axis,
{
use widget::scroll::Elem::{Handle, Track};
use widget::scroll::Interaction::{Highlighted, Clicked};

let color = scroll_state.color;
let track_color = match scroll_state.interaction {
Clicked(Track) => color.highlighted(),
Highlighted(_) | Clicked(_) => color,
_ if scroll_state.is_scrolling => color,
_ => return,
}.alpha(0.2);
let handle_color = match scroll_state.interaction {
Clicked(Handle(_)) => color.clicked(),
Highlighted(_) | Clicked(_) => color,
_ if scroll_state.is_scrolling => color,
_ => return,
};
let thickness = scroll_state.thickness;
let track = scroll::track::<A>(kid_area_rect, thickness);
let handle = scroll::handle::<A>(track, &scroll_state);
draw_rectangle(context, graphics, track, track_color);
draw_rectangle(context, graphics, handle, handle_color);
}

// An element for a horizontal scroll Bar.
let horizontal = |g: &mut G, bar: scroll::Bar| {
let track = scroll::horizontal_track(visible, thickness);
let handle = scroll::horizontal_handle(&bar, track, scroll_state.total_dim[0]);
draw_bar(g, bar, track, handle);
};
if let Some(ref scroll_state) = maybe_y_scroll_state {
draw_axis::<G, scroll::Y>(context, graphics, kid_area_rect, scroll_state)
}

// Whether we draw horizontal or vertical or both depends on our state.
match (scroll_state.maybe_vertical, scroll_state.maybe_horizontal) {
(Some(v_bar), Some(h_bar)) => {
horizontal(graphics, h_bar);
vertical(graphics, v_bar);
},
(Some(bar), None) => vertical(graphics, bar),
(None, Some(bar)) => horizontal(graphics, bar),
(None, None) => (),
if let Some(ref scroll_state) = maybe_x_scroll_state {
draw_axis::<G, scroll::X>(context, graphics, kid_area_rect, scroll_state)
}
}
Loading