Skip to content

Commit

Permalink
add some animation
Browse files Browse the repository at this point in the history
  • Loading branch information
tsukinaha committed Mar 27, 2024
1 parent 6008a6d commit 1ef6773
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 7 deletions.
1 change: 1 addition & 0 deletions resources/resources.gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
<file compressed="true" preprocess="xml-stripblanks">item.ui</file>
<file compressed="true" preprocess="xml-stripblanks">movie.ui</file>
<file compressed="true" preprocess="xml-stripblanks">history.ui</file>
<file compressed="true" preprocess="xml-stripblanks">episoderow.ui</file>
</gresource>
</gresources>
13 changes: 13 additions & 0 deletions resources/ui/episoderow.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="EpisodeRow" parent="GtkBox">
<child>
<object class="GtkPicture" id="image">
</object>
</child>
<child>
<object class="GtkLabel" id="content_label">
</object>
</child>
</template>
</interface>
9 changes: 8 additions & 1 deletion resources/ui/history.ui
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@
</object>
</child>
<child>
<object class="GtkGridView" id="historygrid">
<object class="GtkRevealer" id="historyrevealer">
<property name="transition-type">crossfade</property>
<property name="transition-duration">700</property>
<property name="reveal-child">False</property>
<child>
<object class="GtkGridView" id="historygrid">
</object>
</child>
</object>
</child>
</object>
Expand Down
10 changes: 8 additions & 2 deletions resources/ui/item.ui
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,14 @@
<property name="valign">fill</property>
<property name="margin-bottom">3</property>
<child>
<object class="GtkListView" id="itemlist">
<property name="orientation">horizontal</property>
<object class="GtkRevealer" id="itemrevealer">
<property name="transition-duration">700</property>
<property name="reveal-child">False</property>
<child>
<object class="GtkListView" id="itemlist">
<property name="orientation">horizontal</property>
</object>
</child>
</object>
</child>
</object>
Expand Down
9 changes: 8 additions & 1 deletion resources/ui/search.ui
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@
</object>
</child>
<child>
<object class="GtkGridView" id="searchgrid">
<object class="GtkRevealer" id="searchrevealer">
<property name="transition-type">crossfade</property>
<property name="transition-duration">700</property>
<property name="reveal-child">False</property>
<child>
<object class="GtkGridView" id="searchgrid">
</object>
</child>
</object>
</child>
</object>
Expand Down
2 changes: 1 addition & 1 deletion src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

mod provider;
mod image;
mod network;
mod new_dropsel;
Expand Down
58 changes: 58 additions & 0 deletions src/ui/provider/episoderowitem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
mod imp {
use std::cell::RefCell;

use glib::Properties;
use gtk::glib;
use gtk::prelude::*;
use gtk::subclass::prelude::*;

use super::TaskData;

// ANCHOR: struct_and_subclass
// Object holding the state
#[derive(Properties, Default)]
#[properties(wrapper_type = super::EpisodeObject)]
pub struct EpisodeObject {
#[property(name = "imageid", get, set, type = String, member = imageid)]
#[property(name = "label", get, set, type = String, member = label)]
pub data: RefCell<TaskData>,
}

// The central trait for subclassing a GObject
#[glib::object_subclass]
impl ObjectSubclass for EpisodeObject {
const NAME: &'static str = "EpisodeObject";
type Type = super::EpisodeObject;
}

// Trait shared by all GObjects
#[glib::derived_properties]
impl ObjectImpl for EpisodeObject {}
// ANCHOR_END: struct_and_subclass
}

use glib::Object;
use gtk::glib;

// ANCHOR: glib_wrapper_and_new
glib::wrapper! {
pub struct EpisodeObject(ObjectSubclass<imp::EpisodeObject>);
}

impl EpisodeObject {
pub fn new(imageid: bool, label: String) -> Self {
Object::builder()
.property("imageid", imageid)
.property("label", label)
.build()
}
}
// ANCHOR_END: glib_wrapper_and_new

// ANCHOR: task_data
#[derive(Default)]
pub struct TaskData {
pub imageid: String,
pub label: String,
}
// ANCHOR: task_data
1 change: 1 addition & 0 deletions src/ui/provider/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod episoderowitem;
102 changes: 102 additions & 0 deletions src/ui/widgets/episoderow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use glib::Object;
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use gtk::{glib, pango};
use pango::{AttrInt, AttrList};

use crate::ui::provider::episoderowitem::EpisodeObject;

mod imp {
use std::cell::RefCell;

use glib::Binding;
use gtk::subclass::prelude::*;
use gtk::{glib, CheckButton, CompositeTemplate, Label, Picture};

// Object holding the state
#[derive(Default, CompositeTemplate)]
#[template(resource = "/moe/tsukimi/episoderow.ui")]
pub struct EpisodeRow {
#[template_child]
pub image: TemplateChild<Picture>,
#[template_child]
pub content_label: TemplateChild<Label>,
// Vector holding the bindings to properties of `TaskObject`
pub bindings: RefCell<Vec<Binding>>,
}

// The central trait for subclassing a GObject
#[glib::object_subclass]
impl ObjectSubclass for EpisodeRow {
// `NAME` needs to match `class` attribute of template
const NAME: &'static str = "EpisodeRow";
type Type = super::EpisodeRow;
type ParentType = gtk::Box;

fn class_init(klass: &mut Self::Class) {
klass.bind_template();
}

fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
obj.init_template();
}
}

// Trait shared by all GObjects
impl ObjectImpl for EpisodeRow {}

// Trait shared by all widgets
impl WidgetImpl for EpisodeRow {}

// Trait shared by all boxes
impl BoxImpl for EpisodeRow {}
}

glib::wrapper! {
pub struct EpisodeRow(ObjectSubclass<imp::EpisodeRow>)
@extends gtk::Box, gtk::Widget,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}

impl Default for EpisodeRow {
fn default() -> Self {
Self::new()
}
}

impl EpisodeRow {
pub fn new() -> Self {
Object::builder().build()
}

pub fn bind(&self, episode_object: &EpisodeObject) {
// Get state
let image = self.imp().image.get();
let content_label = self.imp().content_label.get();
let mut bindings = self.imp().bindings.borrow_mut();

// Bind `task_object.completed` to `task_row.completed_button.active`
let image_binding = episode_object
.bind_property("completed", &image, "active")
.bidirectional()
.sync_create()
.build();
// Save binding
bindings.push(image_binding);

// Bind `task_object.content` to `task_row.content_label.label`
let content_label_binding = episode_object
.bind_property("content", &content_label, "label")
.sync_create()
.build();
// Save binding
bindings.push(content_label_binding);
}

pub fn unbind(&self) {
// Unbind all stored bindings
for binding in self.imp().bindings.borrow_mut().drain(..) {
binding.unbind();
}
}
}
4 changes: 4 additions & 0 deletions src/ui/widgets/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ mod imp {
pub spinner: TemplateChild<gtk::Spinner>,
#[template_child]
pub historyscrolled: TemplateChild<gtk::ScrolledWindow>,
#[template_child]
pub historyrevealer: TemplateChild<gtk::Revealer>,
pub selection: gtk::SingleSelection,
}

Expand All @@ -55,6 +57,7 @@ mod imp {
self.parent_constructed();
let obj = self.obj();
let spinner = self.spinner.get();
let historyrevealer = self.historyrevealer.get();
spinner.set_visible(true);
let (sender, receiver) = async_channel::bounded::<Vec<crate::ui::network::Resume>>(1);
crate::ui::network::runtime().spawn(glib::clone!(@strong sender => async move {
Expand All @@ -72,6 +75,7 @@ mod imp {
store.append(&object);
}
spinner.set_visible(false);
historyrevealer.set_reveal_child(true);
}
}));

Expand Down
6 changes: 5 additions & 1 deletion src/ui/widgets/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ mod imp {
pub itemlist: TemplateChild<gtk::ListView>,
#[template_child]
pub osdbox: TemplateChild<gtk::Box>,
#[template_child]
pub itemrevealer: TemplateChild<gtk::Revealer>,
pub selection: gtk::SingleSelection,
}

Expand All @@ -49,6 +51,7 @@ mod imp {
fn constructed(&self) {
self.parent_constructed();
let obj = self.obj();
let itemrevealer = self.itemrevealer.get();
let id = obj.id();
let path = format!(
"{}/.local/share/tsukimi/b{}.png",
Expand Down Expand Up @@ -110,6 +113,7 @@ mod imp {
let object = glib::BoxedAnyObject::new(info);
store.append(&object);
}
itemrevealer.set_reveal_child(true);
});

let factory = gtk::SignalListItemFactory::new();
Expand All @@ -120,7 +124,7 @@ mod imp {
let vbox = gtk::Box::new(gtk::Orientation::Vertical, 5);
let label = gtk::Label::new(Some(&seriesinfo.Name));
label.set_halign(gtk::Align::Start);
let markup = format!("E{} : {}", seriesinfo.IndexNumber, seriesinfo.Name);
let markup = format!("{}. {}", seriesinfo.IndexNumber, seriesinfo.Name);
label.set_markup(markup.as_str());
label.set_ellipsize(gtk::pango::EllipsizeMode::End);
label.set_size_request(-1,20);
Expand Down
3 changes: 2 additions & 1 deletion src/ui/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ pub mod settings;
pub mod search;
pub mod item;
pub mod movie;
pub mod history;
pub mod history;
pub mod episoderow;
5 changes: 5 additions & 0 deletions src/ui/widgets/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ mod imp {
pub spinner: TemplateChild<gtk::Spinner>,
#[template_child]
pub searchscrolled: TemplateChild<gtk::ScrolledWindow>,
#[template_child]
pub searchrevealer: TemplateChild<gtk::Revealer>,
pub selection: gtk::SingleSelection,
}

Expand All @@ -57,6 +59,8 @@ mod imp {
let obj = self.obj();
self.parent_constructed();
let spinner = self.spinner.get();
let searchrevealer = self.searchrevealer.get();

let (sender, receiver) = async_channel::bounded::<Vec<crate::ui::network::SearchResult>>(1);
self.searchentry.connect_activate(glib::clone!(@strong sender,@weak spinner=> move |entry| {
spinner.set_visible(true);
Expand All @@ -81,6 +85,7 @@ mod imp {
store.append(&object);
}
}
searchrevealer.set_reveal_child(true);
}
}));

Expand Down

0 comments on commit 1ef6773

Please sign in to comment.