mirror of
https://github.com/elementary/gala.git
synced 2024-12-25 02:02:11 +03:00
forgot DragDropAction.vala file
This commit is contained in:
parent
1e7ab1d307
commit
05ed8e811f
220
src/DragDropAction.vala
Normal file
220
src/DragDropAction.vala
Normal file
@ -0,0 +1,220 @@
|
||||
//
|
||||
// Copyright (C) 2013 Tom Beckmann
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
public enum DragDropActionType
|
||||
{
|
||||
SOURCE = 0,
|
||||
DESTINATION
|
||||
}
|
||||
|
||||
public class DragDropAction : Clutter.Action
|
||||
{
|
||||
public DragDropActionType drag_type { get; private set; }
|
||||
public string drag_id { get; set; }
|
||||
public Clutter.Actor handle { get; private set; }
|
||||
|
||||
Clutter.Actor? hovered = null;
|
||||
bool clicked = false;
|
||||
bool dragging = false;
|
||||
|
||||
/**
|
||||
* A drag has been started. You have to connect to this signal
|
||||
* @return A ClutterActor that serves as handle
|
||||
**/
|
||||
public signal Clutter.Actor started ();
|
||||
|
||||
/**
|
||||
* A drag has been canceled. You may want to consider cleaning up
|
||||
* your handle.
|
||||
**/
|
||||
public signal void canceled ();
|
||||
|
||||
/**
|
||||
* A drag action has successfully been finished.
|
||||
* @param actor The actor on which the drag finished
|
||||
**/
|
||||
public signal void finished (Clutter.Actor actor);
|
||||
|
||||
/**
|
||||
* The destination has been crossed
|
||||
* @param hovered indicates whether the actor is now hovered or not
|
||||
**/
|
||||
public signal void crossed (bool hovered);
|
||||
|
||||
/**
|
||||
* Create a new DragDropAction
|
||||
* @param type The type of this actor
|
||||
* @param id An ID that marks which sources can be dragged on
|
||||
* which destinations. It has to be the same for all actors that
|
||||
* should be compatible with each other.
|
||||
**/
|
||||
public DragDropAction (DragDropActionType type, string id)
|
||||
{
|
||||
drag_type = type;
|
||||
drag_id = id;
|
||||
}
|
||||
|
||||
~DragDropAction ()
|
||||
{
|
||||
if (actor != null)
|
||||
release_actor (actor);
|
||||
}
|
||||
|
||||
public override void set_actor (Clutter.Actor? new_actor)
|
||||
{
|
||||
if (actor != null) {
|
||||
release_actor (actor);
|
||||
}
|
||||
|
||||
if (new_actor != null) {
|
||||
connect_actor (new_actor);
|
||||
}
|
||||
|
||||
base.set_actor (new_actor);
|
||||
}
|
||||
|
||||
void release_actor (Clutter.Actor actor)
|
||||
{
|
||||
if (drag_type == DragDropActionType.SOURCE) {
|
||||
actor.button_press_event.disconnect (source_clicked);
|
||||
actor.motion_event.disconnect (source_motion);
|
||||
}
|
||||
}
|
||||
|
||||
void connect_actor (Clutter.Actor actor)
|
||||
{
|
||||
if (drag_type == DragDropActionType.SOURCE) {
|
||||
actor.button_press_event.connect (source_clicked);
|
||||
actor.motion_event.connect (source_motion);
|
||||
}
|
||||
}
|
||||
|
||||
bool source_clicked (Clutter.ButtonEvent event)
|
||||
{
|
||||
if (event.button != 1)
|
||||
return false;
|
||||
|
||||
clicked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool source_motion (Clutter.MotionEvent event)
|
||||
{
|
||||
if (!clicked)
|
||||
return false;
|
||||
|
||||
handle = started ();
|
||||
if (handle == null) {
|
||||
critical ("No handle has been returned by the started signal, aborting drag.");
|
||||
return false;
|
||||
}
|
||||
|
||||
dragging = true;
|
||||
clicked = false;
|
||||
actor.get_stage ().captured_event.connect (follow_move);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool follow_move (Clutter.Event event)
|
||||
{
|
||||
switch (event.get_type ()) {
|
||||
case Clutter.EventType.KEY_PRESS:
|
||||
if (event.get_key_code () == Clutter.Key.Escape) {
|
||||
cancel ();
|
||||
}
|
||||
return true;
|
||||
case Clutter.EventType.MOTION:
|
||||
float x, y;
|
||||
event.get_coords (out x, out y);
|
||||
handle.x = x;
|
||||
handle.y = y;
|
||||
|
||||
var actor = actor.get_stage ().get_actor_at_pos (Clutter.PickMode.REACTIVE, (int)x, (int)y);
|
||||
DragDropAction action = null;
|
||||
if (actor == null || (action = get_drag_drop_action (actor)) == null) {
|
||||
if (hovered != null) {
|
||||
get_drag_drop_action (hovered).crossed (false);
|
||||
hovered = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (hovered != null) {
|
||||
get_drag_drop_action (hovered).crossed (false);
|
||||
}
|
||||
|
||||
hovered = actor;
|
||||
action.crossed (true);
|
||||
|
||||
return true;
|
||||
case Clutter.EventType.BUTTON_RELEASE:
|
||||
if (hovered != null) {
|
||||
finish ();
|
||||
} else {
|
||||
cancel ();
|
||||
}
|
||||
return true;
|
||||
case Clutter.EventType.ENTER:
|
||||
case Clutter.EventType.LEAVE:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns a DragDropAction instance if this actor has one or null.
|
||||
// It also checks if checks if it is a DESTINATION and if the id matches
|
||||
DragDropAction? get_drag_drop_action (Clutter.Actor actor)
|
||||
{
|
||||
DragDropAction drop_action = null;
|
||||
|
||||
foreach (var action in actor.get_actions ()) {
|
||||
if (action is DragDropAction) {
|
||||
drop_action = action as DragDropAction;
|
||||
if (drop_action.drag_type != DragDropActionType.DESTINATION || drop_action.drag_id != drag_id) {
|
||||
drop_action = null;
|
||||
continue;
|
||||
}
|
||||
return drop_action;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abort the drag
|
||||
**/
|
||||
public void cancel ()
|
||||
{
|
||||
if (dragging) {
|
||||
actor.get_stage ().captured_event.disconnect (follow_move);
|
||||
}
|
||||
|
||||
canceled ();
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
void finish ()
|
||||
{
|
||||
// make sure they reset the style or whatever they changed when hovered
|
||||
get_drag_drop_action (hovered).crossed (false);
|
||||
|
||||
actor.get_stage ().captured_event.disconnect (follow_move);
|
||||
finished (hovered);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user