-
-
Notifications
You must be signed in to change notification settings - Fork 203
Initial Implementation for Pencil Tool (Freehand Drawing) #679
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
AshishS-1123
wants to merge
9
commits into
akiraux:main
Choose a base branch
from
AshishS-1123:pencil-tool
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
a99ad94
Create basic FreeHandMode for creating curves
AshishS-1123 6859e19
Setup actions and create dummy item
AshishS-1123 0be8f0d
Proper name and icon in Layer panel
AshishS-1123 bd7ad14
Create model to store and process path data
AshishS-1123 86ca510
Store raw points from user events
AshishS-1123 814764b
Write Schneider's Algorithm for simplifying the raw points
AshishS-1123 eaa1e7f
Diplay calculated bezier points on canvas
AshishS-1123 324311b
Lint fixes
AshishS-1123 543adc0
Helpful comments
AshishS-1123 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,26 @@ public struct Akira.Geometry.Point { | |
this.y = y; | ||
} | ||
|
||
public Point add (Point pt) { | ||
return Geometry.Point (x + pt.x, y + pt.y); | ||
} | ||
|
||
public Point sub (Point pt) { | ||
return Geometry.Point (x - pt.x, y - pt.y); | ||
} | ||
|
||
public double dot (Point pt) { | ||
return x * pt.x + y * pt.y; | ||
} | ||
|
||
public Point scale (double val) { | ||
return Geometry.Point (x * val, y * val); | ||
} | ||
|
||
public double distance (Point pt) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should probably add a distance_squared for distance comparisons--so we don't have to do sqrt when not necessary. |
||
return Utils.GeometryMath.distance (x, y, pt.x, pt.y); | ||
} | ||
|
||
public Point.deserialized (Json.Object obj) { | ||
x = obj.get_double_member ("x"); | ||
y = obj.get_double_member ("y"); | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/** | ||
* Copyright (c) 2019-2021 Alecaddd (https://alecaddd.com) | ||
* | ||
* This file is part of Akira. | ||
* | ||
* Akira 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. | ||
|
||
* Akira 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 Akira. If not, see <https://www.gnu.org/licenses/>. | ||
* | ||
* Authored by: Martin "mbfraga" Fraga <[email protected]> | ||
*/ | ||
|
||
public class Akira.Lib.Items.ModelTypePencil : ModelType { | ||
public static ModelInstance minimal_rect () { | ||
return default_path ( | ||
new Lib.Components.Coordinates (0.5, 0.5), | ||
null, | ||
null | ||
); | ||
} | ||
|
||
public static ModelInstance default_path ( | ||
Lib.Components.Coordinates center, | ||
Lib.Components.Borders? borders, | ||
Lib.Components.Fills? fills | ||
) { | ||
var new_item = new ModelInstance (-1, new ModelTypePencil ()); | ||
new_item.components.center = center; | ||
new_item.components.borders = borders; | ||
new_item.components.fills = fills; | ||
new_item.components.transform = Lib.Components.Components.default_transform (); | ||
new_item.components.flipped = Lib.Components.Components.default_flipped (); | ||
new_item.components.border_radius = Lib.Components.Components.default_border_radius (); | ||
new_item.components.path = new Lib.Components.Path.from_single_point ( | ||
Akira.Geometry.Point (center.x, center.y), | ||
Lib.Modes.PathEditMode.Type.LINE, | ||
false | ||
); | ||
new_item.components.size = new Lib.Components.Size (1, 1, false); | ||
new_item.components.name = Lib.Components.Components.default_name (); | ||
return new_item; | ||
} | ||
|
||
public override string name_id { get { return "pencil"; } } | ||
|
||
public override Components.CompiledGeometry compile_geometry ( | ||
Components.Components? components, | ||
Lib.Items.ModelNode? node | ||
) { | ||
return new Components.CompiledGeometry.from_components (components, node, true); | ||
} | ||
|
||
public override void construct_canvas_item (ModelInstance instance) { | ||
instance.drawable = new Drawables.DrawablePath ( | ||
(instance.components.path == null) ? null : instance.components.path.data | ||
); | ||
} | ||
|
||
public override void component_updated (ModelInstance instance, Lib.Components.Component.Type type) { | ||
switch (type) { | ||
case Lib.Components.Component.Type.COMPILED_BORDER: | ||
if (!instance.compiled_border.is_visible) { | ||
instance.drawable.line_width = 0; | ||
instance.drawable.stroke_rgba = Gdk.RGBA () { alpha = 0 }; | ||
break; | ||
} | ||
|
||
// The "line-width" property expects a DOUBLE type, but we don't support subpixels | ||
// so we always handle the border size as INT, therefore we need to type cast it here. | ||
instance.drawable.line_width = (double) instance.compiled_border.size; | ||
instance.drawable.stroke_rgba = instance.compiled_border.color; | ||
break; | ||
case Lib.Components.Component.Type.COMPILED_FILL: | ||
if (!instance.compiled_fill.is_visible) { | ||
instance.drawable.fill_rgba = Gdk.RGBA () { alpha = 0 }; | ||
break; | ||
} | ||
|
||
instance.drawable.fill_rgba = instance.compiled_fill.color; | ||
break; | ||
case Lib.Components.Component.Type.COMPILED_GEOMETRY: | ||
// The points property is only available to DrawablePath, so first typecast it | ||
// modify it, then assign to instance. | ||
Drawables.DrawablePath drawable = instance.drawable as Drawables.DrawablePath; | ||
drawable.center_x = -instance.compiled_geometry.source_width / 2.0; | ||
drawable.center_y = -instance.compiled_geometry.source_height / 2.0; | ||
drawable.transform = instance.compiled_geometry.transformation_matrix; | ||
drawable.points = instance.components.path.data; | ||
drawable.commands = instance.components.path.commands; | ||
break; | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
/** | ||
* Copyright (c) 2021 Alecaddd (https://alecaddd.com) | ||
* | ||
* This file is part of Akira. | ||
* | ||
* Akira 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. | ||
|
||
* Akira 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 Akira. If not, see <https://www.gnu.org/licenses/>. | ||
* | ||
* Authored by: Ashish Shevale <[email protected]> | ||
*/ | ||
|
||
public class Akira.Lib.Modes.FreeHandMode : AbstractInteractionMode { | ||
|
||
public weak Lib.ViewCanvas view_canvas { get; construct; } | ||
public Lib.Items.ModelInstance instance { get; construct; } | ||
private Models.FreeHandModel edit_model; | ||
|
||
private bool is_click = false; | ||
|
||
public FreeHandMode (Lib.ViewCanvas canvas, Lib.Items.ModelInstance instance) { | ||
Object ( | ||
view_canvas: canvas, | ||
instance: instance | ||
); | ||
|
||
edit_model = new Models.FreeHandModel (instance, view_canvas); | ||
} | ||
|
||
public override AbstractInteractionMode.ModeType mode_type () { | ||
return AbstractInteractionMode.ModeType.FREE_HAND; | ||
} | ||
|
||
public override Utils.Nobs.Nob active_nob () { | ||
return Utils.Nobs.Nob.NONE; | ||
} | ||
|
||
public override void mode_begin () { | ||
// Hide the nobs and show the path layer. | ||
view_canvas.toggle_layer_visibility (ViewLayers.ViewLayer.NOBS_LAYER_ID, false); | ||
view_canvas.toggle_layer_visibility (ViewLayers.ViewLayer.PATH_LAYER_ID, true); | ||
} | ||
|
||
public override void mode_end () { | ||
// Hide the path layer and show nobs. | ||
view_canvas.toggle_layer_visibility (ViewLayers.ViewLayer.NOBS_LAYER_ID, true); | ||
view_canvas.toggle_layer_visibility (ViewLayers.ViewLayer.PATH_LAYER_ID, false); | ||
} | ||
|
||
public override Gdk.CursorType? cursor_type () { | ||
return Gdk.CursorType.CROSSHAIR; | ||
} | ||
|
||
public override bool key_press_event (Gdk.EventKey event) { | ||
return false; | ||
} | ||
|
||
public override bool key_release_event (Gdk.EventKey event) { | ||
return false; | ||
} | ||
|
||
public override bool button_press_event (Gdk.EventButton event) { | ||
is_click = true; | ||
|
||
if (edit_model.first_point.x == -1) { | ||
edit_model.first_point = Geometry.Point (event.x, event.y); | ||
} | ||
return true; | ||
} | ||
|
||
public override bool button_release_event (Gdk.EventButton event) { | ||
is_click = false; | ||
edit_model.fit_curve (); | ||
view_canvas.mode_manager.deregister_active_mode (); | ||
return true; | ||
} | ||
|
||
public override bool motion_notify_event (Gdk.EventMotion event) { | ||
if (is_click) { | ||
Geometry.Point point = Geometry.Point (event.x, event.y); | ||
// print("add point %f %f\n", event.x, event.y); | ||
edit_model.add_raw_point (point); | ||
} | ||
return true; | ||
} | ||
|
||
public override Object? extra_context () { | ||
return null; | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the difference between CURVE and Bezier--they are both drawing beziers.