Skip to content

Commit

Permalink
Add mouse interaction to Yle Image Gui
Browse files Browse the repository at this point in the history
* Mouse will point to links on hover
* New page will be loaded when mouse is clicked while hovering
  • Loading branch information
Nykseli committed Jan 31, 2023
1 parent 8f625a0 commit f31e07f
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 17 deletions.
18 changes: 12 additions & 6 deletions src/gui/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{
time::Duration,
};

use egui::{self, InputState, Key::*};
use egui::{self, InputState, Key::*, PointerState};

use crate::parser::{HtmlItem, HtmlLink, HtmlLoader, HtmlParser};

Expand Down Expand Up @@ -183,7 +183,7 @@ pub enum FetchState<T: HtmlParser> {
}

pub trait IGuiCtx {
fn handle_input(&mut self, input: &InputState);
fn handle_input(&mut self, input: InputState);
fn draw(&mut self, ui: &mut egui::Ui);
fn set_refresh_interval(&mut self, interval: u64);
fn stop_refresh_interval(&mut self);
Expand All @@ -199,6 +199,7 @@ pub struct GuiContext<T: HtmlParser + TelePager + Send + 'static> {
pub history: TeleHistory,
pub page_buffer: Vec<i32>,
pub worker: Option<GuiWorker>,
pub pointer: PointerState,
}

impl<T: HtmlParser + TelePager + Send + 'static> GuiContext<T> {
Expand All @@ -212,6 +213,7 @@ impl<T: HtmlParser + TelePager + Send + 'static> GuiContext<T> {
page_buffer: Vec::with_capacity(3),
history: TeleHistory::new(current_page),
worker: None,
pointer: Default::default(),
}
}

Expand All @@ -230,17 +232,18 @@ impl<T: HtmlParser + TelePager + Send + 'static> GuiContext<T> {
page_buffer: Vec::with_capacity(3),
history: TeleHistory::new(current_page),
worker: None,
pointer: Default::default(),
}
}

pub fn handle_input(&mut self, input: &InputState) {
pub fn handle_input(&mut self, input: InputState) {
// Ignore input while fetching
match *self.state.lock().unwrap() {
FetchState::Complete(_) => {}
_ => return,
};

if let Some(num) = input_to_num(input) {
if let Some(num) = input_to_num(&input) {
if self.page_buffer.len() < 3 {
self.page_buffer.push(num);
}
Expand All @@ -252,16 +255,19 @@ impl<T: HtmlParser + TelePager + Send + 'static> GuiContext<T> {
}
}

// After keyboard stuff is handled, move the ownership of pointer to self and
// deal with mouse inputs
self.pointer = input.pointer;
// prev
if input.pointer.button_released(egui::PointerButton::Extra1) {
if self.pointer.button_released(egui::PointerButton::Extra1) {
if let Some(page) = self.history.prev() {
self.current_page = page;
self.load_current_page();
}
}

// next
if input.pointer.button_released(egui::PointerButton::Extra2) {
if self.pointer.button_released(egui::PointerButton::Extra2) {
if let Some(page) = self.history.next() {
self.current_page = page;
self.load_current_page();
Expand Down
5 changes: 1 addition & 4 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,6 @@ impl TeleTextApp {
TeleTextSettings::default()
};

/* let mut page = Box::new(GuiYleImageContext::new(GuiContext::new(
ctx.egui_ctx.clone(),
))) as Box<dyn IGuiCtx>; */
let mut page = settings.open_page.to_gui(&ctx.egui_ctx);
let page_ref = &mut page as &mut Box<dyn IGuiCtx>;

Expand Down Expand Up @@ -226,7 +223,7 @@ impl eframe::App for TeleTextApp {

egui::CentralPanel::default().show(ctx, |ui| {
if let Some(page) = page {
page.handle_input(&input);
page.handle_input(input);
page.draw(ui);
}
});
Expand Down
37 changes: 31 additions & 6 deletions src/gui/yle_image.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::{cell::RefCell, ops::Deref, rc::Rc};

use egui::{FontId, InputState, RichText, TextStyle};
use egui::{CursorIcon, FontId, InputState, RichText, TextStyle};
use egui_extras::RetainedImage;

use crate::parser::{HtmlLink, HtmlText, YleImage};
use crate::parser::{common::HtmlImageArea, HtmlLink, HtmlText, YleImage};

use super::common::{FetchState, GuiContext, IGuiCtx, PageDraw, TelePage, TelePager};

Expand Down Expand Up @@ -82,11 +82,36 @@ impl<'a> GuiYleImage<'a> {
}
}

fn draw_image(&mut self, image: &[u8]) {
fn draw_image(&mut self, image: &[u8], image_map: &Vec<HtmlImageArea>) {
let mut ctx = self.ctx.borrow_mut();
let pos = ctx.pointer.hover_pos();
let clicked = ctx.pointer.primary_released();
self.ui
.with_layout(egui::Layout::top_down(egui::Align::Center), |ui| {
let image = RetainedImage::from_image_bytes("debug_name", image).unwrap();
image.show_max_size(ui, ui.available_size());

let resp = image.show_max_size(ui, ui.available_size());
if let Some(pos) = pos {
let rh = resp.rect.max.y - resp.rect.min.y;
let rw = resp.rect.max.x - resp.rect.min.x;
// The aspect ratio of the image will stay the same as it's being scaled
// so the scale of width and height will be the same
let scale = rw / (image.size()[0] as f32);
// Translate the pointer to be inside of the image
let px = pos.x - resp.rect.min.x;
let py = pos.y - resp.rect.min.y;
if px > 0.0 && px < rw && py > 0.0 && py < rh {
for area in image_map {
if area.in_area(px, py, scale) {
ui.ctx().output().cursor_icon = CursorIcon::PointingHand;
if clicked {
ctx.load_page(&area.link, true);
}
break;
}
}
}
}
});
}

Expand Down Expand Up @@ -165,7 +190,7 @@ impl<'a> PageDraw<'a, YleImage> for GuiYleImage<'a> {
match state.lock().unwrap().deref() {
FetchState::Complete(page) => {
self.draw_header(&page.title);
self.draw_image(&page.image);
self.draw_image(&page.image, &page.image_map);
self.draw_page_navigation(&page.botton_navigation);
}
FetchState::Fetching => {
Expand Down Expand Up @@ -231,7 +256,7 @@ impl GuiYleImageContext {
}

impl IGuiCtx for GuiYleImageContext {
fn handle_input(&mut self, input: &InputState) {
fn handle_input(&mut self, input: InputState) {
self.ctx.handle_input(input)
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/yle_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ impl GuiYleTextContext {
}

impl IGuiCtx for GuiYleTextContext {
fn handle_input(&mut self, input: &InputState) {
fn handle_input(&mut self, input: InputState) {
self.ctx.handle_input(input)
}

Expand Down

0 comments on commit f31e07f

Please sign in to comment.