mirror of
https://github.com/JockeTF/fimfareader.git
synced 2024-11-27 07:28:00 +01:00
Add minimal functionality glue
This commit is contained in:
parent
c5b728564f
commit
e6760885c4
6 changed files with 271 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/target
|
/target
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
**/*~
|
||||||
|
|
|
@ -10,6 +10,11 @@ members = [
|
||||||
"gtk",
|
"gtk",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
default-members = [
|
||||||
|
"cli",
|
||||||
|
"gtk",
|
||||||
|
]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
|
||||||
|
|
82
gtk/src/components/app.rs
Normal file
82
gtk/src/components/app.rs
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
//! Application window.
|
||||||
|
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::BufReader;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
use gtk::*;
|
||||||
|
|
||||||
|
use fimfareader::archive::Fetcher;
|
||||||
|
use fimfareader::archive::Story;
|
||||||
|
use fimfareader::query::parse;
|
||||||
|
|
||||||
|
pub struct AppWindow {
|
||||||
|
fetcher: Fetcher<BufReader<File>>,
|
||||||
|
window: ApplicationWindow,
|
||||||
|
search: ToggleButton,
|
||||||
|
result: Mutex<TreeView>,
|
||||||
|
entry: Entry,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppWindow {
|
||||||
|
pub fn new(fetcher: Fetcher<BufReader<File>>) -> Option<Rc<Self>> {
|
||||||
|
let ui = include_str!("app.ui");
|
||||||
|
let builder = Builder::new_from_string(ui);
|
||||||
|
|
||||||
|
let this = Rc::new(Self {
|
||||||
|
fetcher: fetcher,
|
||||||
|
window: builder.get_object("app")?,
|
||||||
|
search: builder.get_object("search")?,
|
||||||
|
result: Mutex::new(builder.get_object("result")?),
|
||||||
|
entry: builder.get_object("entry")?,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.apply(this.fetcher.iter().collect());
|
||||||
|
Some(Self::connect(this))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect(self: Rc<Self>) -> Rc<Self> {
|
||||||
|
self.window.connect_destroy(move |_| gtk::main_quit());
|
||||||
|
|
||||||
|
let clone = self.clone();
|
||||||
|
self.entry.connect_activate(move |entry| {
|
||||||
|
let text = entry.get_text().unwrap();
|
||||||
|
clone.filter(text.as_str().trim());
|
||||||
|
});
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply(&self, stories: Vec<&Story>) {
|
||||||
|
let store = ListStore::new(&[
|
||||||
|
i64::static_type(),
|
||||||
|
String::static_type(),
|
||||||
|
String::static_type(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
for (i, story) in stories.iter().enumerate() {
|
||||||
|
store.insert_with_values(
|
||||||
|
Some(i as u32),
|
||||||
|
&[0, 1, 2],
|
||||||
|
&[&story.id, &story.title, &story.author.name],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = self.result.lock().unwrap();
|
||||||
|
result.set_model(Some(&store));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn filter(&self, query: &str) {
|
||||||
|
let filter = parse(query);
|
||||||
|
|
||||||
|
if filter.is_err() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let filter = filter.unwrap();
|
||||||
|
let vector = self.fetcher.filter(&filter);
|
||||||
|
|
||||||
|
self.apply(vector);
|
||||||
|
}
|
||||||
|
}
|
160
gtk/src/components/app.ui
Normal file
160
gtk/src/components/app.ui
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- Generated with glade 3.22.1
|
||||||
|
|
||||||
|
Copyright (C) 2019 Joakim Soderlund
|
||||||
|
|
||||||
|
This file is part of Fimfareader.
|
||||||
|
|
||||||
|
Fimfareader is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fimfareader is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fimfareader. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Author: Joakim Soderlund
|
||||||
|
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk+" version="3.20"/>
|
||||||
|
<!-- interface-license-type gplv3 -->
|
||||||
|
<!-- interface-name Fimfareader -->
|
||||||
|
<!-- interface-description Story browser for Fimfarchive -->
|
||||||
|
<!-- interface-copyright 2019 Joakim Soderlund -->
|
||||||
|
<!-- interface-authors Joakim Soderlund -->
|
||||||
|
<object class="GtkApplicationWindow" id="app">
|
||||||
|
<property name="width_request">800</property>
|
||||||
|
<property name="height_request">600</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">application-archive</property>
|
||||||
|
<child type="titlebar">
|
||||||
|
<object class="GtkHeaderBar">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="show_close_button">True</property>
|
||||||
|
<child type="title">
|
||||||
|
<object class="GtkEntry" id="entry">
|
||||||
|
<property name="width_request">500</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="truncate_multiline">True</property>
|
||||||
|
<property name="shadow_type">none</property>
|
||||||
|
<property name="caps_lock_warning">False</property>
|
||||||
|
<property name="primary_icon_name">search-symbolic</property>
|
||||||
|
<property name="placeholder_text" translatable="yes">Search...</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkMenuButton" id="menu">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="focus_on_click">False</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="icon_name">open-menu-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkToggleButton" id="search">
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="focus_on_click">False</property>
|
||||||
|
<property name="receives_default">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkImage">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">False</property>
|
||||||
|
<property name="stock">gtk-find</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
<packing>
|
||||||
|
<property name="pack_type">end</property>
|
||||||
|
<property name="position">2</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="shadow_type">in</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeView" id="result">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="enable_search">False</property>
|
||||||
|
<property name="show_expanders">False</property>
|
||||||
|
<child internal-child="selection">
|
||||||
|
<object class="GtkTreeSelection"/>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn" id="id_column">
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="sizing">fixed</property>
|
||||||
|
<property name="fixed_width">100</property>
|
||||||
|
<property name="min_width">75</property>
|
||||||
|
<property name="max_width">200</property>
|
||||||
|
<property name="title" translatable="yes">ID</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">0</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn" id="title_column">
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="sizing">fixed</property>
|
||||||
|
<property name="fixed_width">300</property>
|
||||||
|
<property name="min_width">100</property>
|
||||||
|
<property name="max_width">400</property>
|
||||||
|
<property name="title" translatable="yes">Title</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">1</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkTreeViewColumn" id="author_column">
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="sizing">autosize</property>
|
||||||
|
<property name="fixed_width">300</property>
|
||||||
|
<property name="min_width">100</property>
|
||||||
|
<property name="max_width">500</property>
|
||||||
|
<property name="title" translatable="yes">Author</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkCellRendererText"/>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="text">2</attribute>
|
||||||
|
</attributes>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</interface>
|
5
gtk/src/components/mod.rs
Normal file
5
gtk/src/components/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
// UI module.
|
||||||
|
|
||||||
|
mod app;
|
||||||
|
|
||||||
|
pub use self::app::AppWindow;
|
|
@ -2,6 +2,23 @@
|
||||||
|
|
||||||
use fimfareader::prelude::*;
|
use fimfareader::prelude::*;
|
||||||
|
|
||||||
|
use components::AppWindow;
|
||||||
|
|
||||||
|
mod components;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
Err(Error::usage("Not implemented"))
|
gtk::init().map_err(|e| match e {
|
||||||
|
_ => Error::usage("Could not initialize GTK"),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let fetcher = Fetcher::from("fimfarchive.zip")?;
|
||||||
|
|
||||||
|
let _window = match AppWindow::new(fetcher) {
|
||||||
|
Some(window) => Ok(window),
|
||||||
|
None => Err(Error::usage("Could not create main window")),
|
||||||
|
}?;
|
||||||
|
|
||||||
|
gtk::main();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue