Skip to content

Commit

Permalink
Merge pull request #58 from barzamin/canvas-example
Browse files Browse the repository at this point in the history
Add a canvas example
  • Loading branch information
NoraCodes committed Feb 4, 2019
2 parents 5eb3af8 + c38efda commit 684b545
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
* README.md now links to libui, and is more explanatory
* `LayoutGrid::insert_at` no longer takes `left` and `height` arguments
* Many APIs which took `u64` or `i64` arguments now take `i32` for wider compatibility
* The semi-unstable `iui::draw` subsystem is again exported to downstream consumers of the `iui` crate.

### Deprecated

Expand Down
65 changes: 65 additions & 0 deletions iui/examples/canvas.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
extern crate iui;
extern crate ui_sys;

use iui::controls::{
Area, AreaDrawParams, AreaHandler, HorizontalBox, LayoutStrategy,
};
use iui::draw::{Brush, Path, SolidBrush, FillMode};
use iui::prelude::*;
use std::f64::consts::PI;

struct HandleCanvas {}
impl AreaHandler for HandleCanvas {
fn draw(&mut self, _area: &Area, draw_params: &AreaDrawParams) {
let ctx = &draw_params.context;

let path = Path::new(ctx, FillMode::Winding);
path.add_rectangle(ctx, 0., 0., draw_params.area_width, draw_params.area_height);
path.end(ctx);

let brush = Brush::Solid(SolidBrush {
r: 0.2,
g: 0.6,
b: 0.8,
a: 1.,
});

draw_params.context.fill(&path, &brush);

let path = Path::new(ctx, FillMode::Winding);
for i in 0..100 {
let x = i as f64 / 100.;
let y = ((x * PI * 2.).sin() + 1.) / 2.;
path.add_rectangle(
ctx,
x * draw_params.area_width,
0.,
draw_params.area_width / 100.,
y * draw_params.area_height,
);
}
path.end(ctx);

let brush = Brush::Solid(SolidBrush {
r: 0.2,
g: 0.,
b: 0.3,
a: 1.,
});

draw_params.context.fill(&path, &brush);
}
}

fn main() {
let ui = UI::init().expect("Couldn't initialize UI library");
let mut win = Window::new(&ui, "Area Canvas Example", 200, 200, WindowType::NoMenubar);

let mut hbox = HorizontalBox::new(&ui);
let area = Area::new(&ui, Box::new(HandleCanvas {}));
hbox.append(&ui, area, LayoutStrategy::Stretchy);

win.set_child(&ui, hbox);
win.show(&ui);
ui.main();
}
32 changes: 16 additions & 16 deletions iui/src/controls/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use controls::Control;
use draw;
use std::os::raw::c_int;
use std::mem;
use std::os::raw::c_int;
use ui::UI;
pub use ui_sys::uiExtKey as ExtKey;
use ui_sys::{
Expand All @@ -30,11 +30,11 @@ impl RustAreaHandler {
fn new(_ctx: &UI, trait_object: Box<AreaHandler>) -> Box<RustAreaHandler> {
return Box::new(RustAreaHandler {
ui_area_handler: uiAreaHandler {
Draw: draw,
MouseEvent: mouse_event,
MouseCrossed: mouse_crossed,
DragBroken: drag_broken,
KeyEvent: key_event,
Draw: Some(draw),
MouseEvent: Some(mouse_event),
MouseCrossed: Some(mouse_crossed),
DragBroken: Some(drag_broken),
KeyEvent: Some(key_event),
},
trait_object: trait_object,
});
Expand Down Expand Up @@ -116,7 +116,7 @@ impl RustAreaHandler {
}
}

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

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

Expand Down Expand Up @@ -253,11 +253,11 @@ impl AreaDrawParams {
}

bitflags! {
pub flags Modifiers: u8 {
const MODIFIER_CTRL = 1 << 0,
const MODIFIER_ALT = 1 << 1,
const MODIFIER_SHIFT = 1 << 2,
const MODIFIER_SUPER = 1 << 3,
pub struct Modifiers: u8 {
const MODIFIER_CTRL = 1 << 0;
const MODIFIER_ALT = 1 << 1;
const MODIFIER_SHIFT = 1 << 2;
const MODIFIER_SUPER = 1 << 3;
}
}

Expand Down
2 changes: 2 additions & 0 deletions iui/src/controls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ mod entry;
pub use self::entry::*;
mod progressbar;
pub use self::progressbar::*;
mod area;
pub use self::area::*;

/// A generic UI control. Any UI control can be turned into this type.
///
Expand Down
4 changes: 2 additions & 2 deletions iui/src/draw/brush.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::marker::PhantomData;
use std::ptr;
use ui::UI;
use draw::DrawContext;
use ui_sys::{self, uiDrawBrush};

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

impl Brush {
pub fn as_ui_draw_brush_ref(&self, _ctx: &UI) -> BrushRef {
pub fn as_ui_draw_brush_ref(&self, _ctx: &DrawContext) -> BrushRef {
match *self {
Brush::Solid(ref solid_brush) => BrushRef {
ui_draw_brush: uiDrawBrush {
Expand Down
17 changes: 8 additions & 9 deletions iui/src/draw/context.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use draw::{Brush, Path, StrokeParams, Transform};
use ui::UI;
use ui_sys::{self, uiDrawContext};

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

/// Draw a stroke on this DrawContext which runs along the given Path, with the given Brush and StrokeParams.
pub fn stroke(&self, ctx: &UI, path: &Path, brush: &Brush, stroke_params: &StrokeParams) {
pub fn stroke(&self, path: &Path, brush: &Brush, stroke_params: &StrokeParams) {
unsafe {
let brush = brush.as_ui_draw_brush_ref(ctx);
let stroke_params = stroke_params.as_stroke_params_ref(ctx);
let brush = brush.as_ui_draw_brush_ref(self);
let stroke_params = stroke_params.as_stroke_params_ref(self);
ui_sys::uiDrawStroke(
self.ui_draw_context,
path.ptr(),
Expand All @@ -34,25 +33,25 @@ impl DrawContext {
}

/// Draw a fill on this DrawContext using the given Path using the given Brush.
pub fn fill(&self, ctx: &UI, path: &Path, brush: &Brush) {
pub fn fill(&self, path: &Path, brush: &Brush) {
unsafe {
let brush = brush.as_ui_draw_brush_ref(ctx);
let brush = brush.as_ui_draw_brush_ref(self);
ui_sys::uiDrawFill(self.ui_draw_context, path.ptr(), brush.ptr())
}
}

/// Transform this DrawContext by the given Transform.
pub fn transform(&self, _ctx: &UI, txform: &Transform) {
pub fn transform(&self, txform: &Transform) {
unsafe { ui_sys::uiDrawTransform(self.ui_draw_context, txform.ptr()) }
}

/// Open a modal allowing the user to save the contents of this DrawContext.
pub fn save(&self, _ctx: &UI) {
pub fn save(&self) {
unsafe { ui_sys::uiDrawSave(self.ui_draw_context) }
}

/// Open a modal allowing the user to load the contents of a DrawContext onto this one.
pub fn restore(&self, _ctx: &UI) {
pub fn restore(&self) {
unsafe { ui_sys::uiDrawRestore(self.ui_draw_context) }
}
}
44 changes: 30 additions & 14 deletions iui/src/draw/path.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use draw::DrawContext;
use std::os::raw::c_int;
use ui::UI;
use ui_sys::{self, uiDrawPath};

pub use ui_sys::uiDrawFillMode as FillMode;
use ui_sys::{self, uiDrawFillMode, uiDrawFillModeAlternate, uiDrawFillModeWinding, uiDrawPath};

pub struct Path {
ui_draw_path: *mut uiDrawPath,
Expand All @@ -14,22 +12,40 @@ impl Drop for Path {
}
}

/// Represents the fill mode used when drawing a path.
#[derive(Clone, Copy, PartialEq)]
pub enum FillMode {
/// Draw using the [non-zero winding number fill rule](https://en.wikipedia.org/wiki/Nonzero-rule).
Winding,
/// Draw using the [even-odd fill rule](https://en.wikipedia.org/wiki/Even-odd_rule).
Alternate,
}

impl FillMode {
fn into_ui_fillmode(self) -> uiDrawFillMode {
return match self {
FillMode::Winding => uiDrawFillModeWinding,
FillMode::Alternate => uiDrawFillModeAlternate,
} as uiDrawFillMode;
}
}

impl Path {
pub fn new(_ctx: &UI, fill_mode: FillMode) -> Path {
pub fn new(_ctx: &DrawContext, fill_mode: FillMode) -> Path {
unsafe {
Path {
ui_draw_path: ui_sys::uiDrawNewPath(fill_mode),
ui_draw_path: ui_sys::uiDrawNewPath(fill_mode.into_ui_fillmode()),
}
}
}

pub fn new_figure(&self, _ctx: &UI, x: f64, y: f64) {
pub fn new_figure(&self, _ctx: &DrawContext, x: f64, y: f64) {
unsafe { ui_sys::uiDrawPathNewFigure(self.ui_draw_path, x, y) }
}

pub fn new_figure_with_arc(
&self,
_ctx: &UI,
_ctx: &DrawContext,
x_center: f64,
y_center: f64,
radius: f64,
Expand All @@ -50,13 +66,13 @@ impl Path {
}
}

pub fn line_to(&self, _ctx: &UI, x: f64, y: f64) {
pub fn line_to(&self, _ctx: &DrawContext, x: f64, y: f64) {
unsafe { ui_sys::uiDrawPathLineTo(self.ui_draw_path, x, y) }
}

pub fn arc_to(
&self,
_ctx: &UI,
_ctx: &DrawContext,
x_center: f64,
y_center: f64,
radius: f64,
Expand All @@ -79,7 +95,7 @@ impl Path {

pub fn bezier_to(
&self,
_ctx: &UI,
_ctx: &DrawContext,
c1x: f64,
c1y: f64,
c2x: f64,
Expand All @@ -90,15 +106,15 @@ impl Path {
unsafe { ui_sys::uiDrawPathBezierTo(self.ui_draw_path, c1x, c1y, c2x, c2y, end_x, end_y) }
}

pub fn close_figure(&self, _ctx: &UI) {
pub fn close_figure(&self, _ctx: &DrawContext) {
unsafe { ui_sys::uiDrawPathCloseFigure(self.ui_draw_path) }
}

pub fn add_rectangle(&self, _ctx: &UI, x: f64, y: f64, width: f64, height: f64) {
pub fn add_rectangle(&self, _ctx: &DrawContext, x: f64, y: f64, width: f64, height: f64) {
unsafe { ui_sys::uiDrawPathAddRectangle(self.ui_draw_path, x, y, width, height) }
}

pub fn end(&self, _ctx: &UI) {
pub fn end(&self, _ctx: &DrawContext) {
unsafe { ui_sys::uiDrawPathEnd(self.ui_draw_path) }
}

Expand Down
6 changes: 3 additions & 3 deletions iui/src/draw/strokeparams.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::os::raw::c_double;
use std::marker::PhantomData;
use ui::UI;
use std::os::raw::c_double;
use draw::DrawContext;
use ui_sys::uiDrawStrokeParams;

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

impl StrokeParams {
pub fn as_stroke_params_ref(&self, _ctx: &UI) -> StrokeParamsRef {
pub fn as_stroke_params_ref(&self, _ctx: &DrawContext) -> StrokeParamsRef {
StrokeParamsRef {
ui_draw_stroke_params: uiDrawStrokeParams {
Cap: self.cap,
Expand Down
2 changes: 2 additions & 0 deletions iui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
//! For code examples, see the [examples](https://github.com/rust-native-ui/libui-rs/blob/master/iui/examples/)
//! directory.

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate failure;
extern crate libc;
Expand Down

0 comments on commit 684b545

Please sign in to comment.