PistonDevelopers / conrod

An easy-to-use, 2D GUI library written entirely in Rust.
Other
3.35k stars 296 forks source link

Write a Guide / Tutorial #505

Open mitchmindtree opened 9 years ago

mitchmindtree commented 9 years ago

The Guide should probably be structured to look something like this:

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 :+1:

olsonjeffery commented 9 years ago

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?).

mitchmindtree commented 9 years ago

@olsonjeffery good point! I've edited the comment above with a 5th chapter. No problem btw, any ideas / requests are welcome :+1:

jarrett commented 9 years ago

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?

mitchmindtree commented 9 years ago

@jarrett that would be great! Yeah I think a GUIDE.md at the top level is probably a good idea for now :+1: I'll add it to the top comment.

Phlosioneer commented 8 years ago

List of available widgets is outdated - Image widget added in #696.

mitchmindtree commented 8 years ago

@Phlosioneer thanks, fixed in #731.

enricostano commented 8 years ago

Some broken link fixed https://github.com/PistonDevelopers/conrod/pull/829

zen3ger commented 7 years ago

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: https://github.com/zen3ger/conrod-guessing_game

I'm open to any suggestions!

lukors commented 7 years ago

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.

bobgates commented 7 years ago

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.

mitchmindtree commented 7 years ago

@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 - conrod/src/guide/. This allows users to generate the guide from the src using cargo doc and also means we can use docs.rs for hosting it. It also means we can use cargo test to test the inline code examples.

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.

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.

Agreed! Perhaps we could have an examples/tutorial/ subdirectory with example names like examples/tutorial/hello_world_01.rs for each piece of code that is relevant to the hello world tutorial as an example. As a reference, I quite like the way glium does this by providing the updated source for each major step in the tutorial as 01.rs, 02.rs, etc.

Ironmaggot commented 7 years ago

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:

mitchmindtree commented 7 years ago

@Ironmaggot perhaps this could be based around the hello_world.rs example - I think it is probably the simplest example that doesn't use the support module.

Ironmaggot commented 7 years ago

@mitchmindtree I tried to use hello_world.rs example and tried to transform it into a "spiritual" representation of what I meant. I most probably got things wrong in this example, but I hope people can understand what I am trying to convey with this.

There are a couple of problems with hello_world.rs though. Most of the other examples seemed to have a separate "Ids" section. I take that such a section is necessary once the UI gets more complex than the hello_world.rs. I think that there should be a dedicated section for that in the template as well. Similarly, there should be sections for other things which become required once a program gets more complex. Although, due to my lack of knowledge about conrod, I can't think of any.

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 /* comments */. I don't know enough conrod to template'ify it more.

Example of what a template could look like - Click to expand ```rust //! 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::::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 `"); } } ```
lukors commented 6 years ago

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.

atoav commented 6 years ago

Conrod seems super nice, but is quite unusable due to its lack of a guide. The examples are nice to have, but the amount of boilerplate code is too high to be of good use for anybody who just wants to get started. For example it is totally unclear what you would need to import in your own because of all the feature flags etc.

I think 2. Using Conrod (to create a basic app GUI) is meant to adress this – sadly since I first checked out conrod (nearly 1,5 years ago), there has been no progress to this. Does this mean conrod is abandoned?

luleyleo commented 6 years ago

I took the template that I've created for myself, rewrote, documented and uploaded it. Maybe this helps a bit until someone finds the time (and motivation) to write the guide. https://github.com/Finnerale/conrod-boilerplate

JadedBlueEyes commented 5 years ago

Hey guys, I think it might be a good idea to use mdBook. It's what the Rust book is made in.

tobia commented 5 years ago

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 --features "winit glium" in the Build and run the examples page!

JadedBlueEyes commented 5 years ago

FYI, you should probably check out other crates, before you settle on any one. Some I've found include

tobia commented 5 years ago

@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!

lucidBrot commented 4 years ago

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.