Skip to content

Commit

Permalink
Code reorganization is finished.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArturKovacs committed Aug 3, 2018
1 parent 8da82c3 commit b8d83fc
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 312 deletions.
4 changes: 3 additions & 1 deletion src/image_cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub mod errors {
}

use self::errors::*;
pub use self::errors::Result;

pub struct ImageCache {
dir_path: PathBuf,
Expand All @@ -37,6 +38,7 @@ pub struct ImageCache {
}

/// This is a store for the supported images loaded from a folder
///
/// The basic idea is to have a few images already in the memory while an image is shown on the screen
impl ImageCache {
/// # Arguemnts
Expand All @@ -51,7 +53,7 @@ impl ImageCache {
}
}

pub fn current_file_name<'a>(&'a self) -> &'a OsString {
pub fn current_filename<'a>(&'a self) -> &'a OsString {
&self.current_name
}

Expand Down
125 changes: 80 additions & 45 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,26 @@ extern crate sys_info;
extern crate backtrace;

use std::env;
use std::ffi::OsString;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::cell::RefCell;
use std::thread;
use std::time::{Duration, Instant};
use std::time::Duration;

use glium::glutin::{VirtualKeyCode, WindowEvent};
use glium::{glutin, Surface};
use glium::glutin::dpi::LogicalSize;
use glium::texture::{RawImage2d, SrgbTexture2d};

use glium::glutin::EventsLoop;

use cgmath::ElementWise;
use cgmath::SquareMatrix;
use cgmath::{Matrix4, Vector2, Vector4};

mod image_cache;
use image_cache::ImageCache;

mod handle_panic;
mod ui;
mod shaders;

mod picture_controller;
use picture_controller::PictureController;
mod picture_panel;
use picture_panel::PicturePanel;

mod playback_manager;
use playback_manager::{PlaybackManager, LoadRequest};

mod window;
use window::*;
Expand Down Expand Up @@ -64,45 +57,91 @@ fn texture_from_image(
).unwrap()
}


trait OptionRefClone {
fn ref_clone(&self) -> Self;
}

impl OptionRefClone for Option<Rc<glium::texture::SrgbTexture2d>> {
fn ref_clone(&self) -> Option<Rc<glium::texture::SrgbTexture2d>> {
match *self {
Some(ref image) => Some(image.clone()),
None => None,
}
}
}


struct Program {
window: Window,
ui: ui::Ui,
picture_controller: PictureController,
picture_panel: PicturePanel,
playback_manager: RefCell<PlaybackManager>,
}

impl Program {
fn draw_picture(window: &mut Window, picture_controller: &mut PicturePanel) {
let mut target = window.display().draw();

target.clear_color(0.9, 0.9, 0.9, 0.0);
picture_controller.draw(&mut target, window);
target.finish().unwrap();
}

fn start() {
let mut events_loop = glutin::EventsLoop::new();
let mut window = Window::init(&events_loop);
let mut picture_panel = PicturePanel::new(window.display());
let playback_manager = RefCell::new(PlaybackManager::new());

// Load image
if let Some(img_path) = env::args().skip(1).next() {
let img_path = PathBuf::from(img_path);
let mut playback_manager = playback_manager.borrow_mut();
playback_manager.request_load(LoadRequest::LoadSpecific(img_path));
playback_manager.update_image(&mut window);
picture_panel.set_image(playback_manager.image_texture().ref_clone());
} else {
window.set_title_filename("Drag and drop an image on the window.");
}

// TODO INITIALIZE THE UI AFTER THE IMAGE IS VISIBLE ON THE SCREEN.
let mut ui = ui::Ui::new(&window.display, Window::BOTTOM_PANEL_HEIGHT);
// Just quickly display the loaded image here before we load the remaining parts of the program
Self::draw_picture(&mut window, &mut picture_panel);

let mut ui = ui::Ui::new(window.display(), Window::BOTTOM_PANEL_HEIGHT);
let exe_parent = std::env::current_exe().unwrap().parent().unwrap().to_owned();

let button_texture = Rc::new(
load_texture_without_cache(
&window.display,
window.display(),
&exe_parent.join("cogs.png")
)
);

let button = ui.create_button(button_texture, ||());

if let Some(button) = ui.get_button_mut(button) {
button.set_callback(Box::new(|| println!("Clicked!")));
button.set_callback(Box::new(|| {
// TODO I want to write something like this:
// playback_manager.borrow_mut().request_load(LoadRequest::LoadNext);
println!("Clicked!");
}));
}

let mut picture_controller = PictureController::new(&window.display);


let mut program = Program {
window,
ui,
picture_controller
picture_panel,
playback_manager
};

program.start_event_loop(&mut events_loop);
}

fn load_ui(&mut self) {

}

fn start_event_loop(&mut self, events_loop: &mut glutin::EventsLoop) {
let mut running = true;
// the main loop
Expand All @@ -127,13 +166,12 @@ impl Program {
}

// Pre events
self.window.pre_events();
self.picture_controller.pre_events();
self.picture_panel.pre_events();

// Dispatch event
self.picture_controller.handle_event(&event, &mut self.window);
self.picture_panel.handle_event(&event, &mut self.window, &mut self.playback_manager.borrow_mut());
if let Event::WindowEvent { ref event, .. } = event {
let window_size = self.window.display.gl_window().get_inner_size().unwrap();
let window_size = self.window.display().gl_window().get_inner_size().unwrap();
self.ui.window_event(&event, window_size);
}

Expand All @@ -146,30 +184,27 @@ impl Program {
}
});

self.window.update_playback();

if self.window.load_request != LoadRequest::None {
let image = match self.window.image_texture {
Some(ref image) => Some(image.clone()),
None => None,
};
self.picture_controller.set_image(image);
}
let load_requested = {
let mut playback_manager = self.playback_manager.borrow_mut();
playback_manager.update_image(&mut self.window);
self.picture_panel.set_image(playback_manager.image_texture().ref_clone());

*playback_manager.load_request() != LoadRequest::None
};
self.draw();

// Update dirctory only after draw
if self.window.load_request != LoadRequest::None {
self.window.image_cache.update_directory().unwrap();
let mut playback_manager = self.playback_manager.borrow_mut();
// Update dirctory after draw
if load_requested {
playback_manager.update_directory().unwrap();
}

let should_sleep = {
self.window.should_sleep()
&& self.picture_controller.should_sleep()
&& self.window.load_request == LoadRequest::None
playback_manager.should_sleep()
&& self.picture_panel.should_sleep()
&& !load_requested
};


// Let other processes run for a bit.
//thread::yield_now();
if should_sleep {
Expand All @@ -179,11 +214,11 @@ impl Program {
}

fn draw(&mut self) {
let mut target = self.window.display.draw();
let mut target = self.window.display().draw();

target.clear_color(0.9, 0.9, 0.9, 0.0);

self.picture_controller.draw(&mut target, &self.window);
self.picture_panel.draw(&mut target, &self.window);
self.ui.draw(&mut target);

target.finish().unwrap();
Expand Down
64 changes: 30 additions & 34 deletions src/picture_controller.rs → src/picture_panel.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@

use std::env;
use std::ffi::OsString;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use std::rc::Rc;
use std::thread;
use std::time::{Duration, Instant};
use std::mem;

use glium;
use glium::glutin::{VirtualKeyCode, WindowEvent};
use glium::glutin::dpi::LogicalSize;
use glium::texture::{RawImage2d, SrgbTexture2d};
use glium::index::PrimitiveType;

use glium::{Display, Rect, Frame, Surface, VertexBuffer, IndexBuffer, Program};
use glium::{Frame, Surface};
use glium::glutin;


Expand All @@ -25,6 +19,7 @@ use cgmath::{Matrix4, Vector2, Vector4};
use shaders;

use window::*;
use playback_manager::*;

#[derive(Copy, Clone)]
struct Vertex {
Expand All @@ -39,7 +34,7 @@ enum FileHoverState {
HoveredFile{prev_file: PathBuf}
}

pub struct PictureController {
pub struct PicturePanel {
vertex_buffer: glium::VertexBuffer<Vertex>,
index_buffer: glium::IndexBuffer<u16>,
program: glium::Program,
Expand All @@ -62,8 +57,8 @@ pub struct PictureController {
should_sleep: bool,
}

impl PictureController {
pub fn new(display: &glium::Display) -> PictureController {
impl PicturePanel {
pub fn new(display: &glium::Display) -> PicturePanel {
// Clear the screen right at the start so that the user sees the background color
// whilst the image is loading.
{
Expand Down Expand Up @@ -115,7 +110,7 @@ impl PictureController {
},
).unwrap();

PictureController {
PicturePanel {
vertex_buffer,
index_buffer,
program,
Expand Down Expand Up @@ -147,10 +142,15 @@ impl PictureController {
self.image_texture = image_texture;
}

pub fn handle_event(&mut self, event: &glutin::Event, window: &mut Window) {
pub fn handle_event(
&mut self,
event: &glutin::Event,
window: &mut Window,
playback_manager: &mut PlaybackManager
) {
match event {
glutin::Event::WindowEvent { event, .. } => {
let window_size = window.display.gl_window().get_inner_size().unwrap();
let window_size = window.display().gl_window().get_inner_size().unwrap();
let panel_size = Self::get_panel_size(window_size);
match event {
WindowEvent::KeyboardInput { input, .. } => {
Expand All @@ -159,25 +159,21 @@ impl PictureController {
match keycode {
VirtualKeyCode::Right | VirtualKeyCode::Left => {
if keycode == VirtualKeyCode::Right {
window.request_load(LoadRequest::LoadNext);
playback_manager.request_load(LoadRequest::LoadNext);
} else {
window.request_load(LoadRequest::LoadPrevious);
playback_manager.request_load(LoadRequest::LoadPrevious);
}
}
VirtualKeyCode::Space => {
window.playback_state =
if window.playback_state == PlaybackState::Forward {
let filename = window
.image_cache
.current_file_name().to_str().unwrap().to_owned();
window.set_title_filename(filename.as_ref());
PlaybackState::Paused
} else {
window.set_title_filename("PLAYING");
window.playback_start_time = Instant::now();
window.frame_count_since_playback_start = 0;
PlaybackState::Forward
};
if playback_manager.playback_state() == PlaybackState::Forward {
playback_manager.pause_playback();
let filename = playback_manager
.current_filename().to_str().unwrap().to_owned();
window.set_title_filename(filename.as_ref());
} else {
playback_manager.start_playback_forward();
window.set_title_filename("PLAYING");
};
}
VirtualKeyCode::R => {
self.zoom_scale = 1.0;
Expand Down Expand Up @@ -275,20 +271,20 @@ impl PictureController {
}
}
WindowEvent::HoveredFile(file_name) => {
self.file_hover_state = FileHoverState::HoveredFile{prev_file: window.image_cache.current_file_path()};
window.load_request = LoadRequest::LoadSpecific(file_name.clone());
self.file_hover_state = FileHoverState::HoveredFile{prev_file: playback_manager.current_file_path()};
playback_manager.request_load(LoadRequest::LoadSpecific(file_name.clone()));
}
WindowEvent::HoveredFileCancelled => {
let mut tmp_hover_state = FileHoverState::Idle;
mem::swap(&mut self.file_hover_state, &mut tmp_hover_state);
if let FileHoverState::HoveredFile{prev_file} = tmp_hover_state {
window.load_request = LoadRequest::LoadSpecific(prev_file);
playback_manager.request_load(LoadRequest::LoadSpecific(prev_file));
}
}
WindowEvent::DroppedFile(file_name) => {
match self.file_hover_state {
FileHoverState::Idle => {
window.load_request = LoadRequest::LoadSpecific(file_name.clone());
playback_manager.request_load(LoadRequest::LoadSpecific(file_name.clone()));
}
_ => (),
}
Expand All @@ -302,7 +298,7 @@ impl PictureController {


pub fn draw(&mut self, target: &mut Frame, window: &Window) {
let window_size = window.display.gl_window().get_inner_size().unwrap();
let window_size = window.display().gl_window().get_inner_size().unwrap();
let panel_size = Self::get_panel_size(window_size);

self.update_projection_transform(panel_size);
Expand Down
Loading

0 comments on commit b8d83fc

Please sign in to comment.