Rust-Conrod/: conrod — An easy-to-use, immediate-mode, 2D GUI library written entirely in Rust

Conrod Build Status Crates.io

An easy-to-use, 2D GUI library written entirely in Rust.

Guide

  1. What is Conrod?
  2. Getting Started
  3. Let's Create a GUI
    • Setup a Basic Window (using piston_window)
    • Conrod Setup
    • Instantiating Widgets
    • Widget Positioning and Layout
  4. Using and Customising Themes
    • What is a Theme?
    • Custom Themes
    • Serializing Themes
  5. Designing Custom Widgets (using the Widget trait)
    • The Widget trait
    • The widget_style! macro
    • The builder_methods! macro
    • Making a Button widget
  6. Custom Graphics and Window Backends
    • Demonstration of Backend Implementation (using glium and glutin)
  7. Internals
    • The Ui's Widget Graph
    • Ui::set_widgets - How does it work?
  8. FAQ

The Guide is a work-in-progress. If a section is not linked, it is likely not yet implemented.

Crates

Crate Badges Description
conrod_core Crates.io docs.rs The fundamentals for any conrod project.
conrod_derive Crates.io docs.rs Provides the WidgetCommon and WidgetStyle derive macros.
conrod_winit Crates.io docs.rs Simplifies using conrod_core with winit
conrod_gfx Crates.io docs.rs Simplifies using conrod_core with the gfx ecosystem
conrod_glium Crates.io docs.rs Simplifies using conrod_core with glium
conrod_piston Crates.io docs.rs Simplifies using conrod_core with piston
conrod_vulkano Crates.io docs.rs Simplifies using conrod_core with vulkano

Current State

We're just starting to reach a stable-ish API pattern! There will still be some large changes, however these are more likely to be new features than API overhauls.

To get a clearer idea of where we're at see the issues and in particular, the 1.0.0 milestone.

Contributing

Want to help out? See Piston's how to contribute guide.

License

Licensed under either of

at your option.

Contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Example Assets

Comments

  • Alpha chanel causes transparent window with glium backend under Wayland
    Alpha chanel causes transparent window with glium backend under Wayland

    Apr 30, 2020

    I believe this is related to https://github.com/glium/glium/issues/1678. I'm absolutely not familiar with how OpenGL surfaces should interact with Wayland, but what I gathered is that the resulting alpha channel will affect the compositing of the window.

    The glium backend uses the glium::Blend::alpha_blending() alpha blending function (https://github.com/PistonDevelopers/conrod/blob/351367ea0e55d2d92ba054777daf1801252d8bf0/backends/conrod_glium/src/lib.rs#L294) in which the alpha channel is calculated by srcAlpha * srcAlpha + dstAlpha * (1 - srcAlpha) (https://github.com/glium/glium/blob/776413b4eb8da16a4e9801feb27754e400e7d25a/src/draw_parameters/blend.rs#L28). To me this seems really wrong. I believe the usual way of combining the alpha channels is srcAlpha + dstAlpha * (1 - srcAlpha), which means the code should be changed into this:

    diff --git a/backends/conrod_glium/src/lib.rs b/backends/conrod_glium/src/lib.rs
    index d58bd56..8e2d7eb 100644
    --- a/backends/conrod_glium/src/lib.rs
    +++ b/backends/conrod_glium/src/lib.rs
    @@ -291,7 +291,18 @@ pub fn program<F>(facade: &F) -> Result<glium::Program, glium::program::ProgramC
     
     /// Default glium `DrawParameters` with alpha blending enabled.
     pub fn draw_parameters() -> glium::DrawParameters<'static> {
    -    let blend = glium::Blend::alpha_blending();
    +    use glium::{Blend, BlendingFunction, LinearBlendingFactor};
    +    let blend = Blend {
    +        color: BlendingFunction::Addition {
    +            source: LinearBlendingFactor::SourceAlpha,
    +            destination: LinearBlendingFactor::OneMinusSourceAlpha,
    +        },
    +        alpha: BlendingFunction::Addition {
    +            source: LinearBlendingFactor::One,
    +            destination: LinearBlendingFactor::OneMinusSourceAlpha,
    +        },
    +        constant_value: (0.0, 0.0, 0.0, 0.0),
    +    };
         glium::DrawParameters { multisampling: true, blend: blend, ..Default::default() }
     }
     
    
    

    However I do wonder if this should be fixed in glium by changing glium::Blend::alpha_blending().

    The new blending function matches that of of the wgpu backend, which does not exhibit this issue.

    The gfx backend, while it to does not appear to exhibit this issue, uses gfx::preset::blend::ALPHA which is srcAlpha + dstAlpha, so it is also incorrect.

    Reply
  • error: failed to run custom build command for `shaderc-sys v0.6.2`
    error: failed to run custom build command for `shaderc-sys v0.6.2`

    May 10, 2020

    Cloned the repository with "git clone https://github.com/PistonDevelopers/conrod.git". Current HEAD commit ID is 0c61e49afba22964a9479c371c7aaca3ab96ca67.

    I switched to conrod directory and ran "cargo build --release". The build failed with the following error:

    error: failed to run custom build command for shaderc-sys v0.6.2

    Caused by: process didn't exit successfully: /Users/austern/src/conrod/target/debug/build/shaderc-sys-f341b3d5cd06cebe/build-script-build (exit code: 101) --- stdout cargo:warning=System installed library not found. Falling back to build from source

    --- stderr thread 'main' panicked at '

    couldn't find required command: "cmake"

    ', /Users/austern/.cargo/registry/src/github.com-1ecc6299db9ec823/shaderc-sys-0.6.2/build/cmd_finder.rs:50:13 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

    warning: build failed, waiting for other jobs to finish... error: build failed

    My system is macOS Mojave 10.14.6. I'm using Rust version 1.43.1.

    Reply
  • Resolution scaling
    Resolution scaling

    May 27, 2020

    There is problem when system option - resolution scaling is different than 100% - for example when drawing point path in corner of the screen: 4K (3840x2160), scale 200% - no curve displayed 4K (3840x2160), scale 100% - curve is visible Full HD (1920x1080), scale 200% - no curve displayed Full HD (1920x1080), scale 125% - no curve displayed Full HD (1920x1080), scale 100% - curve is visible This bug occurs on both Linux and Windows. Is there any way to get info about system resolution scaling from conrod?

    Reply
  • scroll bar  have Tween animation ??
    scroll bar have Tween animation ??

    Jun 5, 2020

    scroll bar have Tween animation ?? It looks too stiff we need an Transition animation。 and I think many GUI controls can be built in, such as flutter

    Reply
  • cargo run examples failed
    cargo run examples failed

    Jun 11, 2020

    cargo run --release "winit glium" --example all_winit_glium error: a bin target must be available for cargo run

    I'm running win8.1

    Also, you should point out upfront out that you need cmake, ninja and python3. (I'm 100% new to rust, but conrod seems very promising to me.)

    Thanks!

    Reply
  • Cannot run examples
    Cannot run examples

    Jun 15, 2020

    @iMac conrod % cargo run --release --features "winit glium" --example all_winit_glium error: --features is not allowed in the root of a virtual workspace note: while this was previously accepted, it didn't actually do anything

    Reply
  • The Road to Pure Rust
    The Road to Pure Rust

    Feb 21, 2015

    Requiring users to compile / install C libraries is a real pity. It would be amazing if Conrod required nothing more than

    [dependencies]
    conrod = "*"
    

    I think we still have two dependencies that require having C libraries installed on the user's system:

    • [x] SDL2

    ~~This is only used for the example, but should be easily replaced by glutin :) #312~~ Conrod is now backend agnostic and all examples now use glutin.

    • [x] FreeType

    ~~This one may be trickier to handle. Is anyone aware of any purely rust font-rendering?~~ Now replaced with rusttype!

    discussion 
    Reply
  • Defer rendering of widgets in order to resolve drawing conflicts.
    Defer rendering of widgets in order to resolve drawing conflicts.

    Oct 16, 2014

    Current Problem

    We are unable to solve drawing conflicts between multiple widgets.

    i.e. when drawing an open DropDownList, the dropped menu will be covered by the widget below if that widget is drawn after the DropDownList. This is becuase the UiContext has know way of re-ordering the rendering of widgets.

    Solution

    Rather than calling .draw(graphics_backend) as the final builder method for every widget call and rendering each widget in its exact call site, I'm proposing that instead we store each called widget in the UiContext within something like a Vec<&mut Drawable>. Finally, once the user has finished calling all of their widget functions, they can call uic.draw(graphics_backend) which will:

    1. resolve conflicts between widgets and
    2. call the .draw(..) method for every stored widget in the correct order.

    Positives

    • One less builder method for every widget.
    • Correctly ordered widget drawing.

    Negatives

    • the need to call uic.draw(..) at the end of the render cycle.
    • the UiContext will need to store more widget information throughout the render cycle.
    discussion draft medium 
    Reply
  • Relicense under dual MIT/Apache-2.0
    Relicense under dual MIT/Apache-2.0

    Jan 10, 2016

    This issue was automatically generated. Feel free to close without ceremony if you do not agree with re-licensing or if it is not possible for other reasons. Respond to @cmr with any questions or concerns, or pop over to #rust-offtopic on IRC to discuss.

    You're receiving this because someone (perhaps the project maintainer) published a crates.io package with the license as "MIT" xor "Apache-2.0" and the repository field pointing here.

    TL;DR the Rust ecosystem is largely Apache-2.0. Being available under that license is good for interoperation. The MIT license as an add-on can be nice for GPLv2 projects to use your code.

    Why?

    The MIT license requires reproducing countless copies of the same copyright header with different names in the copyright field, for every MIT library in use. The Apache license does not have this drawback. However, this is not the primary motivation for me creating these issues. The Apache license also has protections from patent trolls and an explicit contribution licensing clause. However, the Apache license is incompatible with GPLv2. This is why Rust is dual-licensed as MIT/Apache (the "primary" license being Apache, MIT only for GPLv2 compat), and doing so would be wise for this project. This also makes this crate suitable for inclusion and unrestricted sharing in the Rust standard distribution and other projects using dual MIT/Apache, such as my personal ulterior motive, the Robigalia project.

    Some ask, "Does this really apply to binary redistributions? Does MIT really require reproducing the whole thing?" I'm not a lawyer, and I can't give legal advice, but some Google Android apps include open source attributions using this interpretation. Others also agree with it. But, again, the copyright notice redistribution is not the primary motivation for the dual-licensing. It's stronger protections to licensees and better interoperation with the wider Rust ecosystem.

    How?

    To do this, get explicit approval from each contributor of copyrightable work (as not all contributions qualify for copyright, due to not being a "creative work", e.g. a typo fix) and then add the following to your README:

    ## License
    
    Licensed under either of
    
     * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
     * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
    
    at your option.
    
    ### Contribution
    
    Unless you explicitly state otherwise, any contribution intentionally submitted
    for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
    additional terms or conditions.
    

    and in your license headers, if you have them, use the following boilerplate (based on that used in Rust):

    // Copyright 2016 conrod Developers
    //
    // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
    // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
    // http://opensource.org/licenses/MIT>, at your option. This file may not be
    // copied, modified, or distributed except according to those terms.
    

    It's commonly asked whether license headers are required. I'm not comfortable making an official recommendation either way, but the Apache license recommends it in their appendix on how to use the license.

    Be sure to add the relevant LICENSE-{MIT,APACHE} files. You can copy these from the Rust repo for a plain-text version.

    And don't forget to update the license metadata in your Cargo.toml to:

    license = "MIT OR Apache-2.0"
    

    I'll be going through projects which agree to be relicensed and have approval by the necessary contributors and doing this changes, so feel free to leave the heavy lifting to me!

    Contributor checkoff

    To agree to relicensing, comment with :

    I license past and future contributions under the dual MIT/Apache-2.0 license, allowing licensees to chose either at their option.
    

    Or, if you're a contributor, you can check the box in this repo next to your name. My scripts will pick this exact phrase up and check your checkbox, but I'll come through and manually review this issue later as well.

    • [x] @BenMcH
    • [x] @EleDiaz
    • [x] @Esption
    • [ ] @Potpourri
    • [x] @Ryman
    • [x] @TheNeikos
    • [x] @Vinatorul
    • [x] @aepsil0n
    • [ ] @alexchandel
    • [x] @benaryorg
    • [x] @bheart
    • [ ] @burtonageo
    • [x] @bvssvni
    • [x] @cmr
    • [x] @cybergeek94
    • [x] @dcampbell24
    • [ ] @debloper
    • [x] @ebfull
    • [x] @eklavya
    • [x] @evenlis
    • [x] @frewsxcv
    • [x] @gaudecker
    • [x] @gchp
    • [x] @indiv0
    • [x] @iwillspeak
    • [x] @jarrett
    • [x] @leonkunert
    • [x] @lifthrasiir
    • [x] @mitchmindtree
    • [x] @natemara
    • [x] @steveklabnik
    • [x] @stjahns
    • [x] @stratact
    • [ ] @tjtolon
    • [ ] @waynenilsen
    • [ ] @yuripourre
    • [x] @zummenix
    Reply
  • Update to latest changes in graphics and piston_window crates. Removes some unused dev-dependencies.
    Update to latest changes in graphics and piston_window crates. Removes some unused dev-dependencies.

    Feb 12, 2016

    Don't merge yet.

    Since updating, all of the colours in all of the examples have become much lighter:

    Before screen shot 2016-02-13 at 1 42 58 am

    After screen shot 2016-02-13 at 1 41 18 am

    It's possible that there might be some other change we have to update to in conrod, but perhaps also possible that there may have been a bug introduced to the graphics or gfx_graphics crates during the update to the latest gfx. Will look into this soon as this should be fixed before merging this PR. Ping @bvssvni

    Reply
  • [Breaking Change] Replace elmesque crate with primitive graphics widgets (see comment for more details).
    [Breaking Change] Replace elmesque crate with primitive graphics widgets (see comment for more details).

    Nov 15, 2015

    ~~This is a WIP - Do not merge just yet.~~

    This is quite a hefty change, and in turn is leaking into quite a few areas:

    • Add the widget::primitive module, hosting all primitive widgets. This module should contain all the primitive widgets a widget designer could possibly need to implement their own complex widgets.
    • Added an example demonstrating each of the primitive widgets.
    • Widgets will now compose themselves of primitive graphics widgets rather than drawing their own Elements or Forms. This allows us to remove the elmesque crate and use our own graphics layout instead, in turn providing a far simpler (and more efficient) graphics backend.
    • Theme will now support custom widget styling (rather than hard-coded style types).
    • Added methods to the Sizeable trait that allow setting a Widget's dimensions to match the dimensions of some other Widget.
    • Added a TitleBar widget, which Canvas will now use instead of its own custom TitleBar type.
    • Added a Widget::picking_passthrough(bool) method which allows a user to indicate whether their widget should be pick-able by the mouse or other widget picking methods. This is useful for primitive graphics widgets that are only designed to be used as graphical elements, and that are not themselves interactive.
    • Fixed a bug in Graph::scroll_offset where the behaviour would be incorrect if two widgets shared both Edge::Depth and Edge::Position.
    • Removed Label widget in favour of new Text primitive widget that handles automatic line-wrapping, line-spacing, etc.
    • Moved color.rs module from elmesque into conrod.
    • Removes rustc-serialize as the first step towards using serde (perhaps as a feature).

    All-in-all I think this should be a massive API improvement, and allow conrod to be a lot simpler to work with regarding graphics (elmesque has been a common point of confusion). It should also be much faster than elmesque as drawing will no longer require near as many allocations.

    Closes #421. Closes #466. Closes #506. Closes #509. Closes #522. Closes #555. Makes a start on #576. Closes #581. Closes #582. Closes #616. Closes #617. Fixes #628. Closes #629.

    Reply
  • Something strange with position and size of a drawable area of a window.
    Something strange with position and size of a drawable area of a window.

    Apr 8, 2015

    Current all_widgets.rs looks like: untitled

    bug help wanted 
    Reply