Commit aa06f0f6 authored by Bilal Elmoussaoui's avatar Bilal Elmoussaoui

subclass PaginatorWidget

parent 8f181ddc
......@@ -68,7 +68,7 @@ mod imp {
"next-page",
clone!(@weak application => move |_, _| {
let window = application.window();
if window.paginator.borrow_mut().try_next().is_none() {
if window.paginator.try_next().is_none() {
window.widget.close();
}
}),
......@@ -79,7 +79,7 @@ mod imp {
"previous-page",
clone!(@weak application => move |_, _| {
let window = application.window();
if window.paginator.borrow_mut().try_previous().is_none() {
if window.paginator.try_previous().is_none() {
window.reset_tour();
}
}),
......
use gettextrs::gettext;
use gtk::glib::{self, clone};
use gtk::prelude::*;
use gtk::{
glib::{self, clone},
subclass::prelude::*,
};
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Debug)]
pub struct PaginatorWidget {
pub widget: gtk::Box,
carousel: adw::Carousel,
carousel_dots: adw::CarouselIndicatorDots,
headerbar: gtk::HeaderBar,
pages: RefCell<Vec<gtk::Widget>>,
current_page: RefCell<u32>,
next_overlay: gtk::Overlay,
next_btn: gtk::Button,
start_btn: gtk::Button,
finish_btn: gtk::Button,
close_btn: gtk::Button,
previous_btn: gtk::Button,
mod imp {
use std::cell::Cell;
use super::*;
#[derive(Debug)]
pub struct PaginatorWidget {
pub(super) carousel: adw::Carousel,
pub(super) carousel_dots: adw::CarouselIndicatorDots,
pub(super) headerbar: gtk::HeaderBar,
pub(super) pages: RefCell<Vec<gtk::Widget>>,
pub(super) current_page: Cell<u32>,
pub(super) next_overlay: gtk::Overlay,
pub(super) next_btn: gtk::Button,
pub(super) start_btn: gtk::Button,
pub(super) finish_btn: gtk::Button,
pub(super) close_btn: gtk::Button,
pub(super) previous_btn: gtk::Button,
}
impl Default for PaginatorWidget {
fn default() -> Self {
Self {
carousel: adw::Carousel::new(),
carousel_dots: adw::CarouselIndicatorDots::new(),
headerbar: gtk::HeaderBar::builder().show_title_buttons(false).build(),
start_btn: gtk::Button::with_label(&gettext("_Start")),
next_overlay: gtk::Overlay::new(),
next_btn: gtk::Button::with_label(&gettext("_Next")),
finish_btn: gtk::Button::with_label(&gettext("_Close")),
close_btn: gtk::Button::with_label(&gettext("_Close")),
previous_btn: gtk::Button::with_label(&gettext("_Previous")),
pages: RefCell::new(Vec::new()),
current_page: Cell::new(0),
}
}
}
#[glib::object_subclass]
impl ObjectSubclass for PaginatorWidget {
const NAME: &'static str = "PaginatorWidget";
type ParentType = gtk::Box;
type Type = super::PaginatorWidget;
}
impl ObjectImpl for PaginatorWidget {
fn constructed(&self, obj: &Self::Type) {
let layout_manager = obj
.layout_manager()
.map(|l| l.downcast::<gtk::BoxLayout>().unwrap())
.unwrap();
layout_manager.set_orientation(gtk::Orientation::Vertical);
self.carousel_dots.set_carousel(Some(&self.carousel));
self.carousel.set_hexpand(true);
self.carousel.set_vexpand(true);
self.carousel
.set_scroll_params(&adw::SpringParams::new(1.0, 0.5, 300.0));
self.carousel
.connect_position_notify(clone!(@weak obj => move |_| {
obj.update_position();
}));
self.start_btn.add_css_class("suggested-action");
self.start_btn.set_use_underline(true);
self.start_btn.set_action_name(Some("app.start-tour"));
self.next_btn.add_css_class("suggested-action");
self.next_btn.set_use_underline(true);
self.next_btn.set_action_name(Some("app.next-page"));
self.close_btn.set_use_underline(true);
self.close_btn.set_action_name(Some("app.quit"));
self.finish_btn.add_css_class("suggested-action");
self.finish_btn.set_use_underline(true);
self.finish_btn.set_action_name(Some("app.quit"));
self.previous_btn.set_use_underline(true);
self.previous_btn.set_action_name(Some("app.previous-page"));
self.next_overlay.set_child(Some(&self.next_btn));
self.next_overlay.add_overlay(&self.finish_btn);
self.next_overlay.set_can_target(false);
let previous_overlay = gtk::Overlay::new();
previous_overlay.set_child(Some(&self.close_btn));
previous_overlay.add_overlay(&self.previous_btn);
let start_overlay = gtk::Overlay::new();
start_overlay.set_child(Some(&self.start_btn));
start_overlay.add_overlay(&self.next_overlay);
let btn_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Horizontal);
btn_size_group.add_widget(&self.previous_btn);
btn_size_group.add_widget(&self.close_btn);
btn_size_group.add_widget(&self.next_overlay);
btn_size_group.add_widget(&start_overlay);
btn_size_group.add_widget(&self.finish_btn);
self.headerbar.set_title_widget(Some(&self.carousel_dots));
self.headerbar.pack_start(&previous_overlay);
self.headerbar.pack_end(&start_overlay);
obj.append(&self.headerbar);
obj.append(&self.carousel);
self.parent_constructed(obj);
}
}
impl WidgetImpl for PaginatorWidget {}
impl BoxImpl for PaginatorWidget {}
}
glib::wrapper! {
pub struct PaginatorWidget(ObjectSubclass<imp::PaginatorWidget>)
@extends gtk::Widget, gtk::Box;
}
impl PaginatorWidget {
pub fn new() -> Rc<Self> {
let widget = gtk::Box::new(gtk::Orientation::Vertical, 0);
let paginator = Rc::new(Self {
widget,
carousel: adw::Carousel::new(),
carousel_dots: adw::CarouselIndicatorDots::new(),
headerbar: gtk::HeaderBar::builder().show_title_buttons(false).build(),
start_btn: gtk::Button::with_label(&gettext("_Start")),
next_overlay: gtk::Overlay::new(),
next_btn: gtk::Button::with_label(&gettext("_Next")),
finish_btn: gtk::Button::with_label(&gettext("_Close")),
close_btn: gtk::Button::with_label(&gettext("_Close")),
previous_btn: gtk::Button::with_label(&gettext("_Previous")),
pages: RefCell::new(Vec::new()),
current_page: RefCell::new(0),
});
paginator.init(paginator.clone());
paginator
pub fn new() -> Self {
glib::Object::new(&[]).unwrap()
}
pub fn try_next(&self) -> Option<()> {
let p = *self.current_page.borrow() + 1;
if p == self.carousel.n_pages() {
let imp = self.imp();
let p = imp.current_page.get() + 1;
if p == imp.carousel.n_pages() {
return None;
}
self.set_page(p);
......@@ -52,7 +142,7 @@ impl PaginatorWidget {
}
pub fn try_previous(&self) -> Option<()> {
let p = *self.current_page.borrow();
let p = self.imp().current_page.get();
if p == 0 {
return None;
}
......@@ -61,18 +151,21 @@ impl PaginatorWidget {
}
pub fn add_page(&self, page: gtk::Widget) {
let page_nr = self.pages.borrow().len();
self.carousel.insert(&page, page_nr as i32);
self.pages.borrow_mut().push(page);
let imp = self.imp();
let page_nr = imp.pages.borrow().len();
imp.carousel.insert(&page, page_nr as i32);
imp.pages.borrow_mut().push(page);
self.update_position();
}
fn update_position(&self) {
let position = self.carousel.position();
let imp = self.imp();
let position = imp.carousel.position();
let page_nr = position.round() as u32;
let n_pages = self.carousel.n_pages() as f64;
let n_pages = imp.carousel.n_pages() as f64;
let forelast_page = n_pages - 2.0;
let last_page = n_pages - 1.0;
......@@ -91,86 +184,31 @@ impl PaginatorWidget {
panic!("Position of the carousel is outside the allowed range");
};
self.start_btn.set_opacity(opacity_start);
self.start_btn.set_visible(opacity_start > 0_f64);
imp.start_btn.set_opacity(opacity_start);
imp.start_btn.set_visible(opacity_start > 0_f64);
self.next_btn.set_opacity(opacity_next);
self.next_btn.set_visible(opacity_next > 0_f64);
self.next_overlay.set_can_target(opacity_next > 0_f64);
imp.next_btn.set_opacity(opacity_next);
imp.next_btn.set_visible(opacity_next > 0_f64);
imp.next_overlay.set_can_target(opacity_next > 0_f64);
self.finish_btn.set_opacity(opacity_finish);
self.finish_btn.set_visible(opacity_finish > 0_f64);
imp.finish_btn.set_opacity(opacity_finish);
imp.finish_btn.set_visible(opacity_finish > 0_f64);
self.previous_btn.set_opacity(opacity_previous);
self.previous_btn.set_visible(opacity_previous > 0_f64);
imp.previous_btn.set_opacity(opacity_previous);
imp.previous_btn.set_visible(opacity_previous > 0_f64);
self.close_btn.set_opacity(opacity_close);
self.start_btn.set_visible(opacity_close > 0_f64);
self.current_page.replace(page_nr);
}
imp.close_btn.set_opacity(opacity_close);
imp.start_btn.set_visible(opacity_close > 0_f64);
fn init(&self, p: Rc<Self>) {
self.carousel_dots.set_carousel(Some(&self.carousel));
self.carousel.set_hexpand(true);
self.carousel.set_vexpand(true);
self.carousel
.set_scroll_params(&adw::SpringParams::new(1.0, 0.5, 300.0));
self.carousel
.connect_position_notify(clone!(@weak p => move |_| {
p.update_position();
}));
self.start_btn.add_css_class("suggested-action");
self.start_btn.set_use_underline(true);
self.start_btn.set_action_name(Some("app.start-tour"));
self.next_btn.add_css_class("suggested-action");
self.next_btn.set_use_underline(true);
self.next_btn.set_action_name(Some("app.next-page"));
self.close_btn.set_use_underline(true);
self.close_btn.set_action_name(Some("app.quit"));
self.finish_btn.add_css_class("suggested-action");
self.finish_btn.set_use_underline(true);
self.finish_btn.set_action_name(Some("app.quit"));
self.previous_btn.set_use_underline(true);
self.previous_btn.set_action_name(Some("app.previous-page"));
self.next_overlay.set_child(Some(&self.next_btn));
self.next_overlay.add_overlay(&self.finish_btn);
self.next_overlay.set_can_target(false);
let previous_overlay = gtk::Overlay::new();
previous_overlay.set_child(Some(&self.close_btn));
previous_overlay.add_overlay(&self.previous_btn);
let start_overlay = gtk::Overlay::new();
start_overlay.set_child(Some(&self.start_btn));
start_overlay.add_overlay(&self.next_overlay);
let btn_size_group = gtk::SizeGroup::new(gtk::SizeGroupMode::Horizontal);
btn_size_group.add_widget(&self.previous_btn);
btn_size_group.add_widget(&self.close_btn);
btn_size_group.add_widget(&self.next_overlay);
btn_size_group.add_widget(&start_overlay);
btn_size_group.add_widget(&self.finish_btn);
self.headerbar.set_title_widget(Some(&self.carousel_dots));
self.headerbar.pack_start(&previous_overlay);
self.headerbar.pack_end(&start_overlay);
self.widget.append(&self.headerbar);
self.widget.append(&self.carousel);
imp.current_page.set(page_nr);
}
pub fn set_page(&self, page_nr: u32) {
if page_nr < self.carousel.n_pages() {
let pages = &self.pages.borrow();
let imp = self.imp();
if page_nr < imp.carousel.n_pages() {
let pages = &imp.pages.borrow();
let page = pages.get(page_nr as usize).unwrap();
self.carousel.scroll_to(page, true);
imp.carousel.scroll_to(page, true);
}
}
}
use adw::prelude::*;
use gettextrs::gettext;
use std::cell::RefCell;
use std::rc::Rc;
use super::pages::{ImagePageWidget, WelcomePageWidget};
use super::paginator::PaginatorWidget;
......@@ -11,14 +9,14 @@ use crate::Application;
#[derive(Debug)]
pub struct Window {
pub widget: adw::ApplicationWindow,
pub paginator: RefCell<Rc<PaginatorWidget>>,
pub paginator: PaginatorWidget,
}
impl Window {
pub fn new(app: &Application) -> Self {
let widget = adw::ApplicationWindow::new(app);
let paginator = RefCell::new(PaginatorWidget::new());
let paginator = PaginatorWidget::new();
let mut window_widget = Window { widget, paginator };
......@@ -27,11 +25,11 @@ impl Window {
}
pub fn start_tour(&self) {
self.paginator.borrow_mut().set_page(1);
self.paginator.set_page(1);
}
pub fn reset_tour(&self) {
self.paginator.borrow_mut().set_page(0);
self.paginator.set_page(0);
}
fn init(&mut self) {
......@@ -43,9 +41,8 @@ impl Window {
self.widget.add_css_class("devel");
}
self.paginator
.borrow_mut()
.add_page(WelcomePageWidget::new().widget.upcast::<gtk::Widget>());
self.paginator.borrow_mut().add_page(
self.paginator.add_page(
ImagePageWidget::new(
"/org/gnome/Tour/overview.svg",
gettext("Get an Overview"),
......@@ -55,7 +52,7 @@ impl Window {
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(
self.paginator.add_page(
ImagePageWidget::new(
"/org/gnome/Tour/search.svg",
gettext("Just Type to Search"),
......@@ -65,7 +62,7 @@ impl Window {
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(
self.paginator.add_page(
ImagePageWidget::new(
"/org/gnome/Tour/workspaces.svg",
gettext("Keep on Top with Workspaces"),
......@@ -75,7 +72,7 @@ impl Window {
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(
self.paginator.add_page(
ImagePageWidget::new(
"/org/gnome/Tour/blank.svg",
gettext("Up/Down for the Overview"),
......@@ -85,7 +82,7 @@ impl Window {
.upcast::<gtk::Widget>(),
);
self.paginator.borrow_mut().add_page(
self.paginator.add_page(
ImagePageWidget::new(
"/org/gnome/Tour/blank.svg",
gettext("Left/Right for Workspaces"),
......@@ -102,10 +99,8 @@ impl Window {
);
last_page.widget.add_css_class("last-page");
self.paginator
.borrow_mut()
.add_page(last_page.widget.upcast::<gtk::Widget>());
self.widget
.set_content(Some(&self.paginator.borrow().widget));
self.widget.set_content(Some(&self.paginator));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment