Skip to content

Commit

Permalink
Input no longer blinks in the background
Browse files Browse the repository at this point in the history
Also, Expand now expands properly.
  • Loading branch information
ecton committed Nov 8, 2023
1 parent b27b9db commit fc16562
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 30 deletions.
4 changes: 2 additions & 2 deletions examples/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use gooey::widgets::Input;
use gooey::widgets::{Expand, Input};
use gooey::Run;

fn main() -> gooey::Result {
Input::new("Hello").run()
Expand::new(Input::new("Hello")).run()
}
13 changes: 13 additions & 0 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,18 @@ impl<'context, 'window> WidgetContext<'context, 'window> {
redraw_status: self.redraw_status.clone(),
}
}

/// Returns the window containing this widget.
#[must_use]
pub fn window(&self) -> &RunningWindow<'window> {
self.window
}

/// Returns an exclusive reference to the window containing this widget.
#[must_use]
pub fn window_mut(&mut self) -> &mut RunningWindow<'window> {
self.window
}
}

pub(crate) struct WindowHandle {
Expand Down Expand Up @@ -890,6 +902,7 @@ impl<'window> Deref for WidgetContext<'_, 'window> {
self.window
}
}

impl<'window> DerefMut for WidgetContext<'_, 'window> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.window
Expand Down
18 changes: 18 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use std::ops::Sub;
pub use kludgine;
use kludgine::app::winit::error::EventLoopError;
use kludgine::figures::units::UPx;
use kludgine::figures::{Fraction, IntoUnsigned, ScreenUnit};
pub use names::Name;
pub use utils::WithClone;

Expand All @@ -44,6 +45,23 @@ impl ConstraintLimit {
ConstraintLimit::Known(v) | ConstraintLimit::ClippedAfter(v) => v,
}
}

/// Converts `measured` to unsigned pixels, and adjusts it according to the
/// contraint's intentions.
///
/// If this constraint is of a known size, it will return the maximum of the
/// measured size and the contraint. If it is of an unknown size, it will
/// return the measured size.
pub fn fit_measured<Unit>(self, measured: Unit, scale: Fraction) -> UPx
where
Unit: ScreenUnit,
{
let measured = measured.into_px(scale).into_unsigned();
match self {
ConstraintLimit::Known(size) => size.max(measured),
ConstraintLimit::ClippedAfter(_) => measured,
}
}
}

impl Sub<UPx> for ConstraintLimit {
Expand Down
13 changes: 11 additions & 2 deletions src/widgets/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,16 @@ impl Widget for Expand {
);
let child = self.child.mounted(&mut context.as_event_context());
let size = context.for_other(&child).layout(available_space);
context.set_child_layout(&child, Rect::from(size.into_signed()));
size

let expanded_size = Size::new(
available_space
.width
.fit_measured(size.width, context.graphics.scale()),
available_space
.height
.fit_measured(size.height, context.graphics.scale()),
);
context.set_child_layout(&child, Rect::from(expanded_size.into_signed()));
expanded_size
}
}
9 changes: 7 additions & 2 deletions src/widgets/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ impl Widget for Input {
(Err(_), Err(_)) => {}
}
} else if let Ok((location, _)) = cursor_glyph(buffer, &cursor) {
if cursor_state.visible {
let window_focused = context.window().focused().get();
if window_focused && cursor_state.visible {
context.graphics.draw_shape(
&Shape::filled_rect(
Rect::new(
Expand All @@ -294,7 +295,11 @@ impl Widget for Input {
None,
);
}
context.redraw_in(cursor_state.remaining_until_blink);
if window_focused {
context.redraw_in(cursor_state.remaining_until_blink);
} else {
context.redraw_when_changed(context.window().focused());
}
}
}

Expand Down
128 changes: 104 additions & 24 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::ffi::OsStr;
use std::ops::{Deref, DerefMut};
use std::panic::{AssertUnwindSafe, UnwindSafe};
use std::path::Path;
use std::string::ToString;
Expand Down Expand Up @@ -34,7 +35,53 @@ use crate::window::sealed::WindowCommand;
use crate::{ConstraintLimit, Run};

/// A currently running Gooey window.
pub type RunningWindow<'window> = kludgine::app::Window<'window, WindowCommand>;
pub struct RunningWindow<'window> {
window: kludgine::app::Window<'window, WindowCommand>,
focused: Dynamic<bool>,
occluded: Dynamic<bool>,
}

impl<'window> RunningWindow<'window> {
pub(crate) fn new(
window: kludgine::app::Window<'window, WindowCommand>,
focused: &Dynamic<bool>,
occluded: &Dynamic<bool>,
) -> Self {
Self {
window,
focused: focused.clone(),
occluded: occluded.clone(),
}
}

/// Returns a dynamic that is updated whenever this window's focus status
/// changes.
#[must_use]
pub const fn focused(&self) -> &Dynamic<bool> {
&self.focused
}

/// Returns a dynamic that is updated whenever this window's occlusion
/// status changes.
#[must_use]
pub fn occluded(&self) -> &Dynamic<bool> {
&self.occluded
}
}

impl<'window> Deref for RunningWindow<'window> {
type Target = kludgine::app::Window<'window, WindowCommand>;

fn deref(&self) -> &Self::Target {
&self.window
}
}

impl<'window> DerefMut for RunningWindow<'window> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.window
}
}

/// The attributes of a Gooey window.
pub type WindowAttributes = kludgine::app::WindowAttributes<WindowCommand>;
Expand Down Expand Up @@ -194,8 +241,8 @@ struct GooeyWindow<T> {
mouse_state: MouseState,
redraw_status: RedrawStatus,
initial_frame: bool,
occluded: Option<Dynamic<bool>>,
focused: Option<Dynamic<bool>>,
occluded: Dynamic<bool>,
focused: Dynamic<bool>,
}

impl<T> GooeyWindow<T>
Expand All @@ -216,14 +263,27 @@ where
type Context = AssertUnwindSafe<sealed::Context<T::Context>>;

fn initialize(
mut window: RunningWindow<'_>,
window: kludgine::app::Window<'_, WindowCommand>,
_graphics: &mut kludgine::Graphics<'_>,
AssertUnwindSafe(context): Self::Context,
) -> Self {
let mut behavior = T::initialize(&mut window, context.user);
let occluded = context
.settings
.borrow_mut()
.occluded
.take()
.unwrap_or_default();
let focused = context
.settings
.borrow_mut()
.focused
.take()
.unwrap_or_default();
let mut behavior = T::initialize(
&mut RunningWindow::new(window, &focused, &occluded),
context.user,
);
let root = Tree::default().push_boxed(behavior.make_root(), None);
let occluded = context.settings.borrow_mut().occluded.take();
let focused = context.settings.borrow_mut().focused.take();

Self {
behavior,
Expand All @@ -242,11 +302,16 @@ where
}
}

fn prepare(&mut self, mut window: RunningWindow<'_>, graphics: &mut kludgine::Graphics<'_>) {
fn prepare(
&mut self,
window: kludgine::app::Window<'_, WindowCommand>,
graphics: &mut kludgine::Graphics<'_>,
) {
self.redraw_status.refresh_received();
graphics.reset_text_attributes();
self.root.tree.reset_render_order();
let graphics = self.contents.new_frame(graphics);
let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
let mut context = GraphicsContext {
widget: WidgetContext::new(self.root.clone(), &self.redraw_status, &mut window),
graphics: Exclusive::Owned(Graphics::new(graphics)),
Expand Down Expand Up @@ -280,24 +345,20 @@ where
window: kludgine::app::Window<'_, WindowCommand>,
_kludgine: &mut Kludgine,
) {
if let Some(focused) = &self.focused {
focused.update(window.focused());
}
self.focused.update(window.focused());
}

fn occlusion_changed(
&mut self,
window: kludgine::app::Window<'_, WindowCommand>,
_kludgine: &mut Kludgine,
) {
if let Some(occluded) = &self.occluded {
occluded.update(window.ocluded());
}
self.occluded.update(window.ocluded());
}

fn render<'pass>(
&'pass mut self,
_window: RunningWindow<'_>,
_window: kludgine::app::Window<'_, WindowCommand>,
graphics: &mut kludgine::RenderingGraphics<'_, 'pass>,
) -> bool {
self.contents.render(graphics);
Expand All @@ -316,8 +377,16 @@ where
.expect("called more than once")
}

fn close_requested(&mut self, mut window: RunningWindow<'_>, _kludgine: &mut Kludgine) -> bool {
self.request_close(&mut window)
fn close_requested(
&mut self,
window: kludgine::app::Window<'_, WindowCommand>,
_kludgine: &mut Kludgine,
) -> bool {
self.request_close(&mut RunningWindow::new(
window,
&self.focused,
&self.occluded,
))
}

// fn power_preference() -> wgpu::PowerPreference {
Expand Down Expand Up @@ -352,14 +421,15 @@ where

fn keyboard_input(
&mut self,
mut window: RunningWindow<'_>,
window: kludgine::app::Window<'_, WindowCommand>,
kludgine: &mut Kludgine,
device_id: DeviceId,
input: KeyEvent,
is_synthetic: bool,
) {
let target = self.root.tree.focused_widget().unwrap_or(self.root.id());
let target = self.root.tree.widget(target).expect("missing widget");
let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
let mut target = EventContext::new(
WidgetContext::new(target, &self.redraw_status, &mut window),
kludgine,
Expand Down Expand Up @@ -404,7 +474,7 @@ where

fn mouse_wheel(
&mut self,
mut window: RunningWindow<'_>,
window: kludgine::app::Window<'_, WindowCommand>,
kludgine: &mut Kludgine,
device_id: DeviceId,
delta: MouseScrollDelta,
Expand All @@ -422,6 +492,7 @@ where
.expect("missing widget")
});

let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
let mut widget = EventContext::new(
WidgetContext::new(widget, &self.redraw_status, &mut window),
kludgine,
Expand All @@ -433,7 +504,12 @@ where

// fn modifiers_changed(&mut self, window: kludgine::app::Window<'_, ()>) {}

fn ime(&mut self, mut window: RunningWindow<'_>, kludgine: &mut Kludgine, ime: Ime) {
fn ime(
&mut self,
window: kludgine::app::Window<'_, WindowCommand>,
kludgine: &mut Kludgine,
ime: Ime,
) {
let widget = self
.root
.tree
Expand All @@ -445,6 +521,7 @@ where
.widget(self.root.id())
.expect("missing widget")
});
let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
let mut target = EventContext::new(
WidgetContext::new(widget, &self.redraw_status, &mut window),
kludgine,
Expand All @@ -456,14 +533,15 @@ where

fn cursor_moved(
&mut self,
mut window: RunningWindow<'_>,
window: kludgine::app::Window<'_, WindowCommand>,
kludgine: &mut Kludgine,
device_id: DeviceId,
position: PhysicalPosition<f64>,
) {
let location = Point::<Px>::from(position);
self.mouse_state.location = Some(location);

let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
if let Some(state) = self.mouse_state.devices.get(&device_id) {
// Mouse Drag
for (button, handler) in state {
Expand Down Expand Up @@ -505,11 +583,12 @@ where

fn cursor_left(
&mut self,
mut window: RunningWindow<'_>,
window: kludgine::app::Window<'_, WindowCommand>,
kludgine: &mut Kludgine,
_device_id: DeviceId,
) {
if self.mouse_state.widget.take().is_some() {
let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
let mut context = EventContext::new(
WidgetContext::new(self.root.clone(), &self.redraw_status, &mut window),
kludgine,
Expand All @@ -520,12 +599,13 @@ where

fn mouse_input(
&mut self,
mut window: RunningWindow<'_>,
window: kludgine::app::Window<'_, WindowCommand>,
kludgine: &mut Kludgine,
device_id: DeviceId,
state: ElementState,
button: MouseButton,
) {
let mut window = RunningWindow::new(window, &self.focused, &self.occluded);
match state {
ElementState::Pressed => {
EventContext::new(
Expand Down Expand Up @@ -587,7 +667,7 @@ where

fn event(
&mut self,
mut window: RunningWindow<'_>,
mut window: kludgine::app::Window<'_, WindowCommand>,
_kludgine: &mut Kludgine,
event: WindowCommand,
) {
Expand Down

0 comments on commit fc16562

Please sign in to comment.