I'm trying to write code using conrod with a winit/glium backend. Conrod is an intermediate mode graphical user interface library for Rust while wininit provides an event model and glium the OpenGL bindings.
My code draws a grid of values onto a screen with a (row,col), i.e. "text1" at (0,0), "text2", (1,0), "text3" at (0,1) etc. where (row,col) is translated to an absolute (x,y) coordinate.
Basic flow is this:
- For each value I want to render as text
- Calculate the column / row of the value, i.e. (idx % num_cols, idx / num_cols)
- Calculate an x and y from the column and row. i.e. (col * WIDTH, ROW * HEIGHT).
- Create a widget::Text at (x, y) containing the value
The code that does this is shown below in a slightly simplified form. The entire file is online here.
This should be simple code to implement but when I run it, the text boxes are not drawn from x=0, y=0 but instead somewhere but not exactly offset from the centre of the view in both axes.
As far as I can tell this shouldn't happen because I am explicitly setting the absolute position and have confirmed the coordinates are correct. So I would expect them to render from the top left of the screen. I don't understand what causes the offset.
Any ideas?
The code that calculates position is this:
fn draw_ui(ui: &mut Ui, model: &mut UiModel) {
let ui = &mut ui.set_widgets();
// Canvas is the backdrop to the view
widget::Canvas::new()
.color(BACKGROUND_COLOUR)
.set(model.static_ids.canvas, ui);
// Create text widgets for each value
let state = model.session_state.read().unwrap();
// Create / update the widgets
if state.values.is_empty() {
// ... removed
} else {
let num_cols: usize = 2;
state.values.iter().enumerate().for_each(|(i, v)| {
// Create / update the cell and its state
let (node_id, value) = v;
if let Some(id) = model.value_ids.get(node_id) {
let (col, row) = (i % num_cols, i / num_cols);
let valid = value.is_valid();
let value = if let Some(ref value) = value.value {
value.to_string()
} else {
"None".to_string()
};
// Turn the value into a string to render it
let (x, y) = (col as f64 * (CELL_WIDTH + PADDING), row as f64 * (CELL_HEIGHT + PADDING));
value_widget(&value, valid, x, y, CELL_WIDTH, CELL_HEIGHT, model.static_ids.canvas)
.set(*id, ui);
}
});
}
}
fn value_widget(value: &str, valid: bool, x: f64, y: f64, w: f64, h: f64, canvas_id: conrod::widget::Id) -> widget::Text {
let color = if valid { GOOD_COLOUR } else { BAD_COLOUR };
widget::Text::new(value)
.x_y(x, y)
.w(w).h(h)
.color(color)
}