add gala namespace to DragDropAction class

This commit is contained in:
Tom Beckmann 2013-06-27 14:12:51 +02:00
parent 05ed8e811f
commit 3703a701aa

View File

@ -15,206 +15,208 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
public enum DragDropActionType
namespace Gala
{
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)
public enum DragDropActionType
{
drag_type = type;
drag_id = id;
SOURCE = 0,
DESTINATION
}
~DragDropAction ()
public class DragDropAction : Clutter.Action
{
if (actor != null)
release_actor (actor);
}
public DragDropActionType drag_type { get; private set; }
public string drag_id { get; set; }
public Clutter.Actor handle { get; private set; }
public override void set_actor (Clutter.Actor? new_actor)
{
if (actor != null) {
release_actor (actor);
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;
}
if (new_actor != null) {
connect_actor (new_actor);
~DragDropAction ()
{
if (actor != null)
release_actor (actor);
}
base.set_actor (new_actor);
}
public override void set_actor (Clutter.Actor? new_actor)
{
if (actor != null) {
release_actor (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);
}
}
if (new_actor != null) {
connect_actor (new_actor);
}
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;
base.set_actor (new_actor);
}
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;
void release_actor (Clutter.Actor actor)
{
if (drag_type == DragDropActionType.SOURCE) {
actor.button_press_event.disconnect (source_clicked);
actor.motion_event.disconnect (source_motion);
}
}
return null;
}
/**
* Abort the drag
**/
public void cancel ()
{
if (dragging) {
actor.get_stage ().captured_event.disconnect (follow_move);
void connect_actor (Clutter.Actor actor)
{
if (drag_type == DragDropActionType.SOURCE) {
actor.button_press_event.connect (source_clicked);
actor.motion_event.connect (source_motion);
}
}
canceled ();
dragging = false;
}
bool source_clicked (Clutter.ButtonEvent event)
{
if (event.button != 1)
return false;
void finish ()
{
// make sure they reset the style or whatever they changed when hovered
get_drag_drop_action (hovered).crossed (false);
clicked = true;
return true;
}
actor.get_stage ().captured_event.disconnect (follow_move);
finished (hovered);
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);
}
}
}