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
Write a Guide / Tutorial #505
Comments
Hi, I know it's not super helpful to just make a request without offering to help, but would it worth considering adding discussion tuts around using conrod as the GUI layer while using lower-level (than piston) frameworks (like glium or gfx-rs) for actual graphics? That's my current situation. I'm using gfx-rs for the main graphics b/c im doing a 2d charmap/tilemap thing on a plane mesh + shader stuff. I would like to use piston for the GUI portion while taking on all the piston-idiomatic baggage (or taking it on the degree least neccesary.. eg how to use piston when i'm creating windows via raw glutin calls?). |
@olsonjeffery good point! I've edited the comment above with a 5th chapter. No problem btw, any ideas / requests are welcome 👍 |
I'm starting to use Conrod heavily on a real project, and I need it to be documented for possible future devs. So I was thinking I might just take a stab at this guide. What form should it take? A Markdown file? A web page? A wiki? |
@jarrett that would be great! Yeah I think a |
List of available widgets is outdated - Image widget added in #696. |
@Phlosioneer thanks, fixed in #731. |
Some broken link fixed #829 |
I'm newbie in rust and conrod (and github), however I wanted to help people on how to get started with conrod. I thought it could be usefull to document how I go along the bulletpoints here. I'm about to do a simple demoapp based on how things are layed out under 2) point. so far I have this code: I'm open to any suggestions! |
I think having a placeholder "hello world" example for the "Using Conrod" chapter would be great. I can't find a simple minimal example, and since that part of the guide is not written yet, and I don't seem to be able to figure it out on my own, I don't know where to start with this library. I feel like if I had that, I might be able to figure things out using the documentation from there. If anyone knows where I can find a minimal example like this, or want to add this to the "Using Conrod" chapter as a placeholder, that would be much appreciated. |
Okay, I have a simple little hello world, but what to do with it? Post it on github and link? I'm new to this open source practice. Also: is the guide somewhere on github? I haven't been able to find it easily, but that's not to say it isn't there. I'd like to have a go at 2 above - having spent a couple of days going through exactly the exercise that is envisaged for it. How should code be linked to the guide? I can put short examples in the text, but it might be useful to have all the code available too. |
@bobgates great, I really appreciate your interest in helping out with this! The guide is included within the conrod repo as doc-comments within a public module in the src repo - I think the first chapter should be a decent example of how to handle links etc, but just let us know if anything is unclear from that point.
Agreed! Perhaps we could have an |
Hello, a newb to conrod and rust here. It is a bit hard to figure out conrod using the examples alone. Specifically, it is difficult to differentiate what is and what isn't the boilerplate code. So, I propose a "Quick Start" chapter for the guide. That "Quick Start" chapter should contain the essential code which every conrod program would need to function - in other words a general use template. The template would explain what each region of the code is meant for and the comments in that template would also mark down where the rest of the program is placed according to conrod custom. Uses for reader:
|
@Ironmaggot perhaps this could be based around the |
@mitchmindtree I tried to use There are a couple of problems with Another section that I didn't know where to place was the section where the "juice" of the app should go. You know, the part of the app for which one builds the UI and how it should behave in relation to the other sections. In the example below, I wrote the Example of what a template could look like - Click to expand//! A simple example that demonstrates using conrod within a basic `winit` window loop, using
//! `glium` to render the `conrod::render::Primitives` to screen.
#[cfg(all(feature="winit", feature="glium"))] #[macro_use] extern crate conrod;
fn main() {
feature::main();
}
#[cfg(all(feature="winit", feature="glium"))]
mod feature {
use conrod::{self, widget, Colorable, Positionable, Widget};
use conrod::backend::glium::glium::{self, Surface};
pub fn main() {
/* GRAPHICS OPTIONS--------------------------------------------------------------------
Define window details here. If you have an .ini file where users can set preferences for
graphics options, this would be the place they are read and stored. Place here graphics
settings such as resolution, vsync on/off, multisampling level, etc. Contents of this
section will be used in INITIALIZATION PROCEDURES. */
const WIDTH: u32 = 400;
const HEIGHT: u32 = 200;
/* INITIALIZATION PROCEDURES--------------------------------------------
Following blocks of code build the necessary infrastructure for conrod's
functioning.*/
// Building the window
let mut events_loop = glium::glutin::EventsLoop::new();
let window = glium::glutin::WindowBuilder::new()
.with_title("Hello Conrod!")
.with_dimensions(WIDTH, HEIGHT);
let context = glium::glutin::ContextBuilder::new()
.with_vsync(true)
.with_multisampling(4);
let display = glium::Display::new(window, context, &events_loop).unwrap();
// construct our `Ui`.
let mut ui = conrod::UiBuilder::new([WIDTH as f64, HEIGHT as f64]).build();
// Generate the widget identifiers.
widget_ids!(struct Ids { text });
let ids = Ids::new(ui.widget_id_generator());
// Add a `Font` to the `Ui`'s `font::Map` from file.
const FONT_PATH: &'static str =
concat!(env!("CARGO_MANIFEST_DIR"), "/assets/fonts/NotoSans/NotoSans-Regular.ttf");
ui.fonts.insert_from_file(FONT_PATH).unwrap();
// A type used for converting `conrod::render::Primitives` into `Command`s that can be used
// for drawing to the glium `Surface`.
let mut renderer = conrod::backend::glium::Renderer::new(&display).unwrap();
// The image map describing each of our widget->image mappings (in our case, none).
let image_map = conrod::image::Map::<glium::texture::Texture2d>::new();
let mut events = Vec::new();
'render: loop {
/* RENDERING LOOP'S INFRASTRUCTURE--------------------------------------
Following code is the plumbing which should be present in every render loop
for conrod to function as intended. This section gets the events ready
for processing. (Needs some sort of laconic explanation WHY the things here
are the way they are.)*/
events.clear();
// Get all the new events since the last frame.
events_loop.poll_events(|event| { events.push(event); });
// If there are no new events, wait for one.
if events.is_empty() {
events_loop.run_forever(|event| {
events.push(event);
glium::glutin::ControlFlow::Break
});
}
// Process the events.
for event in events.drain(..) {
/* INPUT PROCESSING------------------------------------------------------
Use this section of the code to process the input. Add new matches here
for input as you develop functionality for them. This section's responsibility
should be to receive the input events and prepare them for "ui" event
handling. */
// Break from the loop upon `Escape` or closed window.
match event.clone() {
glium::glutin::Event::WindowEvent { event, .. } => {
match event {
glium::glutin::WindowEvent::Closed |
glium::glutin::WindowEvent::KeyboardInput {
input: glium::glutin::KeyboardInput {
virtual_keycode: Some(glium::glutin::VirtualKeyCode::Escape),
..
},
..
} => break 'render,
_ => (),
}
}
_ => (),
};
// Use the `winit` backend feature to convert the winit event to a conrod input.
let input = match conrod::backend::winit::convert_event(event, &display) {
None => continue,
Some(input) => input,
};
// Handle the input with the `Ui`.
ui.handle_event(input);
// Set the widgets.
let ui = &mut ui.set_widgets();
/* BUILDING OF THE USER INTERFACE-----------------------------------
This is the place where you write the code for the elements of your UI.
This section should be responsible for all your widgets, buttons,
primitives and text which will appear on the screen during the use. */
// "Hello World!" in the middle of the screen.
widget::Text::new("Hello World!")
.middle_of(ui.window)
.color(conrod::color::WHITE)
.font_size(32)
.set(ids.text, ui);
}
// Draw the `Ui` if it has changed.
if let Some(primitives) = ui.draw_if_changed() {
renderer.fill(&display, primitives, &image_map);
let mut target = display.draw();
target.clear_color(0.0, 0.0, 0.0, 1.0);
renderer.draw(&display, &mut target, &image_map).unwrap();
target.finish().unwrap();
}
}
}
}
#[cfg(not(all(feature="winit", feature="glium")))]
mod feature {
pub fn main() {
println!("This example requires the `winit` and `glium` features. \
Try running `cargo run --release --features=\"winit glium\" --example <example_name>`");
}
} |
Nice work @Ironmaggot! That helps clear some things up. I think that could serve as a good base, if we can just get one working template that can be used to build programs on with comments, that would be incredibly useful for people. I'm very interested in helping out with this. However, I'm in the same boat as you @Ironmaggot in that I don't know enough to build on that template. I would really appreciate some help from someone who knows this library better than I do. Even after starting on an app and having a functional UI, I'm having trouble expanding it because I don't understand how the library is structured. I'm currently reading Conrod code and trying to figure it all out, but if someone who knows more about this would be willing to point me towards where I can find good information/code about it, or write out the basic structure of how it all works, that would be very useful. Either way I will help write this tutorial that hopefully will unlock this library for other people in my situation. |
Conrod seems super nice, but is quite unusable due to its lack of a guide. I think |
I took the template that I've created for myself, rewrote, documented and uploaded it. |
Hey guys, I think it might be a good idea to use mdBook. It's what the Rust book is made in. |
Hello. I just found out about Conrod and I think it's pretty awesome! I'm going to use it for my next project, and contribute whatever I can. But for now, I just want to add to the discussion by saying what is it that I'm struggling with, as a beginner. I'm finding it really hard to understand the role of all the libraries and frameworks being used. The homepage and the introduction What is Conrod? mention a ton of them: winit, gfx, glium, piston, vulkano, glutin, sdl2, glfw, raw opengl... I'm sure all of those dependencies have their purpose, their pros and cons. I've been reading some of their documentation, just to understand if they fit my use case or not, but I'm far from having a complete picture. For example, in my case I'd like to write a cross-platform (Win / Mac / Linux X11) GUI program, to be used both as a standalone utility and as a VST plugin (different build targets.) I don't need 3D graphics, nor a game engine. What combination of backends should I choose? What about people who are developing games? I think a small chapter about backend selection would be of much use, written by somebody who already knows what all those libraries are, their pros and cons. Also, a short tip on how to use crate imports and/or feature flags to perform said selection would also be useful for us newbies. I'm still learning Rust and right now I can't figure out what piece of code is actually receiving the flags set by |
@derpmarine168 thank you. Some I had not seen before. I checked them all, here are my impressions:
I will write some code to get familiar with Conrod and Azul, to figure out which one fits my use case better. Thank you for your pointers! |
I managed to get a hello world to work. You can find the files for download, as well as an ugly writeup how I got there under lucidbrot/conrod-howto. The most helpful thing was when I discovered the guide hidden in the conrod_core source folder. It's worth pointing out that the linked third chapter is not yet linked in the README. Before you link it now, it is also worth pointing out that it is seemingly not entirely up to date or some things were missing. That may be a layer 8 problem, but perhaps it would need a rework. |
The Guide should probably be structured to look something like this:
App
struct with some dummy data.ui
function for the app.widget_ids!
macro(not yet implemented).Button
).Positionable
,Colorable
, etc traits (show where to find all available builder methods / traits for a widget in the docs).DropDownList
)Theme
sTheme
s.Theme
(load from json).Theme
(use in demo app from previous chapter).Theme
.Widget
traitButton
.Graph
and how each of the different types of IDs/indices relate to each other.render::Primitives
to draw to a custom backend.I think it'd make sense to do this in markdown for now (i.e. a
GUIDE.md
) but I'm open to any other suggestions 👍The text was updated successfully, but these errors were encountered: