diff --git a/examples/dial.rs b/examples/dial.rs new file mode 100644 index 0000000000000000000000000000000000000000..a336e5d0557e3fbf43831c0bfe9a0d20ba335d4e --- /dev/null +++ b/examples/dial.rs @@ -0,0 +1,99 @@ +// Copyright 2019 The xi-editor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! An example of the `dial` widget. + +use druid::widget::{Flex, Label, WidgetExt}; +use druid::{AppLauncher, Color, Data, Lens, PlatformError, Size, Widget, WindowDesc}; + +use druid_widgets::Dial; + +#[derive(Clone, Data, Lens)] +struct DialLabel { + value: f64, +} + +impl DialLabel { + fn new(text: &str, value: f64) -> impl Widget<DialLabel> { + let text = text.to_string(); + let label = + Label::new(move |data: &DialLabel, _env: &_| format!("{} {:.3}", text, data.value)); + let solid = Color::rgb8(0x3a, 0x3a, 0x3a); + let mut col = Flex::column(); + col.add_child( + Dial::new(value, Size::new(100.0, 100.0)) + .lens(DialLabel::value) + .background(solid.clone()) + .padding(5.0), + 0.0, + ); + col.add_child(label.padding(5.0).background(solid.clone()), 0.0); + col + } +} +#[derive(Clone, Data, Lens)] +struct Envelope { + attack: DialLabel, + decay: DialLabel, + sustain: DialLabel, + release: DialLabel, +} + +impl Envelope { + fn new() -> impl Widget<Envelope> { + let solid = Color::rgb8(0x3a, 0x3a, 0x3a); + Flex::row() + .with_child( + DialLabel::new("Attack", 0.0) + .lens(Envelope::attack) + .background(solid.clone()) + .padding(5.0), + 0.0, + ) + .with_child( + DialLabel::new("Decay", 0.0) + .lens(Envelope::decay) + .background(solid.clone()) + .padding(5.0), + 0.0, + ) + .with_child( + DialLabel::new("Sustain", 0.0) + .lens(Envelope::sustain) + .background(solid.clone()) + .padding(5.0), + 0.0, + ) + .with_child( + DialLabel::new("Release", 0.0) + .lens(Envelope::release) + .background(solid.clone()) + .padding(5.0), + 0.0, + ) + } +} + +fn main() -> Result<(), PlatformError> { + AppLauncher::with_window(WindowDesc::new(Envelope::new)) + .use_simple_logger() + .launch(Envelope { + attack: DialLabel { value: 0.1 }, + decay: DialLabel { value: 0.2 }, + sustain: DialLabel { value: 0.3 }, + release: DialLabel { value: 0.4 }, + })?; + + Ok(()) +} diff --git a/src/dial.rs b/src/dial.rs index b9a3444552d0051a9dc881a4b3ebefe2a7ba38fa..84ca0f79bd92f643e84e3cbdd915cdbe90d7820e 100644 --- a/src/dial.rs +++ b/src/dial.rs @@ -1,14 +1,10 @@ use std::f64::consts::PI; -use druid::kurbo::{BezPath, Line}; -use druid::widget::{Align, Flex, Label, WidgetExt}; +use druid::kurbo::BezPath; use druid::{ - AppLauncher, BoxConstraints, Color, Data, Env, Event, EventCtx, LayoutCtx, LinearGradient, - PaintCtx, PlatformError, Point, RenderContext, Size, UnitPoint, UpdateCtx, Vec2, WheelEvent, - Widget, WindowDesc, + BoxConstraints, Color, Env, Event, EventCtx, LayoutCtx, PaintCtx, Point, RenderContext, Size, + UpdateCtx, Vec2, Widget, }; -use log::info; -use std::convert::From; #[derive(Debug, Clone, Default)] pub struct Dial { // properties for the Dial @@ -17,8 +13,8 @@ pub struct Dial { } impl Dial { - pub fn new(size: Size) -> impl Widget<f64> { - Self { value: 0.0, size } + pub fn new(value: f64, size: Size) -> impl Widget<f64> { + Self { value, size } } } @@ -26,7 +22,7 @@ impl Widget<f64> for Dial { fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut f64, _env: &Env) { match event { Event::Wheel(w) => { - let mut delta = w.delta.y / (120 * 10) as f64; // 1% for my machine + let mut delta = w.delta.y / (120 * 10) as f64; // 10% for my machine if w.mods.shift { delta = delta / 10.0; }; @@ -59,13 +55,12 @@ impl Widget<f64> for Dial { } fn paint(&mut self, paint_ctx: &mut PaintCtx, data: &f64, _env: &Env) { - info!("dial paint"); - // for some reason origin (0,0) seems not to point to the border not the interior let center = Point::new(self.size.width / 2.0, self.size.height / 2.0); let diameter = 0.8 * self.size.width / 2.0; let mut path = BezPath::new(); let ambit0 = center + diameter * Vec2::from_angle(0.0); path.move_to(ambit0); + // Circle drawn in 36 segments for v in (0..360).step_by(10) { let ambit = center + diameter * Vec2::from_angle(v as f64 / 360.0 * 2.0 * PI); path.line_to(ambit);