summaryrefslogtreecommitdiffstats
path: root/src/imgview.rs
blob: 93e1832555895abf6f3eb27b136a2c5b3220e263 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::widget::{Widget, WidgetCore};
use crate::coordinates::Coordinates;
use crate::fail::HResult;

use std::path::{Path, PathBuf};

use crate::mediaview::MediaError;

impl std::cmp::PartialEq for ImgView {
    fn eq(&self, other: &Self) -> bool {
        self.core == other.core &&
            self.buffer == other.buffer
    }
}

pub struct ImgView {
    pub core: WidgetCore,
    pub buffer: Vec<String>,
    pub file: PathBuf
}

impl ImgView {
    pub fn new_from_file(core: WidgetCore, file: &Path) -> HResult<ImgView> {
        let mut view = ImgView {
            core: core,
            buffer: vec![],
            file: file.to_path_buf()
        };

        view.encode_file()?;
        Ok(view)
    }

    pub fn encode_file(&mut self) -> HResult<()> {
        let (xsize, ysize) = self.core.coordinates.size_u();
        let (xpos, ypos) = self.core.coordinates.position_u();
        let file = &self.file;
        let media_previewer = self.core.config().media_previewer;

        let output = std::process::Command::new(&media_previewer)
            .arg(format!("{}", (xsize)))
            .arg(format!("{}", (ysize+1)))
            .arg(format!("{}", xpos))
            .arg(format!("{}", ypos))
            .arg("image")
            .arg(format!("true"))
            .arg(format!("true"))
            .arg(file.to_string_lossy().to_string())
            .output()
            .map_err(|e| {
                let msg = format!("Couldn't run {}{}{}! Error: {:?}",
                                  crate::term::color_red(),
                                  media_previewer,
                                  crate::term::normal_color(),
                                  &e.kind());

                self.core.show_status(&msg).ok();

                MediaError::NoPreviewer(msg)
            })?
            .stdout;


        let output = std::str::from_utf8(&output)?;
        let output = output.lines()
            .map(|l| l.to_string())
            .collect();

        self.buffer = output;

        Ok(())
    }

    pub fn set_image_data(&mut self, img_data: Vec<String>) {
        self.buffer = img_data;
    }

    pub fn lines(&self) -> usize {
        self.buffer.len()
    }
}


impl Widget for ImgView {
    fn get_core(&self) -> HResult<&WidgetCore> {
        Ok(&self.core)
    }

    fn get_core_mut(&mut self) -> HResult<&mut WidgetCore> {
        Ok(&mut self.core)
    }

    fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
        if &self.core.coordinates == coordinates { return Ok(()) }

        self.core.coordinates = coordinates.clone();
        self.encode_file()?;

        Ok(())
    }

    fn refresh(&mut self) -> HResult<()> {

        Ok(())
    }

    fn get_drawlist(&self) -> HResult<String> {
        let (xpos, ypos) = self.core.coordinates.position_u();

        let mut draw = self.buffer
            .iter()
            .enumerate()
            .fold(String::new(), |mut draw, (pos, line)| {
                draw += &format!("{}", crate::term::goto_xy_u(xpos+1,
                                                              ypos + pos));
                draw += line;
                draw
            });

        draw += &format!("{}", termion::style::Reset);

        Ok(draw)
    }
}