conrod
conrod copied to clipboard
Code in guide not working
I am following the guide at: https://docs.rs/conrod_core/0.69.0/conrod_core/guide/chapter_3/index.html.
There is a part where it says:
Not quite what we want, yet.
Up until that point, my code is:
#[macro_use] extern crate conrod;
extern crate find_folder;
use glium::Display;
use glium::glutin::{ContextBuilder, WindowBuilder, EventsLoop};
use glium::texture::Texture2d;
use conrod::backend::glium::glium::{self, Surface};
use conrod::backend::glium::Renderer;
use conrod::UiBuilder;
use conrod::{widget, Positionable, Colorable, Widget};
fn main() {
// boilerplate for creating a window
const WIDTH: u32 = 400;
const HEIGHT: u32 = 200;
// The EventsLoop is given to the Display.
let mut events_loop = EventsLoop::new();
let window = WindowBuilder::new().with_title("Hello Conrod").with_dimensions(WIDTH, HEIGHT);
let context = ContextBuilder::new().with_vsync(true); //.with_multisampling(4); // multisampling does not work (NoAvailablePixelFormat)
let display = Display::new(window, context, &events_loop).unwrap();
// create the UI
// UiBuilder receives the dimensions in its constuctor.
let mut ui = UiBuilder::new([WIDTH as f64, HEIGHT as f64]).build();
// load fonts
let assets = find_folder::Search::KidsThenParents(3, 5)
.for_folder("assets")
.unwrap();
let font_path = assets.join("fonts/MesloLGM-Regular.ttf");
ui.fonts.insert_from_file(font_path).unwrap();
// after building the ui we can add widgets. define a widget named text and
// keep track of it, so that it later can be given an id.
widget_ids!(struct Ids { text });
// generate all ids
let ids = Ids::new(ui.widget_id_generator());
// system needs this
let image_map = conrod::image::Map::<Texture2d>::new();
// conrod needs renderer
let mut renderer = Renderer::new(&display).unwrap();
// the main event loop
'main: loop {
// instantiate the widgets
let ui = &mut ui.set_widgets();
widget::Text::new("Hello World!")
.middle_of(ui.window)
.color(conrod::color::WHITE)
.font_size(32)
.set(ids.text, ui);
// Render the `Ui` and then display it on the screen.
if let Some(primitives) = ui.draw_if_changed() {
renderer.fill(&display, primitives, &image_map);
let mut target = display.draw();
target.clear_color(0.0, 1.0, 0.0, 1.0);
renderer.draw(&display, &mut target, &image_map).unwrap();
target.finish().unwrap();
}
}
}
However, Rust complains, that it cannot borrow mutable the ui in the main loop at ui.draw_if_changed():
cannot borrow data in a dereference of `conrod::UiCell<'_>` as mutable (cannot borrow as mutable) [E0596]
trait `DerefMut` is required to modify through a dereference, but it is not implemented for `conrod::UiCell<'_>` [E0596]
My dependencies are:
[dependencies]
conrod = {version="0.55.0", features=["glium", "winit"]}
find_folder = "0.3.0"
My Rust version is:
$ rustc --version
rustc 1.41.1 (f3e1a954d 2020-02-24)
Is the guide outdated, or am I doing something wrong?
AFAIK you're supposed to do this in a separate stack layer like this:
// the main event loop
'main: loop {
// instantiate the widgets
{
let ui = &mut ui.set_widgets();
widget::Text::new("Hello World!")
.middle_of(ui.window)
.color(conrod::color::WHITE)
.font_size(32)
.set(ids.text, ui);
}
// Render the `Ui` and then display it on the screen.
if let Some(primitives) = ui.draw_if_changed() {
renderer.fill(&display, primitives, &image_map);
let mut target = display.draw();
target.clear_color(0.0, 1.0, 0.0, 1.0);
renderer.draw(&display, &mut target, &image_map).unwrap();
target.finish().unwrap();
}
}
If it were in a separate scope like that, wouldn't it go out of scope and therefore not be usable in the next statement?
When you call .set on the widget builder it sets it for the mutable UI reference above.
Ah. That makes sense. 👍