Skip to content

Commit

Permalink
add more padding to building select
Browse files Browse the repository at this point in the history
fixes #112
  • Loading branch information
Uriopass committed Jul 11, 2024
1 parent 31f3c33 commit fb871fc
Show file tree
Hide file tree
Showing 3 changed files with 390 additions and 148 deletions.
24 changes: 12 additions & 12 deletions goryak/src/imagebutton.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,18 @@ impl Widget for ImageButtonWidget {
resp
}

fn layout(&self, mut ctx: LayoutContext<'_>, input: Constraints) -> Vec2 {
if let Some(tooltip) = ctx.dom.get_current().children.first() {
let size = ctx.calculate_layout(*tooltip, Constraints::none());
ctx.layout.set_pos(
*tooltip,
Vec2::new((self.props.size.x - size.x) / 2.0, -size.y - 10.0),
);
}

input.constrain_min(self.props.size)
}

fn paint(&self, mut ctx: PaintContext<'_>) {
let node = ctx.dom.get_current();
let layout_node = ctx.layout.get(ctx.dom.current()).unwrap();
Expand Down Expand Up @@ -174,18 +186,6 @@ impl Widget for ImageButtonWidget {
EventInterest::MOUSE_ALL
}

fn layout(&self, mut ctx: LayoutContext<'_>, input: Constraints) -> Vec2 {
if let Some(tooltip) = ctx.dom.get_current().children.first() {
let size = ctx.calculate_layout(*tooltip, Constraints::none());
ctx.layout.set_pos(
*tooltip,
Vec2::new((self.props.size.x - size.x) / 2.0, -size.y - 10.0),
);
}

input.constrain_min(self.props.size)
}

fn event(&mut self, _: EventContext<'_>, event: &WidgetEvent) -> EventResponse {
match *event {
WidgetEvent::MouseMoved(Some(_)) => {
Expand Down
230 changes: 229 additions & 1 deletion goryak/src/scroll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use yakui_core::widget::{EventContext, LayoutContext, PaintContext, Widget};
use yakui_core::Response;
use yakui_widgets::shapes::RoundedRectangle;

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum VertScrollSize {
/// The scroll size is a percentage of the parent's size.
Percent(f32),
Expand Down Expand Up @@ -249,3 +249,231 @@ impl Widget for VertScrollWidget {
}
}
}

#[derive(Debug, PartialEq)]
pub enum HorizScrollSize {
/// The scroll size is a percentage of the parent's size.
Percent(f32),
/// The scroll size is exactly what is given (within constraints).
Exact(f32),
/// The scroll size is at most what is given (within constraints).
Fixed(f32),
/// The scroll size is equal to the parent's size.
Max,
}

impl HorizScrollSize {
pub fn show<F: FnOnce()>(self, children: F) -> Response<HorizScrollResponse> {
yakui_widgets::util::widget_children::<HorizScrollWidget, F>(
children,
HorizScroll { size: self },
)
}
}

#[derive(Debug)]
pub struct HorizScroll {
pub size: HorizScrollSize,
}

impl HorizScroll {
pub fn show<F: FnOnce()>(self, children: F) -> Response<HorizScrollResponse> {
yakui_widgets::util::widget_children::<HorizScrollWidget, F>(children, self)
}
}

#[derive(Debug)]
#[non_exhaustive]
pub struct HorizScrollWidget {
props: HorizScroll,
scroll_position: Cell<f32>,
size: Cell<f32>,
canvas_size: Cell<f32>,
scrollbar_rect: Cell<Rect>,
scrollbar_dragging: Cell<Option<f32>>,
scrollbar_hovered: bool,
}

pub type HorizScrollResponse = ();

impl Widget for HorizScrollWidget {
type Props<'a> = HorizScroll;
type Response = HorizScrollResponse;

fn new() -> Self {
Self {
props: HorizScroll {
size: HorizScrollSize::Max,
},
scroll_position: Cell::new(0.0),
size: Cell::new(0.0),
canvas_size: Cell::new(0.0),
scrollbar_rect: Cell::new(Rect::ZERO),
scrollbar_dragging: Default::default(),
scrollbar_hovered: false,
}
}

fn update(&mut self, props: Self::Props<'_>) -> Self::Response {
self.props = props;
}

fn flex(&self) -> (u32, FlexFit) {
match self.props.size {
HorizScrollSize::Max => (1, FlexFit::Tight),
HorizScrollSize::Percent(_) => (1, FlexFit::Loose),
HorizScrollSize::Exact(_) => (0, FlexFit::Tight),
_ => (0, FlexFit::Loose),
}
}

fn layout(&self, mut ctx: LayoutContext<'_>, mut constraints: Constraints) -> Vec2 {
if self.props.size != HorizScrollSize::Max {
ctx.layout.enable_clipping(ctx.dom);
}

let node = ctx.dom.get_current();
let mut canvas_size = Vec2::ZERO;

let main_axis_size = match self.props.size {
HorizScrollSize::Max => constraints.max.x,
HorizScrollSize::Fixed(h) => {
constraints.max.x = constraints.max.x.min(h);
constraints.min.x
}
HorizScrollSize::Exact(h) => {
constraints.max.x = constraints.max.x.min(h);
constraints.min.x
}
HorizScrollSize::Percent(percent) => {
constraints.max.x *= percent;
constraints.min.x
}
};

canvas_size.x = main_axis_size;

let child_constraints = Constraints {
min: Vec2::new(0.0, constraints.min.y),
max: Vec2::new(1000000.0, constraints.max.y),
};

for &child in &node.children {
let child_size = ctx.calculate_layout(child, child_constraints);
canvas_size = canvas_size.max(child_size);
}

let mut size = constraints.constrain(canvas_size);
if let HorizScrollSize::Exact(_) = self.props.size {
size.x = size.x.max(constraints.max.x);
}

self.canvas_size.set(canvas_size.x);
self.size.set(size.x);

let max_scroll_position = (canvas_size.x - size.x).max(0.0);
let scroll_position = self.scroll_position.get().clamp(0.0, max_scroll_position);

self.scroll_position.set(scroll_position);

for &child in &node.children {
let off = Vec2::new(-scroll_position, 0.0);
ctx.layout.set_pos(child, off);
}

size
}

fn paint(&self, mut ctx: PaintContext<'_>) {
let drawn_rect = ctx.layout.get(ctx.dom.current()).unwrap().rect;
let node = ctx.dom.get_current();

for &child in &node.children {
ctx.paint(child);
}

let mut scrollbar_height: f32 = 4.0;
if self.scrollbar_hovered {
scrollbar_height = 5.0;
}
const SCROLLBAR_PAD_Y: f32 = 4.0;
const SCROLLBAR_PAD_X: f32 = 2.0;

if self.canvas_size.get() <= drawn_rect.size().x {
self.scrollbar_rect.set(Rect::ZERO);
return;
}
let scrollbar_progress =
self.scroll_position.get() / (self.canvas_size.get() - self.size.get());
let scroll_bar_width = drawn_rect.size().x * (drawn_rect.size().x / self.canvas_size.get());
let remaining_space = drawn_rect.size().x - scroll_bar_width - SCROLLBAR_PAD_X;

let pos_x = remaining_space * scrollbar_progress + SCROLLBAR_PAD_X * 0.5;

let scroll_bar_pos = drawn_rect.pos()
+ Vec2::new(
pos_x,
drawn_rect.size().y - scrollbar_height * 0.5 - SCROLLBAR_PAD_Y,
);
let scroll_bar_rect = Rect::from_pos_size(
scroll_bar_pos,
Vec2::new(scroll_bar_width, scrollbar_height),
);

self.scrollbar_rect.set(scroll_bar_rect);

let mut paint_rect = RoundedRectangle::new(scroll_bar_rect, 5.0);

let mut alpha = 0.5;
if self.scrollbar_hovered {
alpha = 0.7;
}
if self.scrollbar_dragging.get().is_some() {
alpha = 1.0;
}

paint_rect.color = Color::WHITE.with_alpha(alpha);
paint_rect.add(ctx.paint);
}

fn event_interest(&self) -> EventInterest {
EventInterest::MOUSE_ALL
}

fn event(&mut self, _ctx: EventContext<'_>, event: &WidgetEvent) -> EventResponse {
match *event {
WidgetEvent::MouseScroll { delta } => {
*self.scroll_position.get_mut() += delta.y;
EventResponse::Sink
}
WidgetEvent::MouseMoved(Some(pos)) => {
if let Some(last_pos) = self.scrollbar_dragging.get_mut() {
*self.scroll_position.get_mut() +=
(pos.x - *last_pos) * (*self.canvas_size.get_mut() / *self.size.get_mut());
*last_pos = pos.x;
return EventResponse::Sink;
} else {
self.scrollbar_hovered = self.scrollbar_rect.get_mut().contains_point(pos);
}
EventResponse::Bubble
}
WidgetEvent::MouseButtonChanged {
position,
button: MouseButton::One,
down,
..
} => {
if !down {
*self.scrollbar_dragging.get_mut() = None;
return EventResponse::Bubble;
}
if self.scrollbar_rect.get_mut().contains_point(position) {
*self.scrollbar_dragging.get_mut() = Some(position.x);
return EventResponse::Sink;
}
EventResponse::Bubble
}
_ => EventResponse::Bubble,
}
}
}
Loading

0 comments on commit fb871fc

Please sign in to comment.