22#include <glibmm/i18n.h>
23#include <gdkmm/devicetool.h>
24#include <gdkmm/display.h>
25#include <gdkmm/seat.h>
26#include <glibmm/i18n.h>
27#include <glibmm/ustring_hash.h>
60 static bool watch =
false;
61 static bool first =
true;
65 if (prefs->getBool(
"/options/useextinput/value",
true) &&
66 prefs->getBool(
"/options/switchonextinput/value"))
79 return tool->start_root_handler(event);
99 std::cerr <<
"sp_dt_guide_event: No desktop!" << std::endl;
121 auto const t = line.nearestTime(event_dt);
122 event_dt = line.pointAt(t);
123 if (!(modifiers & GDK_SHIFT_MASK)) {
124 m.guideConstrainedSnap(event_dt, *guide);
131 m.guideFreeSnap(event_dt, tmp,
true,
false);
132 guide->
moveto(tmp,
false);
135 m.guideFreeSnap(event_dt, tmp,
false,
true);
142 auto move_guide = [guide] (
Geom::Point const &event_dt,
unsigned modifiers,
bool flag) {
146 guide->
moveto(event_dt, flag);
150 if (modifiers & GDK_CONTROL_MASK) {
152 if (
auto snaps = std::abs(prefs->getInt(
"/options/rotationsnapsperpi/value", 12))) {
153 if (prefs->getBool(
"/options/relativeguiderotationsnap/value",
false)) {
155 auto snap_angle = angle - orig_angle;
156 double sections = std::floor(snap_angle.radians0() * snaps / M_PI + 0.5);
157 angle = M_PI / snaps * sections + orig_angle.radians0();
159 double sections = std::floor(angle.radians0() * snaps / M_PI + 0.5);
160 angle = M_PI / snaps * sections;
164 guide->
set_normal(Geom::Point::polar(angle).cw(), flag);
175 if (event.num_press == 2) {
176 if (event.button == 1) {
177 drag_type = SP_DRAG_NONE;
178 desktop->getTool()->discard_delayed_snap_event();
179 guide_item->ungrab();
180 Inkscape::UI::Dialog::GuidelinePropertiesDialog::showDialog(guide, desktop);
183 }
else if (event.num_press == 1) {
184 if (event.button == 1 && !guide->getLocked()) {
185 auto const event_dt = desktop->w2d(event.pos);
192 drag_origin = Geom::projection(event_dt, Geom::Line(guide->getPoint(), guide->angle()));
194 if (event.modifiers & GDK_SHIFT_MASK) {
196 drag_type = SP_DRAG_ROTATE;
197 } else if (event.modifiers & GDK_CONTROL_MASK) {
198 drag_type = SP_DRAG_MOVE_ORIGIN;
200 drag_type = SP_DRAG_TRANSLATE;
203 if (drag_type == SP_DRAG_ROTATE || drag_type == SP_DRAG_TRANSLATE) {
204 guide_item->grab(EventType::BUTTON_RELEASE |
205 EventType::BUTTON_PRESS |
222 apply_snap(event_dt, event.modifiers);
223 move_guide(event_dt, event.modifiers,
false);
241 apply_snap(event_dt, event.modifiers);
243 if (guide_item->get_canvas()->world_point_inside_canvas(event.pos)) {
244 move_guide(event_dt, event.modifiers,
true);
248 guide->moveto(guide->getPoint(),
false);
249 guide->set_normal(guide->getNormal(),
false);
251 guide_item =
nullptr;
263 guide_item->ungrab();
275 if (!guide->getLocked() && canvas->has_focus()) {
276 guide_item->set_stroke(guide->getHiColor());
280 if (guide->getLocked()) {
285 canvas->set_cursor(
"grab");
288 auto guide_description = guide->description();
290 g_free(guide_description);
294 guide_item->set_stroke(guide->getColor());
305 case GDK_KEY_KP_Delete:
306 case GDK_KEY_BackSpace:
307 if (!guide->getLocked()) {
308 auto doc = guide->document;
310 guide_item =
nullptr;
317 case GDK_KEY_Shift_L:
318 case GDK_KEY_Shift_R:
331 case GDK_KEY_Shift_L:
332 case GDK_KEY_Shift_R: {
355 auto display = Gdk::Display::get_default();
356 auto seat = display->get_default_seat();
357 auto const devices = seat->get_devices(Gdk::Seat::Capabilities::ALL);
359 for (
auto const &dev : devices) {
360 auto const src = dev->get_source();
361 if (src == Gdk::InputSource::MOUSE)
continue;
363 auto const &
name = dev->get_name();
364 if (
name.empty() ||
name ==
"pad")
continue;
366 auto const tool = dev->property_tool().get_value();
370 switch (tool->get_tool_type()) {
371 case Gdk::DeviceTool::Type::PEN:
374 case Gdk::DeviceTool::Type::ERASER:
377 case Gdk::DeviceTool::Type::MOUSE:
392 switch (event.
type()) {
393 case EventType::MOTION:
394 case EventType::BUTTON_PRESS:
395 case EventType::BUTTON_RELEASE:
396 case EventType::SCROLL:
403 auto device =
event.device.get();
406 std::cerr <<
"snoop_extended: missing source device! " << (int)event.
type() << std::endl;
410 auto source = device->get_source();
411 auto name = device->get_name();
414 std::cerr <<
"snoop_extended: name empty!" << std::endl;
422 std::cout <<
"Changed device: " <<
last_name <<
" -> " <<
name << std::endl;
Various trigoniometric helper functions.
Wrapper for angular values.
Infinite line on a plane.
Two-dimensional point that doubles as a vector.
UI::Widget::Canvas * get_canvas() const
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
void setF(MessageType type, char const *format,...) G_GNUC_PRINTF(3
pushes a message on the stack using prinf-style formatting, and replacing our old message
void clear()
removes our current message from the stack
static Preferences * get()
Access the singleton Preferences object.
To do: update description of desktop.
Inkscape::UI::Widget::Canvas * getCanvas() const
SPDocument * getDocument() const
SPNamedView * getNamedView() const
Inkscape::UI::Tools::ToolBase * getTool() const
void set_coordinate_status(Geom::Point const &p)
Sets the coordinate status to a given point.
Inkscape::MessageContext * guidesMessageContext() const
Geom::Affine const & w2d() const
Transformation from window to desktop coordinates (zoom/rotate).
Geom::Point getNormal() const
void moveto(Geom::Point const point_on_line, bool const commit)
void set_normal(Geom::Point const normal_to_line, bool const commit)
Geom::Point getPoint() const
void setup(SPDesktop const *desktop, bool snapindicator=true, SPObject const *item_to_ignore=nullptr, std::vector< Inkscape::SnapCandidatePoint > *unselected_nodes=nullptr)
Convenience shortcut when there is only one item to ignore.
static constexpr bool DEBUG_TOOL_SWITCHER
static Geom::Point drag_origin
bool sp_desktop_root_handler(Inkscape::CanvasEvent const &event, SPDesktop *desktop)
static void snoop_extended(Inkscape::CanvasEvent const &event, SPDesktop *desktop)
static void init_extended()
static SPGuideDragType drag_type
static Gdk::InputSource last_source
static std::unordered_map< Glib::ustring, Glib::ustring > name_to_tool
static Glib::ustring last_name
bool sp_dt_guide_event(Inkscape::CanvasEvent const &event, Inkscape::CanvasItemGuideLine *guide_item, SPGuide *guide)
Editable view implementation.
TODO: insert short description here.
Interface for locally managing a current status message.
EventType
The type of a CanvasEvent.
void set_svg_cursor(Gtk::Widget &widget, std::string const &file_name, std::optional< Colors::Color > fill, std::optional< Colors::Color > stroke)
Loads an SVG cursor from the specified file name, and sets it as the cursor of the given widget.
void dump_event(CanvasEvent const &event, char const *prefix, bool merge=true)
Print an event to stdout.
constexpr bool DEBUG_EVENTS
Whether event debug printing is enabled.
Singleton class to access the preferences file in a convenient way.
Abstract base class for events.
virtual EventType type() const =0
Return the dynamic type of the CanvasEvent.
The pointer has entered a widget or item.
The pointer has exited a widget or item.
Movement of the mouse pointer.