2024-02-09 20:53:59 +01:00
|
|
|
// Copyright (c) 2023-2024 Sophie Herold
|
2023-06-25 21:13:56 +02:00
|
|
|
// Copyright (c) 2023 FineFindus
|
|
|
|
|
//
|
|
|
|
|
// This program 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.
|
|
|
|
|
//
|
|
|
|
|
// This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
|
|
2023-07-16 22:47:10 +02:00
|
|
|
//! A widget that shows an overlay when dragging an image over the window
|
|
|
|
|
//!
|
|
|
|
|
//! This implementation is inspired by [Amberol](https://gitlab.gnome.org/World/amberol)
|
|
|
|
|
|
2024-09-19 22:11:03 +02:00
|
|
|
use std::cell::OnceCell;
|
|
|
|
|
use std::marker::PhantomData;
|
|
|
|
|
|
2023-07-15 20:43:01 +02:00
|
|
|
use adw::prelude::*;
|
2024-09-19 22:11:03 +02:00
|
|
|
use adw::subclass::prelude::*;
|
|
|
|
|
use glib::Properties;
|
|
|
|
|
use gtk::CompositeTemplate;
|
2023-06-25 21:13:56 +02:00
|
|
|
|
2023-12-06 23:45:02 +01:00
|
|
|
use crate::deps::*;
|
2023-06-25 21:13:56 +02:00
|
|
|
|
2023-12-06 23:45:02 +01:00
|
|
|
mod imp {
|
2023-06-25 21:13:56 +02:00
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
2024-09-19 22:11:03 +02:00
|
|
|
#[derive(Debug, Default, CompositeTemplate, Properties)]
|
2023-06-25 21:13:56 +02:00
|
|
|
#[properties(wrapper_type = super::LpDragOverlay)]
|
2024-09-19 22:11:03 +02:00
|
|
|
#[template(file = "drag_overlay.ui")]
|
2023-06-25 21:13:56 +02:00
|
|
|
pub struct LpDragOverlay {
|
|
|
|
|
/// Widget overplayed when dragging over child
|
2024-09-19 22:11:03 +02:00
|
|
|
#[property(set = Self::set_content)]
|
|
|
|
|
pub content: PhantomData<Option<gtk::Widget>>,
|
|
|
|
|
#[template_child]
|
|
|
|
|
pub overlay: TemplateChild<gtk::Overlay>,
|
|
|
|
|
#[template_child]
|
|
|
|
|
pub revealer: TemplateChild<gtk::Revealer>,
|
2023-07-15 20:43:01 +02:00
|
|
|
#[property(set = Self::set_drop_target, get, explicit_notify, construct_only)]
|
|
|
|
|
pub drop_target: OnceCell<gtk::DropTarget>,
|
2023-06-25 21:13:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[glib::object_subclass]
|
|
|
|
|
impl ObjectSubclass for LpDragOverlay {
|
|
|
|
|
const NAME: &'static str = "LpDragOverlay";
|
|
|
|
|
type Type = super::LpDragOverlay;
|
|
|
|
|
type ParentType = adw::Bin;
|
2023-07-15 20:43:01 +02:00
|
|
|
|
|
|
|
|
fn class_init(klass: &mut Self::Class) {
|
2024-09-19 22:11:03 +02:00
|
|
|
Self::bind_template(klass);
|
2023-07-15 20:43:01 +02:00
|
|
|
klass.set_css_name("lpdragoverlay");
|
|
|
|
|
}
|
2023-06-25 21:13:56 +02:00
|
|
|
|
2024-09-19 22:11:03 +02:00
|
|
|
fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
|
|
|
|
|
obj.init_template();
|
2023-06-25 21:13:56 +02:00
|
|
|
}
|
2024-09-19 22:11:03 +02:00
|
|
|
}
|
2023-06-25 21:13:56 +02:00
|
|
|
|
2024-09-19 22:11:03 +02:00
|
|
|
#[glib::derived_properties]
|
|
|
|
|
impl ObjectImpl for LpDragOverlay {
|
2023-06-25 21:13:56 +02:00
|
|
|
fn constructed(&self) {
|
2024-09-19 22:11:03 +02:00
|
|
|
self.parent_constructed();
|
2023-06-25 21:13:56 +02:00
|
|
|
|
|
|
|
|
self.revealer.set_can_target(false);
|
|
|
|
|
self.revealer
|
|
|
|
|
.set_transition_type(gtk::RevealerTransitionType::Crossfade);
|
2024-09-19 22:11:03 +02:00
|
|
|
//self.revealer.set_reveal_child(false);
|
2023-06-25 21:13:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
impl WidgetImpl for LpDragOverlay {}
|
|
|
|
|
impl BinImpl for LpDragOverlay {}
|
|
|
|
|
|
|
|
|
|
impl LpDragOverlay {
|
2023-07-15 20:43:01 +02:00
|
|
|
pub fn set_drop_target(&self, drop_target: gtk::DropTarget) {
|
2024-06-18 00:37:38 +02:00
|
|
|
drop_target.connect_current_drop_notify(glib::clone!(
|
|
|
|
|
#[weak(rename_to = revealer)]
|
|
|
|
|
self.revealer,
|
|
|
|
|
move |target| {
|
2023-06-25 21:13:56 +02:00
|
|
|
let reveal = target.current_drop().is_some();
|
|
|
|
|
revealer.set_reveal_child(reveal);
|
2024-06-18 00:37:38 +02:00
|
|
|
}
|
|
|
|
|
));
|
2023-07-15 20:43:01 +02:00
|
|
|
|
|
|
|
|
self.drop_target.set(drop_target).unwrap();
|
|
|
|
|
|
|
|
|
|
self.obj().notify("drop-target");
|
2023-06-25 21:13:56 +02:00
|
|
|
}
|
2024-09-19 22:11:03 +02:00
|
|
|
|
|
|
|
|
pub fn set_content(&self, child: Option<gtk::Widget>) {
|
|
|
|
|
self.overlay.set_child(child.as_ref());
|
|
|
|
|
}
|
2023-06-25 21:13:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glib::wrapper! {
|
|
|
|
|
pub struct LpDragOverlay(ObjectSubclass<imp::LpDragOverlay>)
|
|
|
|
|
@extends gtk::Widget, adw::Bin;
|
|
|
|
|
}
|