Skip to content

Commit 684b545

Browse files
authored
Merge pull request #58 from barzamin/canvas-example
Add a canvas example
2 parents 5eb3af8 + c38efda commit 684b545

File tree

9 files changed

+129
-44
lines changed

9 files changed

+129
-44
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
1919
* README.md now links to libui, and is more explanatory
2020
* `LayoutGrid::insert_at` no longer takes `left` and `height` arguments
2121
* Many APIs which took `u64` or `i64` arguments now take `i32` for wider compatibility
22+
* The semi-unstable `iui::draw` subsystem is again exported to downstream consumers of the `iui` crate.
2223

2324
### Deprecated
2425

iui/examples/canvas.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
extern crate iui;
2+
extern crate ui_sys;
3+
4+
use iui::controls::{
5+
Area, AreaDrawParams, AreaHandler, HorizontalBox, LayoutStrategy,
6+
};
7+
use iui::draw::{Brush, Path, SolidBrush, FillMode};
8+
use iui::prelude::*;
9+
use std::f64::consts::PI;
10+
11+
struct HandleCanvas {}
12+
impl AreaHandler for HandleCanvas {
13+
fn draw(&mut self, _area: &Area, draw_params: &AreaDrawParams) {
14+
let ctx = &draw_params.context;
15+
16+
let path = Path::new(ctx, FillMode::Winding);
17+
path.add_rectangle(ctx, 0., 0., draw_params.area_width, draw_params.area_height);
18+
path.end(ctx);
19+
20+
let brush = Brush::Solid(SolidBrush {
21+
r: 0.2,
22+
g: 0.6,
23+
b: 0.8,
24+
a: 1.,
25+
});
26+
27+
draw_params.context.fill(&path, &brush);
28+
29+
let path = Path::new(ctx, FillMode::Winding);
30+
for i in 0..100 {
31+
let x = i as f64 / 100.;
32+
let y = ((x * PI * 2.).sin() + 1.) / 2.;
33+
path.add_rectangle(
34+
ctx,
35+
x * draw_params.area_width,
36+
0.,
37+
draw_params.area_width / 100.,
38+
y * draw_params.area_height,
39+
);
40+
}
41+
path.end(ctx);
42+
43+
let brush = Brush::Solid(SolidBrush {
44+
r: 0.2,
45+
g: 0.,
46+
b: 0.3,
47+
a: 1.,
48+
});
49+
50+
draw_params.context.fill(&path, &brush);
51+
}
52+
}
53+
54+
fn main() {
55+
let ui = UI::init().expect("Couldn't initialize UI library");
56+
let mut win = Window::new(&ui, "Area Canvas Example", 200, 200, WindowType::NoMenubar);
57+
58+
let mut hbox = HorizontalBox::new(&ui);
59+
let area = Area::new(&ui, Box::new(HandleCanvas {}));
60+
hbox.append(&ui, area, LayoutStrategy::Stretchy);
61+
62+
win.set_child(&ui, hbox);
63+
win.show(&ui);
64+
ui.main();
65+
}

iui/src/controls/area.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
33
use controls::Control;
44
use draw;
5-
use std::os::raw::c_int;
65
use std::mem;
6+
use std::os::raw::c_int;
77
use ui::UI;
88
pub use ui_sys::uiExtKey as ExtKey;
99
use ui_sys::{
@@ -30,11 +30,11 @@ impl RustAreaHandler {
3030
fn new(_ctx: &UI, trait_object: Box<AreaHandler>) -> Box<RustAreaHandler> {
3131
return Box::new(RustAreaHandler {
3232
ui_area_handler: uiAreaHandler {
33-
Draw: draw,
34-
MouseEvent: mouse_event,
35-
MouseCrossed: mouse_crossed,
36-
DragBroken: drag_broken,
37-
KeyEvent: key_event,
33+
Draw: Some(draw),
34+
MouseEvent: Some(mouse_event),
35+
MouseCrossed: Some(mouse_crossed),
36+
DragBroken: Some(drag_broken),
37+
KeyEvent: Some(key_event),
3838
},
3939
trait_object: trait_object,
4040
});
@@ -116,7 +116,7 @@ impl RustAreaHandler {
116116
}
117117
}
118118

119-
define_control!{
119+
define_control! {
120120
/// A space on which the application can draw custom content.
121121
/// Area is a Control that represents a blank canvas that a program can draw on as
122122
/// it wishes. Areas also receive keyboard and mouse events, and programs can react
@@ -170,8 +170,8 @@ impl Area {
170170
let mut rust_area_handler = RustAreaHandler::new(ctx, area_handler);
171171
let area = Area::from_raw(ui_sys::uiNewScrollingArea(
172172
&mut *rust_area_handler as *mut RustAreaHandler as *mut uiAreaHandler,
173-
width,
174-
height,
173+
width as i32,
174+
height as i32,
175175
));
176176
mem::forget(rust_area_handler);
177177
area
@@ -188,7 +188,7 @@ impl Area {
188188
/// If called on a non-scrolling `Area`, this function's behavior is undefined.
189189
pub unsafe fn set_size(&self, _ctx: &UI, width: u64, height: u64) {
190190
// TODO: Check if the area is scrolling?
191-
unsafe { ui_sys::uiAreaSetSize(self.uiArea, width as i64, height as i64) }
191+
ui_sys::uiAreaSetSize(self.uiArea, width as i32, height as i32);
192192
}
193193

194194
/// Queues the entire `Area` to be redrawn. This function returns immediately;
@@ -205,7 +205,7 @@ impl Area {
205205
/// If called on a non-scrolling `Area`, this function's behavior is undefined.
206206
pub unsafe fn scroll_to(&self, _ctx: &UI, x: f64, y: f64, width: f64, height: f64) {
207207
// TODO: Make some way to check whether the given area is scrolling or not.
208-
unsafe { ui_sys::uiAreaScrollTo(self.uiArea, x, y, width, height) }
208+
ui_sys::uiAreaScrollTo(self.uiArea, x, y, width, height);
209209
}
210210
}
211211

@@ -253,11 +253,11 @@ impl AreaDrawParams {
253253
}
254254

255255
bitflags! {
256-
pub flags Modifiers: u8 {
257-
const MODIFIER_CTRL = 1 << 0,
258-
const MODIFIER_ALT = 1 << 1,
259-
const MODIFIER_SHIFT = 1 << 2,
260-
const MODIFIER_SUPER = 1 << 3,
256+
pub struct Modifiers: u8 {
257+
const MODIFIER_CTRL = 1 << 0;
258+
const MODIFIER_ALT = 1 << 1;
259+
const MODIFIER_SHIFT = 1 << 2;
260+
const MODIFIER_SUPER = 1 << 3;
261261
}
262262
}
263263

iui/src/controls/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ mod entry;
1919
pub use self::entry::*;
2020
mod progressbar;
2121
pub use self::progressbar::*;
22+
mod area;
23+
pub use self::area::*;
2224

2325
/// A generic UI control. Any UI control can be turned into this type.
2426
///

iui/src/draw/brush.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::marker::PhantomData;
22
use std::ptr;
3-
use ui::UI;
3+
use draw::DrawContext;
44
use ui_sys::{self, uiDrawBrush};
55

66
pub use ui_sys::uiDrawBrushGradientStop as BrushGradientStop;
@@ -22,7 +22,7 @@ pub struct BrushRef<'a> {
2222
}
2323

2424
impl Brush {
25-
pub fn as_ui_draw_brush_ref(&self, _ctx: &UI) -> BrushRef {
25+
pub fn as_ui_draw_brush_ref(&self, _ctx: &DrawContext) -> BrushRef {
2626
match *self {
2727
Brush::Solid(ref solid_brush) => BrushRef {
2828
ui_draw_brush: uiDrawBrush {

iui/src/draw/context.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use draw::{Brush, Path, StrokeParams, Transform};
2-
use ui::UI;
32
use ui_sys::{self, uiDrawContext};
43

54
/// Drawing context, used to draw custom content on the screen.
@@ -20,10 +19,10 @@ impl DrawContext {
2019
}
2120

2221
/// Draw a stroke on this DrawContext which runs along the given Path, with the given Brush and StrokeParams.
23-
pub fn stroke(&self, ctx: &UI, path: &Path, brush: &Brush, stroke_params: &StrokeParams) {
22+
pub fn stroke(&self, path: &Path, brush: &Brush, stroke_params: &StrokeParams) {
2423
unsafe {
25-
let brush = brush.as_ui_draw_brush_ref(ctx);
26-
let stroke_params = stroke_params.as_stroke_params_ref(ctx);
24+
let brush = brush.as_ui_draw_brush_ref(self);
25+
let stroke_params = stroke_params.as_stroke_params_ref(self);
2726
ui_sys::uiDrawStroke(
2827
self.ui_draw_context,
2928
path.ptr(),
@@ -34,25 +33,25 @@ impl DrawContext {
3433
}
3534

3635
/// Draw a fill on this DrawContext using the given Path using the given Brush.
37-
pub fn fill(&self, ctx: &UI, path: &Path, brush: &Brush) {
36+
pub fn fill(&self, path: &Path, brush: &Brush) {
3837
unsafe {
39-
let brush = brush.as_ui_draw_brush_ref(ctx);
38+
let brush = brush.as_ui_draw_brush_ref(self);
4039
ui_sys::uiDrawFill(self.ui_draw_context, path.ptr(), brush.ptr())
4140
}
4241
}
4342

4443
/// Transform this DrawContext by the given Transform.
45-
pub fn transform(&self, _ctx: &UI, txform: &Transform) {
44+
pub fn transform(&self, txform: &Transform) {
4645
unsafe { ui_sys::uiDrawTransform(self.ui_draw_context, txform.ptr()) }
4746
}
4847

4948
/// Open a modal allowing the user to save the contents of this DrawContext.
50-
pub fn save(&self, _ctx: &UI) {
49+
pub fn save(&self) {
5150
unsafe { ui_sys::uiDrawSave(self.ui_draw_context) }
5251
}
5352

5453
/// Open a modal allowing the user to load the contents of a DrawContext onto this one.
55-
pub fn restore(&self, _ctx: &UI) {
54+
pub fn restore(&self) {
5655
unsafe { ui_sys::uiDrawRestore(self.ui_draw_context) }
5756
}
5857
}

iui/src/draw/path.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1+
use draw::DrawContext;
12
use std::os::raw::c_int;
2-
use ui::UI;
3-
use ui_sys::{self, uiDrawPath};
4-
5-
pub use ui_sys::uiDrawFillMode as FillMode;
3+
use ui_sys::{self, uiDrawFillMode, uiDrawFillModeAlternate, uiDrawFillModeWinding, uiDrawPath};
64

75
pub struct Path {
86
ui_draw_path: *mut uiDrawPath,
@@ -14,22 +12,40 @@ impl Drop for Path {
1412
}
1513
}
1614

15+
/// Represents the fill mode used when drawing a path.
16+
#[derive(Clone, Copy, PartialEq)]
17+
pub enum FillMode {
18+
/// Draw using the [non-zero winding number fill rule](https://en.wikipedia.org/wiki/Nonzero-rule).
19+
Winding,
20+
/// Draw using the [even-odd fill rule](https://en.wikipedia.org/wiki/Even-odd_rule).
21+
Alternate,
22+
}
23+
24+
impl FillMode {
25+
fn into_ui_fillmode(self) -> uiDrawFillMode {
26+
return match self {
27+
FillMode::Winding => uiDrawFillModeWinding,
28+
FillMode::Alternate => uiDrawFillModeAlternate,
29+
} as uiDrawFillMode;
30+
}
31+
}
32+
1733
impl Path {
18-
pub fn new(_ctx: &UI, fill_mode: FillMode) -> Path {
34+
pub fn new(_ctx: &DrawContext, fill_mode: FillMode) -> Path {
1935
unsafe {
2036
Path {
21-
ui_draw_path: ui_sys::uiDrawNewPath(fill_mode),
37+
ui_draw_path: ui_sys::uiDrawNewPath(fill_mode.into_ui_fillmode()),
2238
}
2339
}
2440
}
2541

26-
pub fn new_figure(&self, _ctx: &UI, x: f64, y: f64) {
42+
pub fn new_figure(&self, _ctx: &DrawContext, x: f64, y: f64) {
2743
unsafe { ui_sys::uiDrawPathNewFigure(self.ui_draw_path, x, y) }
2844
}
2945

3046
pub fn new_figure_with_arc(
3147
&self,
32-
_ctx: &UI,
48+
_ctx: &DrawContext,
3349
x_center: f64,
3450
y_center: f64,
3551
radius: f64,
@@ -50,13 +66,13 @@ impl Path {
5066
}
5167
}
5268

53-
pub fn line_to(&self, _ctx: &UI, x: f64, y: f64) {
69+
pub fn line_to(&self, _ctx: &DrawContext, x: f64, y: f64) {
5470
unsafe { ui_sys::uiDrawPathLineTo(self.ui_draw_path, x, y) }
5571
}
5672

5773
pub fn arc_to(
5874
&self,
59-
_ctx: &UI,
75+
_ctx: &DrawContext,
6076
x_center: f64,
6177
y_center: f64,
6278
radius: f64,
@@ -79,7 +95,7 @@ impl Path {
7995

8096
pub fn bezier_to(
8197
&self,
82-
_ctx: &UI,
98+
_ctx: &DrawContext,
8399
c1x: f64,
84100
c1y: f64,
85101
c2x: f64,
@@ -90,15 +106,15 @@ impl Path {
90106
unsafe { ui_sys::uiDrawPathBezierTo(self.ui_draw_path, c1x, c1y, c2x, c2y, end_x, end_y) }
91107
}
92108

93-
pub fn close_figure(&self, _ctx: &UI) {
109+
pub fn close_figure(&self, _ctx: &DrawContext) {
94110
unsafe { ui_sys::uiDrawPathCloseFigure(self.ui_draw_path) }
95111
}
96112

97-
pub fn add_rectangle(&self, _ctx: &UI, x: f64, y: f64, width: f64, height: f64) {
113+
pub fn add_rectangle(&self, _ctx: &DrawContext, x: f64, y: f64, width: f64, height: f64) {
98114
unsafe { ui_sys::uiDrawPathAddRectangle(self.ui_draw_path, x, y, width, height) }
99115
}
100116

101-
pub fn end(&self, _ctx: &UI) {
117+
pub fn end(&self, _ctx: &DrawContext) {
102118
unsafe { ui_sys::uiDrawPathEnd(self.ui_draw_path) }
103119
}
104120

iui/src/draw/strokeparams.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use std::os::raw::c_double;
21
use std::marker::PhantomData;
3-
use ui::UI;
2+
use std::os::raw::c_double;
3+
use draw::DrawContext;
44
use ui_sys::uiDrawStrokeParams;
55

66
pub use ui_sys::uiDrawLineCap as LineCap;
@@ -23,7 +23,7 @@ pub struct StrokeParamsRef<'a> {
2323
}
2424

2525
impl StrokeParams {
26-
pub fn as_stroke_params_ref(&self, _ctx: &UI) -> StrokeParamsRef {
26+
pub fn as_stroke_params_ref(&self, _ctx: &DrawContext) -> StrokeParamsRef {
2727
StrokeParamsRef {
2828
ui_draw_stroke_params: uiDrawStrokeParams {
2929
Cap: self.cap,

iui/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
//! For code examples, see the [examples](https://github.com/rust-native-ui/libui-rs/blob/master/iui/examples/)
1818
//! directory.
1919
20+
#[macro_use]
21+
extern crate bitflags;
2022
#[macro_use]
2123
extern crate failure;
2224
extern crate libc;

0 commit comments

Comments
 (0)