Skip to content

Commit

Permalink
Implment hover manager and nob manager
Browse files Browse the repository at this point in the history
This required some core changes to goo.canvasitems (wrapping).
  • Loading branch information
mbfraga committed May 17, 2021
1 parent 385b49f commit f236fc6
Show file tree
Hide file tree
Showing 27 changed files with 1,441 additions and 320 deletions.
6 changes: 3 additions & 3 deletions src/Lib/Canvas.vala
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public class Akira.Lib.Canvas : Goo.Canvas {
Gdk.CursorType? new_cursor = mode_manager.active_cursor_type ();

if (new_cursor == null) {
var hover_cursor = Akira.Lib.Managers.NobManager.cursor_from_nob (nob_manager.hovered_nob);
var hover_cursor = Utils.Nobs.cursor_from_nob (nob_manager.hovered_nob);
new_cursor = (hover_cursor == null) ? Gdk.CursorType.ARROW : hover_cursor;
}

Expand Down Expand Up @@ -317,7 +317,7 @@ public class Akira.Lib.Canvas : Goo.Canvas {
var nob_clicked = nob_manager.hit_test (event.x, event.y);
nob_manager.set_selected_by_name (nob_clicked);

if (nob_clicked == Akira.Lib.Managers.NobManager.Nob.NONE) {
if (nob_clicked == Utils.Nobs.Nob.NONE) {
var clicked_item = get_item_at (event.x, event.y, true);

// Deselect if no item was clicked, or a non selected artboard was clicked.
Expand Down Expand Up @@ -364,7 +364,7 @@ public class Akira.Lib.Canvas : Goo.Canvas {
return true;
}
} else {
nob_manager.set_selected_by_name (Akira.Lib.Managers.NobManager.Nob.NONE);
nob_manager.set_selected_by_name (Utils.Nobs.Nob.NONE);
}

return false;
Expand Down
4 changes: 2 additions & 2 deletions src/Lib/Managers/HoverManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ public class Akira.Lib.Managers.HoverManager : Object {
canvas.window.event_bus.hover_over_layer.connect (on_layer_hovered);
}

public void on_mouse_over (double event_x, double event_y, Akira.Lib.Managers.NobManager.Nob nob) {
if (nob != Akira.Lib.Managers.NobManager.Nob.NONE) {
public void on_mouse_over (double event_x, double event_y, Utils.Nobs.Nob nob) {
if (nob != Utils.Nobs.Nob.NONE) {
current_hover_item = null;
remove_hover_effect ();
return;
Expand Down
128 changes: 20 additions & 108 deletions src/Lib/Managers/NobManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,6 @@ public class Akira.Lib.Managers.NobManager : Object {
private const double LINE_WIDTH = 1.0;
private const double LINE_HEIGHT = 40.0;

/*
Grabber Pos:
8
|
0 1 2
7 3
6 5 4
// -1 if no nob is grabbed.
*/
public enum Nob {
NONE=-1,
TOP_LEFT,
TOP_CENTER,
TOP_RIGHT,
RIGHT_CENTER,
BOTTOM_RIGHT,
BOTTOM_CENTER,
BOTTOM_LEFT,
LEFT_CENTER,
ROTATE
}

/*
* Nob data associated with an item selection.
*/
Expand Down Expand Up @@ -78,8 +55,8 @@ public class Akira.Lib.Managers.NobManager : Object {

public weak Akira.Lib.Canvas canvas { get; construct; }

public Nob selected_nob;
public Nob hovered_nob;
public Utils.Nobs.Nob selected_nob;
public Utils.Nobs.Nob hovered_nob;

private Goo.CanvasItem root;
private Goo.CanvasRect? select_effect;
Expand All @@ -93,9 +70,6 @@ public class Akira.Lib.Managers.NobManager : Object {
private bool is_artboard;
private bool nobs_constructed = false;

// If the effect needs to be created or it's only a value update.
private bool create { get; set; default = true; }

public NobManager (Akira.Lib.Canvas canvas) {
Object (
canvas: canvas
Expand All @@ -114,11 +88,11 @@ public class Akira.Lib.Managers.NobManager : Object {
/**
* Set which nob is selected by its Nob name.
*/
public void set_selected_by_name (Nob selected_nob) {
public void set_selected_by_name (Utils.Nobs.Nob selected_nob) {
this.selected_nob = selected_nob;
}

public Nob hit_test (double x, double y) {
public Utils.Nobs.Nob hit_test (double x, double y) {
double scale = canvas.current_scale;
foreach (var ui_nob in nobs) {
if (ui_nob != null && ui_nob.is_visible ()) {
Expand All @@ -128,72 +102,10 @@ public class Akira.Lib.Managers.NobManager : Object {
}
}

return Nob.NONE;
}

public static bool is_top_nob (Nob nob) {
return nob == Nob.TOP_LEFT || nob == Nob.TOP_CENTER || nob == Nob.TOP_RIGHT;
}

public static bool is_bot_nob (Nob nob) {
return nob == Nob.BOTTOM_LEFT || nob == Nob.BOTTOM_CENTER || nob == Nob.BOTTOM_RIGHT;
}

public static bool is_left_nob (Nob nob) {
return nob == Nob.TOP_LEFT || nob == Nob.LEFT_CENTER || nob == Nob.BOTTOM_LEFT;
}

public static bool is_right_nob (Nob nob) {
return nob == Nob.TOP_RIGHT || nob == Nob.RIGHT_CENTER || nob == Nob.BOTTOM_RIGHT;
}

public static bool is_corner_nob (Nob nob) {
return nob == Nob.TOP_RIGHT || nob == Nob.TOP_LEFT || nob == Nob.BOTTOM_RIGHT || nob == Nob.BOTTOM_LEFT;
return Utils.Nobs.Nob.NONE;
}

/*
* Return a cursor type based of the type of nob.
*/
public static Gdk.CursorType? cursor_from_nob (Nob nob_id) {
Gdk.CursorType? result = null;
switch (nob_id) {
case Managers.NobManager.Nob.NONE:
result = null;
break;
case Managers.NobManager.Nob.TOP_LEFT:
result = Gdk.CursorType.TOP_LEFT_CORNER;
break;
case Managers.NobManager.Nob.TOP_CENTER:
result = Gdk.CursorType.TOP_SIDE;
break;
case Managers.NobManager.Nob.TOP_RIGHT:
result = Gdk.CursorType.TOP_RIGHT_CORNER;
break;
case Managers.NobManager.Nob.RIGHT_CENTER:
result = Gdk.CursorType.RIGHT_SIDE;
break;
case Managers.NobManager.Nob.BOTTOM_RIGHT:
result = Gdk.CursorType.BOTTOM_RIGHT_CORNER;
break;
case Managers.NobManager.Nob.BOTTOM_CENTER:
result = Gdk.CursorType.BOTTOM_SIDE;
break;
case Managers.NobManager.Nob.BOTTOM_LEFT:
result = Gdk.CursorType.BOTTOM_LEFT_CORNER;
break;
case Managers.NobManager.Nob.LEFT_CENTER:
result = Gdk.CursorType.LEFT_SIDE;
break;
case Managers.NobManager.Nob.ROTATE:
result = Gdk.CursorType.EXCHANGE;
break;
}

return result;
}


/**
* Takes a set of items and populates information needed to determine
* the selection box and nob positions. If the number of items is one,
* the selection box may be rotated, otherwise it is never rotated.
Expand Down Expand Up @@ -277,7 +189,7 @@ public class Akira.Lib.Managers.NobManager : Object {
* calculated using `populate_nob_bounds_from_items`.
*/
private static void calculate_nob_position (
Nob nob_name,
Utils.Nobs.Nob nob_name,
ItemNobData nob_data,
ref double pos_x,
ref double pos_y
Expand All @@ -290,39 +202,39 @@ public class Akira.Lib.Managers.NobManager : Object {
double height_offset_y = nob_data.height_offset_y;

switch (nob_name) {
case Nob.TOP_LEFT:
case Utils.Nobs.Nob.TOP_LEFT:
pos_x = top_left_x;
pos_y = top_left_y;
break;
case Nob.TOP_CENTER:
case Utils.Nobs.Nob.TOP_CENTER:
pos_x = top_left_x + width_offset_x / 2.0;
pos_y = top_left_y + width_offset_y / 2.0;
break;
case Nob.TOP_RIGHT:
case Utils.Nobs.Nob.TOP_RIGHT:
pos_x = top_left_x + width_offset_x;
pos_y = top_left_y + width_offset_y;
break;
case Nob.RIGHT_CENTER:
case Utils.Nobs.Nob.RIGHT_CENTER:
pos_x = top_left_x + width_offset_x + height_offset_x / 2.0;
pos_y = top_left_y + width_offset_y + height_offset_y / 2.0;
break;
case Nob.BOTTOM_RIGHT:
case Utils.Nobs.Nob.BOTTOM_RIGHT:
pos_x = top_left_x + width_offset_x + height_offset_x;
pos_y = top_left_y + width_offset_y + height_offset_y;
break;
case Nob.BOTTOM_CENTER:
case Utils.Nobs.Nob.BOTTOM_CENTER:
pos_x = top_left_x + width_offset_x / 2.0 + height_offset_x;
pos_y = top_left_y + width_offset_y / 2.0 + height_offset_y;
break;
case Nob.BOTTOM_LEFT:
case Utils.Nobs.Nob.BOTTOM_LEFT:
pos_x = top_left_x + height_offset_x;
pos_y = top_left_y + height_offset_y;
break;
case Nob.LEFT_CENTER:
case Utils.Nobs.Nob.LEFT_CENTER:
pos_x = top_left_x + height_offset_x / 2.0;
pos_y = top_left_y + height_offset_y / 2.0;
break;
case Nob.NONE:
case Utils.Nobs.Nob.NONE:
default:
break;
}
Expand All @@ -333,7 +245,7 @@ public class Akira.Lib.Managers.NobManager : Object {
*/
public static void nob_position_from_items (
List<Items.CanvasItem> items,
Nob nob_name,
Utils.Nobs.Nob nob_name,
ref double pos_x,
ref double pos_y
) {
Expand Down Expand Up @@ -444,11 +356,11 @@ public class Akira.Lib.Managers.NobManager : Object {

calculate_nob_position ( nob_name, nob_data, ref center_x, ref center_y );

if (!print_middle_height_nobs && (nob_name == Nob.RIGHT_CENTER || nob_name == Nob.LEFT_CENTER)) {
if (!print_middle_height_nobs && (nob_name == Utils.Nobs.Nob.RIGHT_CENTER || nob_name == Utils.Nobs.Nob.LEFT_CENTER)) {
set_visible = false;
} else if (!print_middle_width_nobs && (nob_name == Nob.TOP_CENTER || nob_name == Nob.BOTTOM_CENTER)) {
} else if (!print_middle_width_nobs && (nob_name == Utils.Nobs.Nob.TOP_CENTER || nob_name == Utils.Nobs.Nob.BOTTOM_CENTER)) {
set_visible = false;
} else if (nob.handle_id == Nob.ROTATE) {
} else if (nob.handle_id == Utils.Nobs.Nob.ROTATE) {
double line_offset_x = 0;
double line_offset_y = - (LINE_HEIGHT / canvas.current_scale);
nob_data.bb_matrix.transform_distance (ref line_offset_x, ref line_offset_y);
Expand Down Expand Up @@ -500,7 +412,7 @@ public class Akira.Lib.Managers.NobManager : Object {
root = canvas.get_root_item ();

for (int i = 0; i < 9; i++) {
var nob = new Selection.Nob (root, (Managers.NobManager.Nob) i);
var nob = new Selection.Nob (root, (Utils.Nobs.Nob) i);
nob.set ("visibility", Goo.CanvasItemVisibility.HIDDEN);
nob.pointer_events = Goo.CanvasPointerEvents.NONE;
nobs[i] = nob;
Expand Down
2 changes: 1 addition & 1 deletion src/Lib/Modes/ItemInsertMode.vala
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public class Akira.Lib.Modes.ItemInsertMode : InteractionMode {

sel_manager.add_item_to_selection (new_item);

canvas.nob_manager.selected_nob = Managers.NobManager.Nob.BOTTOM_RIGHT;
canvas.nob_manager.selected_nob = Utils.Nobs.Nob.BOTTOM_RIGHT;
canvas.update_canvas ();

transform_mode = new Akira.Lib.Modes.TransformMode (canvas, null);
Expand Down
10 changes: 5 additions & 5 deletions src/Lib/Modes/TransformMode.vala
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class Akira.Lib.Modes.TransformMode : InteractionMode {

public override void mode_end () {
transform_extra_context = null;
canvas.nob_manager.set_selected_by_name (Akira.Lib.Managers.NobManager.Nob.NONE);
canvas.nob_manager.set_selected_by_name (Utils.Nobs.Nob.NONE);
canvas.window.event_bus.detect_artboard_change ();
canvas.window.event_bus.update_snap_decorators ();
}
Expand All @@ -92,7 +92,7 @@ public class Akira.Lib.Modes.TransformMode : InteractionMode {

public override Gdk.CursorType? cursor_type () {
var selected_nob = canvas.nob_manager.selected_nob;
return Managers.NobManager.cursor_from_nob (selected_nob);
return Utils.Nobs.cursor_from_nob (selected_nob);
}

public override bool key_press_event (Gdk.EventKey event) {
Expand Down Expand Up @@ -134,7 +134,7 @@ public class Akira.Lib.Modes.TransformMode : InteractionMode {
}

switch (selected_nob) {
case Managers.NobManager.Nob.NONE:
case Utils.Nobs.Nob.NONE:
move_from_event (
canvas,
selected_items,
Expand All @@ -145,7 +145,7 @@ public class Akira.Lib.Modes.TransformMode : InteractionMode {
);
break;

case Managers.NobManager.Nob.ROTATE:
case Utils.Nobs.Nob.ROTATE:
rotate_from_event (
canvas,
selected_items,
Expand Down Expand Up @@ -304,7 +304,7 @@ public class Akira.Lib.Modes.TransformMode : InteractionMode {
Akira.Lib.Canvas canvas,
GLib.List<Akira.Lib.Items.CanvasItem> selected_items,
InitialDragState initial_drag_state,
Akira.Lib.Managers.NobManager.Nob selected_nob,
Utils.Nobs.Nob selected_nob,
double event_x,
double event_y,
ref Akira.Lib.Managers.SnapManager.SnapGuideData guide_data
Expand Down
39 changes: 33 additions & 6 deletions src/Lib/Selection/Nob.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ public class Akira.Lib.Selection.Nob : Goo.CanvasRect {
public const double NOB_SIZE = 10;
public const double LINE_WIDTH = 1;

public Managers.NobManager.Nob handle_id;
public Utils.Nobs.Nob handle_id;

private double nob_size;
public double center_x;
public double center_y;

public Nob (Goo.CanvasItem? root, Managers.NobManager.Nob _handle_id) {
public Nob (Goo.CanvasItem? root, Utils.Nobs.Nob _handle_id) {
Object (
parent: root
);
Expand Down Expand Up @@ -57,9 +57,36 @@ public class Akira.Lib.Selection.Nob : Goo.CanvasRect {
center_x = new_x;
center_y = new_y;

var canvas = canvas as Akira.Lib.Canvas;
line_width = LINE_WIDTH / canvas.current_scale;
nob_size = NOB_SIZE / canvas.current_scale;
line_width = LINE_WIDTH / canvas.scale;
nob_size = NOB_SIZE / canvas.scale;

set ("line-width", line_width);
set ("x", - nob_size / 2.0);
set ("y", - nob_size / 2.0);
set ("height", nob_size);
set ("width", nob_size);

this.set (
"visibility",
visible ? Goo.CanvasItemVisibility.VISIBLE: Goo.CanvasItemVisibility.HIDDEN
);
}

/*
* Updates the sate using global coordinates, and a local rotation
*/
public void update_global_state (double new_x, double new_y, double rotation, bool visible) {
var tr = Cairo.Matrix.identity ();
tr.x0 = new_x;
tr.y0 = new_y;
tr.rotate (rotation);
set_transform (tr);

center_x = new_x;
center_y = new_y;

line_width = LINE_WIDTH / canvas.scale;
nob_size = NOB_SIZE / canvas.scale;

set ("line-width", line_width);
set ("x", - nob_size / 2.0);
Expand All @@ -79,7 +106,7 @@ public class Akira.Lib.Selection.Nob : Goo.CanvasRect {

update_state (Cairo.Matrix.identity (), 0, 0, false);

if (handle_id == Managers.NobManager.Nob.ROTATE) {
if (handle_id == Utils.Nobs.Nob.ROTATE) {
set ("radius-x", nob_size);
set ("radius-y", nob_size);
}
Expand Down
Loading

0 comments on commit f236fc6

Please sign in to comment.