Skip to content

Commit

Permalink
Add a progress ring instead of the bar
Browse files Browse the repository at this point in the history
This still looks broken, but I'm going to leave it as-is for now, and
figure out the layout later
  • Loading branch information
rdbende committed Jul 14, 2024
1 parent db4f685 commit 9c4788f
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 128 deletions.
2 changes: 1 addition & 1 deletion com.github.geigi.cozy.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"app-id": "com.github.geigi.cozy",
"runtime": "org.gnome.Platform",
"runtime-version": "46",
"runtime-version": "master",
"sdk": "org.gnome.Sdk",
"command": "com.github.geigi.cozy",
"finish-args": [
Expand Down
83 changes: 60 additions & 23 deletions cozy/ui/book_detail_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
import time
from threading import Event, Thread
from typing import Callable, Final
from math import pi as PI

from gi.repository import Adw, GLib, Gtk, GObject

from gi.repository import Adw, GLib, Gtk, GObject, Gdk, Graphene, Gsk
import cairo
from cozy.control.artwork_cache import ArtworkCache
from cozy.ext import inject
from cozy.model.book import Book
Expand All @@ -13,16 +14,61 @@
from cozy.ui.chapter_element import ChapterElement
from cozy.view_model.book_detail_view_model import BookDetailViewModel

log = logging.getLogger("BookDetailView")
log = logging.getLogger(__name__)

ALBUM_ART_SIZE: Final[int] = 256
PROGRESS_RING_LINE_WIDTH: Final[int] = 5


def call_in_main_thread(*args) -> None:
# TODO: move this elsewhere, it might come useful
GLib.MainContext.default().invoke_full(GLib.PRIORITY_DEFAULT_IDLE, *args)


class ProgressRing(Gtk.Widget):
__gtype_name__ = "ProgressRing"

progress = GObject.Property(type=float, default=0.0)

def __init__(self) -> None:
super().__init__()

self._style_manager = Adw.StyleManager()
self._style_manager.connect("notify::accent-color", self.redraw)
self.connect("notify::progress", self.redraw)

def redraw(self, *_) -> None:
self.queue_draw()

def do_measure(self, *_) -> tuple[int, int, int, int]:
return (40, 40, -1, -1)

def do_snapshot(self, snapshot: Gtk.Snapshot) -> None:
size = self.get_allocated_height()
radius = (size - 8) / 2.0

context = snapshot.append_cairo(Graphene.Rect().init(0, 0, size, size))

context.arc(size / 2, size / 2, radius, 0, 2 * PI)
context.set_source_rgba(*self.get_dim_color())
context.set_line_width(PROGRESS_RING_LINE_WIDTH)
context.stroke()

context.arc(size / 2, size / 2, radius, -0.5 * PI, self.progress * 2 * PI - (0.5 * PI))
context.set_source_rgb(*self.get_accent_color())
context.set_line_width(PROGRESS_RING_LINE_WIDTH)
context.set_line_cap(cairo.LineCap.ROUND)
context.stroke()

def get_dim_color(self) -> tuple[int, int, int, int]:
color = self.get_color()
return color.red, color.green, color.blue, 0.15

def get_accent_color(self) -> tuple[int, int, int]:
color = self._style_manager.get_accent_color_rgba()
return color.red, color.green, color.blue


class ChaptersListBox(Adw.PreferencesGroup):
def __init__(self, title: str):
super().__init__()
Expand All @@ -44,11 +90,10 @@ class BookDetailView(Adw.NavigationPage):

book_label: Gtk.Label = Gtk.Template.Child()
author_label: Gtk.Label = Gtk.Template.Child()
last_played_label: Gtk.Label = Gtk.Template.Child()
total_label: Gtk.Label = Gtk.Template.Child()

remaining_label: Gtk.Label = Gtk.Template.Child()
book_progress_bar: Gtk.ProgressBar = Gtk.Template.Child()

book_progress_ring: ProgressRing = Gtk.Template.Child()

download_box: Gtk.Box = Gtk.Template.Child()
download_label: Gtk.Label = Gtk.Template.Child()
Expand Down Expand Up @@ -89,11 +134,9 @@ def _connect_view_model(self):
self._view_model.bind_to("is_book_available", self._on_book_available_changed)
self._view_model.bind_to("downloaded", self._set_book_download_status)
self._view_model.bind_to("current_chapter", self._on_current_chapter_changed)
self._view_model.bind_to("last_played_text", self._on_last_played_text_changed)
self._view_model.bind_to("remaining_text", self._on_times_changed)
self._view_model.bind_to("progress_percent", self._on_times_changed)
self._view_model.bind_to("total_text", self._on_times_changed)
self._view_model.bind_to("playback_speed", self._on_times_changed)
self._view_model.bind_to("length", self._on_length_changed)
self._view_model.bind_to("progress", self._on_progress_changed)
self._view_model.bind_to("playback_speed", self._on_progress_changed)
self._view_model.bind_to("lock_ui", self._on_lock_ui_changed)

def _connect_widgets(self):
Expand Down Expand Up @@ -122,10 +165,8 @@ def _on_book_changed(self):
self.book_title = book.name
self.author_label.set_text(book.author)

self.last_played_label.set_text(self._view_model.last_played_text)

self._set_cover_image(book)
self._set_progress()
self._on_progress_changed()
self._display_external_section()

def _on_play_changed(self):
Expand Down Expand Up @@ -167,12 +208,12 @@ def _on_current_chapter_changed(self):
child.set_playing(self._view_model.playing)
break

def _on_last_played_text_changed(self):
self.last_played_label.set_text(self._view_model.last_played_text)

def _on_times_changed(self):
def _on_length_changed(self):
self.total_label.set_text(self._view_model.total_text)
self._set_progress()

def _on_progress_changed(self):
self.remaining_label.set_text(self._view_model.remaining_text)
self.book_progress_ring.progress = self._view_model.progress_percent

def _on_lock_ui_changed(self):
self.download_switch.set_sensitive(not self._view_model.lock_ui)
Expand Down Expand Up @@ -261,10 +302,6 @@ def _display_external_section(self):
self.download_switch.set_active(self._view_model.book.offline)
self.download_switch.handler_unblock_by_func(self._download_switch_changed)

def _set_progress(self):
self.remaining_label.set_text(self._view_model.remaining_text)
self.book_progress_bar.set_fraction(self._view_model.progress_percent)

def _set_cover_image(self, book: Book):
self.album_art_container.set_visible(False)

Expand Down
16 changes: 6 additions & 10 deletions cozy/view_model/book_detail_view_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,7 @@ def _on_player_event(self, event, message):
if event in {"play", "pause"}:
self._notify("playing")
elif event in {"position", "book-finished"}:
self._notify("progress_percent")
self._notify("remaining_text")
self._notify("progress")

def _on_fs_monitor_event(self, event, _):
if not self._book:
Expand All @@ -179,18 +178,15 @@ def _on_book_last_played_changed(self):
self._notify("last_played_text")

def _on_book_progress_changed(self):
self._notify("remaining_text")
self._notify("progress_percent")
self._notify("progress")

def _on_book_duration_changed(self):
self._notify("progress_percent")
self._notify("remaining_text")
self._notify("total_text")
self._notify("progress")
self._notify("length")

def _on_playback_speed_changed(self):
self._notify("progress_percent")
self._notify("remaining_text")
self._notify("total_text")
self._notify("progress")
self._notify("length")

def _on_offline_cache_event(self, event, message) -> None:
if self._book and isinstance(message, Book) and self._book.id == message.id and event in {"book-offline-removed", "book-offline"}:
Expand Down
165 changes: 71 additions & 94 deletions data/ui/book_detail.blp
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,81 @@ template $BookDetail: Adw.NavigationPage {
]
}

Button play_button {
focusable: true;
receives-default: true;
Box {
valign: end;
margin-top: 18;
spacing: 6;

$ProgressRing book_progress_ring {
valign: center;
}

Grid {
hexpand: true;
row-spacing: 3;
column-spacing: 20;

Label {
halign: start;
hexpand: true;
label: _("Remaining");

styles [
"dim-label",
]

layout {
column: 0;
row: 0;
}
}

Label remaining_label {
hexpand: true;
xalign: 0;

layout {
column: 1;
row: 0;
}
}

Label {
halign: start;
hexpand: true;
label: _("Total");

styles [
"dim-label",
]

layout {
column: 0;
row: 1;
}
}

Label total_label{
hexpand: true;
xalign: 0;

layout {
column: 1;
row: 1;
}
}
}
}

Button play_button {
halign: start;
valign: end;
vexpand: true;
margin-top: 12;
focusable: true;
receives-default: true;
tooltip-text: _("Start/Stop playback");

accessibility {
label: _("Start or pause the playback");
}
Expand All @@ -133,6 +200,7 @@ template $BookDetail: Adw.NavigationPage {
valign: center;
margin-bottom: 12;
spacing: 5;
visible: false;

Box download_box {
halign: end;
Expand All @@ -155,97 +223,6 @@ template $BookDetail: Adw.NavigationPage {
valign: center;
}
}

ProgressBar book_progress_bar {
width-request: 250;
halign: center;
valign: start;
show-text: true;
margin-bottom: 18;
}

Grid {
margin-bottom: 18;
hexpand: true;
row-spacing: 4;
column-spacing: 20;

Label remaining_text {
halign: start;
hexpand: true;
label: _("Remaining");

styles [
"dim-label",
]

layout {
column: '0';
row: '3';
}
}

Label remaining_label {
hexpand: true;
label: 'label';
xalign: 0;

layout {
column: '1';
row: '3';
}
}

Label total_label {
hexpand: true;
label: 'label';
xalign: 0;

layout {
column: '1';
row: '2';
}
}

Label last_played_label {
hexpand: true;
label: 'label';
xalign: 0;

layout {
column: '1';
row: '1';
}
}

Label {
halign: start;
label: _("Total");

styles [
"dim-label",
]

layout {
column: '0';
row: '2';
}
}

Label {
halign: start;
label: _("Last played");

styles [
"dim-label",
]

layout {
column: '0';
row: '1';
}
}
}
}
}

Expand Down

0 comments on commit 9c4788f

Please sign in to comment.