From fdb2f50a2088b91d23378009a68c05a8f0a744b9 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Mon, 10 Feb 2025 18:17:34 +0100 Subject: [PATCH] Add a graphics tablet input demo (#1162) --- misc/graphics_tablet_input/README.md | 32 +++ .../graphics_tablet_input.gd | 189 +++++++++++++++ .../graphics_tablet_input.tscn | 228 ++++++++++++++++++ misc/graphics_tablet_input/icon.svg | 1 + misc/graphics_tablet_input/icon.svg.import | 37 +++ misc/graphics_tablet_input/project.godot | 71 ++++++ .../screenshots/.gdignore | 0 .../screenshots/graphics_tablet_input.webp | Bin 0 -> 34206 bytes 8 files changed, 558 insertions(+) create mode 100644 misc/graphics_tablet_input/README.md create mode 100644 misc/graphics_tablet_input/graphics_tablet_input.gd create mode 100644 misc/graphics_tablet_input/graphics_tablet_input.tscn create mode 100644 misc/graphics_tablet_input/icon.svg create mode 100644 misc/graphics_tablet_input/icon.svg.import create mode 100644 misc/graphics_tablet_input/project.godot create mode 100644 misc/graphics_tablet_input/screenshots/.gdignore create mode 100644 misc/graphics_tablet_input/screenshots/graphics_tablet_input.webp diff --git a/misc/graphics_tablet_input/README.md b/misc/graphics_tablet_input/README.md new file mode 100644 index 0000000000..d1fd626ef5 --- /dev/null +++ b/misc/graphics_tablet_input/README.md @@ -0,0 +1,32 @@ +# Graphics Tablet Input + +A demo showing how to use graphics tablet input in Godot. Godot has full support +for pressure sensitivity, tilt and pen inversion (i.e. checking whether the +"eraser" is being used on the pen). Note that some platforms and tablets +may not support reporting tilt. + +Input accumulation and V-Sync are disabled by default in this demo to minimize +input lag and get crisp lines (even at low FPS). This makes for the most +responsive drawing experience possible. You can toggle them in the sidebar to +see the difference it makes. Note that on Android, iOS and Web platforms, V-Sync +is forced at a system level and cannot be disabled. + +Lines are drawn using the Line2D node. Every time you lift off the open and start a new +line, a new Line2D node is created. Line antialiasing is provided by enabling 2D MSAA +in the Project Settings. + +Mouse input can also be used to draw in this demo, but using a tablet is recommended. + +> [!NOTE] +> +> If you experience issues on Windows, try changing the tablet driver in the Project +> Settings to **wintab** instead of the default **winink**. Also, try changing your +> tablet's input mode from relative to absolute mode. + +Language: GDScript + +Renderer: Mobile + +## Screenshots + +![Screenshot](screenshots/graphics_tablet_input.webp) diff --git a/misc/graphics_tablet_input/graphics_tablet_input.gd b/misc/graphics_tablet_input/graphics_tablet_input.gd new file mode 100644 index 0000000000..49aa8fb165 --- /dev/null +++ b/misc/graphics_tablet_input/graphics_tablet_input.gd @@ -0,0 +1,189 @@ +extends Control + +# Automatically split lines at regular intervals to avoid performance issues +# while drawing. This is especially due to the width curve which has to be recreated +# on every new point. +const SPLIT_POINT_COUNT = 1024 + +var stroke: Line2D +var width_curve: Curve +var pressures := PackedFloat32Array() +var event_position: Vector2 +var event_tilt: Vector2 + +var line_color := Color.BLACK +var line_width: float = 3.0 + +# If `true`, modulate line width accordding to pen pressure. +# This is done using a width curve that is continuously recreated to match the line's actual profile +# as the line is being drawn by the user. +var pressure_sensitive: bool = true + +var show_tilt_vector: bool = true + +@onready var tablet_info: Label = %TabletInfo + + +func _ready() -> void: + # This makes tablet and mouse input reported as often as possible regardless of framerate. + # When accumulated input is disabled, we can query the pen/mouse position at every input event + # seen by the operating system, without being limited to the framerate the application runs at. + # The downside is that this uses more CPU resources, so input accumulation should only be + # disabled when you need to have access to precise input coordinates. + Input.use_accumulated_input = false + start_stroke() + %TabletDriver.text = "Tablet driver: %s" % DisplayServer.tablet_get_current_driver() + + +func _input(event: InputEvent) -> void: + if event is InputEventKey: + if Input.is_action_pressed(&"increase_line_width"): + $CanvasLayer/PanelContainer/Options/LineWidth/HSlider.value += 0.5 + #_on_line_width_value_changed(line_width) + if Input.is_action_pressed(&"decrease_line_width"): + $CanvasLayer/PanelContainer/Options/LineWidth/HSlider.value -= 0.5 + #_on_line_width_value_changed(line_width) + + if not stroke: + return + + if event is InputEventMouseMotion: + var event_mouse_motion := event as InputEventMouseMotion + tablet_info.text = "Pressure: %.3f\nTilt: %.3v\nInverted pen: %s" % [ + event_mouse_motion.pressure, + event_mouse_motion.tilt, + "Yes" if event_mouse_motion.pen_inverted else "No", + ] + + if event_mouse_motion.pressure <= 0 and stroke.points.size() > 1: + # Initial part of a stroke; create a new line. + start_stroke() + # Enable the buttons if they were previously disabled. + %ClearAllLines.disabled = false + %UndoLastLine.disabled = false + if event_mouse_motion.pressure > 0: + # Continue existing line. + stroke.add_point(event_mouse_motion.position) + pressures.push_back(event_mouse_motion.pressure) + # Only compute the width curve if it's present, as it's not even created + # if pressure sensitivity is disabled. + if width_curve: + width_curve.clear_points() + for pressure_idx in range(pressures.size()): + width_curve.add_point(Vector2( + float(pressure_idx) / pressures.size(), + pressures[pressure_idx] + )) + + # Split into a new line if it gets too long to avoid performance issues. + # This is mostly reached when input accumulation is disabled, as enabling + # input accumulation will naturally reduce point count by a lot. + if stroke.get_point_count() >= SPLIT_POINT_COUNT: + start_stroke() + + event_position = event_mouse_motion.position + event_tilt = event_mouse_motion.tilt + queue_redraw() + + +func _draw() -> void: + if show_tilt_vector: + # Draw tilt vector. + draw_line(event_position, event_position + event_tilt * 50, Color(1, 0, 0, 0.5), 2, true) + + +func start_stroke() -> void: + var new_stroke := Line2D.new() + new_stroke.begin_cap_mode = Line2D.LINE_CAP_ROUND + new_stroke.end_cap_mode = Line2D.LINE_CAP_ROUND + new_stroke.joint_mode = Line2D.LINE_JOINT_ROUND + # Adjust round precision depending on line width to improve performance + # and ensure it doesn't go above the default. + new_stroke.round_precision = mini(line_width, 8) + new_stroke.default_color = line_color + new_stroke.width = line_width + if pressure_sensitive: + new_stroke.width_curve = Curve.new() + add_child(new_stroke) + + new_stroke.owner = self + stroke = new_stroke + if pressure_sensitive: + width_curve = new_stroke.width_curve + else: + width_curve = null + pressures.clear() + + +func _on_undo_last_line_pressed() -> void: + # Remove last node of type Line2D in the scene. + var last_line_2d: Line2D = find_children("", "Line2D")[-1] + if last_line_2d: + # Remove stray empty line present at the end due to mouse motion. + # Note that doing it once doesn't always suffice, as multiple empty lines + # may exist at the end of the list (e.g. after changing line width/color settings). + # In this case, the user will have to use undo multiple times. + if last_line_2d.get_point_count() == 0: + last_line_2d.queue_free() + + var other_last_line_2d: Line2D = find_children("", "Line2D")[-2] + if other_last_line_2d: + other_last_line_2d.queue_free() + else: + last_line_2d.queue_free() + + # Since a new line is created as soon as mouse motion occurs (even if nothing is visible yet), + # we consider the list of lines to be empty with up to 2 items in it here. + %UndoLastLine.disabled = find_children("", "Line2D").size() <= 2 + start_stroke() + + +func _on_clear_all_lines_pressed() -> void: + # Remove all nodes of type Line2D in the scene. + for node in find_children("", "Line2D"): + node.queue_free() + + %ClearAllLines.disabled = true + start_stroke() + + +func _on_line_color_changed(color: Color) -> void: + line_color = color + # Required to make the setting change apply immediately. + start_stroke() + +func _on_line_width_value_changed(value: float) -> void: + line_width = value + $CanvasLayer/PanelContainer/Options/LineWidth/Value.text = "%.1f" % value + # Required to make the setting change apply immediately. + start_stroke() + + +func _on_pressure_sensitive_toggled(toggled_on: bool) -> void: + pressure_sensitive = toggled_on + # Required to make the setting change apply immediately. + start_stroke() + + +func _on_show_tilt_vector_toggled(toggled_on: bool) -> void: + show_tilt_vector = toggled_on + + +func _on_msaa_item_selected(index: int) -> void: + get_viewport().msaa_2d = index as Viewport.MSAA + + +func _on_max_fps_value_changed(value: float) -> void: + # Since the project has low-processor usage mode enabled, we change its sleep interval instead. + # Since this is a value in microseconds between frames, we have to convert it from a FPS value. + @warning_ignore("narrowing_conversion") + OS.low_processor_usage_mode_sleep_usec = 1_000_000.0 / value + $CanvasLayer/PanelContainer/Options/MaxFPS/Value.text = str(roundi(value)) + + +func _on_v_sync_toggled(toggled_on: bool) -> void: + DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_ENABLED if toggled_on else DisplayServer.VSYNC_DISABLED) + + +func _on_input_accumulation_toggled(toggled_on: bool) -> void: + Input.use_accumulated_input = toggled_on diff --git a/misc/graphics_tablet_input/graphics_tablet_input.tscn b/misc/graphics_tablet_input/graphics_tablet_input.tscn new file mode 100644 index 0000000000..4599a7afde --- /dev/null +++ b/misc/graphics_tablet_input/graphics_tablet_input.tscn @@ -0,0 +1,228 @@ +[gd_scene load_steps=13 format=3 uid="uid://dxpettbof8pr8"] + +[ext_resource type="Script" path="res://graphics_tablet_input.gd" id="1_fhuxi"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_0pp2f"] +content_margin_left = 12.0 +content_margin_top = 12.0 +content_margin_right = 12.0 +content_margin_bottom = 12.0 +bg_color = Color(0.223529, 0.223529, 0.223529, 1) + +[sub_resource type="InputEventAction" id="InputEventAction_spbge"] +action = &"undo_last_line" + +[sub_resource type="Shortcut" id="Shortcut_3mcds"] +events = [SubResource("InputEventAction_spbge")] + +[sub_resource type="InputEventAction" id="InputEventAction_7n722"] +action = &"clear_all_lines" + +[sub_resource type="Shortcut" id="Shortcut_5wv4g"] +events = [SubResource("InputEventAction_7n722")] + +[sub_resource type="InputEventAction" id="InputEventAction_y8lr1"] +action = &"change_line_color" + +[sub_resource type="Shortcut" id="Shortcut_1nmmy"] +events = [SubResource("InputEventAction_y8lr1")] + +[sub_resource type="InputEventAction" id="InputEventAction_0l3by"] +action = &"toggle_pressure_sensitive" + +[sub_resource type="Shortcut" id="Shortcut_mnr5q"] +events = [SubResource("InputEventAction_0l3by")] + +[sub_resource type="InputEventAction" id="InputEventAction_4p65y"] +action = &"toggle_tilt_vector" + +[sub_resource type="Shortcut" id="Shortcut_231fk"] +events = [SubResource("InputEventAction_4p65y")] + +[node name="ColorRect" type="ColorRect"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_default_cursor_shape = 3 +script = ExtResource("1_fhuxi") + +[node name="CanvasLayer" type="CanvasLayer" parent="."] + +[node name="PanelContainer" type="PanelContainer" parent="CanvasLayer"] +offset_right = 264.0 +offset_bottom = 648.0 +size_flags_horizontal = 0 +theme_override_styles/panel = SubResource("StyleBoxFlat_0pp2f") + +[node name="Options" type="VBoxContainer" parent="CanvasLayer/PanelContainer"] +custom_minimum_size = Vector2(240, 0) +layout_mode = 2 +size_flags_horizontal = 0 +theme_override_constants/separation = 10 + +[node name="UndoLastLine" type="Button" parent="CanvasLayer/PanelContainer/Options"] +unique_name_in_owner = true +layout_mode = 2 +disabled = true +shortcut = SubResource("Shortcut_3mcds") +text = "Undo Last Line" + +[node name="ClearAllLines" type="Button" parent="CanvasLayer/PanelContainer/Options"] +unique_name_in_owner = true +layout_mode = 2 +disabled = true +shortcut = SubResource("Shortcut_5wv4g") +text = "Clear All Lines" + +[node name="HSeparator" type="HSeparator" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 + +[node name="LineColor" type="HBoxContainer" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +theme_override_constants/separation = 10 + +[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/Options/LineColor"] +layout_mode = 2 +text = "Line Color" + +[node name="ColorPickerButton" type="ColorPickerButton" parent="CanvasLayer/PanelContainer/Options/LineColor"] +custom_minimum_size = Vector2(0, 30) +layout_mode = 2 +size_flags_horizontal = 3 +shortcut = SubResource("Shortcut_1nmmy") + +[node name="LineWidth" type="HBoxContainer" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +tooltip_text = "(-: Decrease, +: Increase)" +theme_override_constants/separation = 10 + +[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/Options/LineWidth"] +layout_mode = 2 +text = "Line Width" + +[node name="HSlider" type="HSlider" parent="CanvasLayer/PanelContainer/Options/LineWidth"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +min_value = 0.5 +max_value = 20.0 +step = 0.5 +value = 3.0 + +[node name="Value" type="Label" parent="CanvasLayer/PanelContainer/Options/LineWidth"] +custom_minimum_size = Vector2(35, 0) +layout_mode = 2 +text = "3.0" +horizontal_alignment = 1 + +[node name="PressureSensitive" type="CheckButton" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +tooltip_text = "If enabled, modulates line width according to pen pressure. +This has no effect if drawing with a mouse or a tablet +without pen pressure support." +button_pressed = true +shortcut = SubResource("Shortcut_mnr5q") +text = "Pressure-Sensitive" + +[node name="ShowTiltVector" type="CheckButton" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +tooltip_text = "If enabled, shows a visual representation of the tilt vector +reported by the graphics tablet. Tilt is not supported by all +graphics tablets." +button_pressed = true +shortcut = SubResource("Shortcut_231fk") +text = "Show Tilt Vector" + +[node name="HSeparator2" type="HSeparator" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 + +[node name="MSAA" type="HBoxContainer" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +theme_override_constants/separation = 10 + +[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/Options/MSAA"] +layout_mode = 2 +text = "MSAA 2D" + +[node name="OptionButton" type="OptionButton" parent="CanvasLayer/PanelContainer/Options/MSAA"] +layout_mode = 2 +selected = 3 +item_count = 4 +popup/item_0/text = "Disabled" +popup/item_1/text = "2×" +popup/item_1/id = 1 +popup/item_2/text = "4×" +popup/item_2/id = 2 +popup/item_3/text = "8×" +popup/item_3/id = 3 + +[node name="MaxFPS" type="HBoxContainer" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +theme_override_constants/separation = 10 + +[node name="Label" type="Label" parent="CanvasLayer/PanelContainer/Options/MaxFPS"] +layout_mode = 2 +text = "Max FPS" + +[node name="HSlider" type="HSlider" parent="CanvasLayer/PanelContainer/Options/MaxFPS"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 4 +min_value = 10.0 +max_value = 240.0 +step = 5.0 +value = 145.0 + +[node name="Value" type="Label" parent="CanvasLayer/PanelContainer/Options/MaxFPS"] +custom_minimum_size = Vector2(35, 0) +layout_mode = 2 +text = "145" +horizontal_alignment = 1 + +[node name="VSync" type="CheckButton" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +tooltip_text = "Disable V-Sync to achieve lower input latency. + +Note that Android, iOS and Web platforms enforce +V-Sync at a system level with no reliable way to disable it." +text = "V-Sync" + +[node name="InputAccumulation" type="CheckButton" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +tooltip_text = "If enabled, inputs are collected and merged into a single input event on every rendered frame. +By default, this is enabled in Godot, but this project disables it by default. + +This should be left disabled for drawing apps that expect precise input, +as lines can become visibly jagged otherwise." +text = "Input Accumulation" + +[node name="Spacer" type="Control" parent="CanvasLayer/PanelContainer/Options"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="TabletInfo" type="Label" parent="CanvasLayer/PanelContainer/Options"] +unique_name_in_owner = true +modulate = Color(1, 1, 1, 0.67451) +layout_mode = 2 +text = "Pressure: 0.000 +Tilt: (0.000, 0.000) +Inverted pen: No" + +[node name="TabletDriver" type="Label" parent="CanvasLayer/PanelContainer/Options"] +unique_name_in_owner = true +modulate = Color(1, 1, 1, 0.501961) +layout_mode = 2 +text = "Tablet driver: " + +[connection signal="pressed" from="CanvasLayer/PanelContainer/Options/UndoLastLine" to="." method="_on_undo_last_line_pressed"] +[connection signal="pressed" from="CanvasLayer/PanelContainer/Options/ClearAllLines" to="." method="_on_clear_all_lines_pressed"] +[connection signal="color_changed" from="CanvasLayer/PanelContainer/Options/LineColor/ColorPickerButton" to="." method="_on_line_color_changed"] +[connection signal="value_changed" from="CanvasLayer/PanelContainer/Options/LineWidth/HSlider" to="." method="_on_line_width_value_changed"] +[connection signal="toggled" from="CanvasLayer/PanelContainer/Options/PressureSensitive" to="." method="_on_pressure_sensitive_toggled"] +[connection signal="toggled" from="CanvasLayer/PanelContainer/Options/ShowTiltVector" to="." method="_on_show_tilt_vector_toggled"] +[connection signal="item_selected" from="CanvasLayer/PanelContainer/Options/MSAA/OptionButton" to="." method="_on_msaa_item_selected"] +[connection signal="value_changed" from="CanvasLayer/PanelContainer/Options/MaxFPS/HSlider" to="." method="_on_max_fps_value_changed"] +[connection signal="toggled" from="CanvasLayer/PanelContainer/Options/VSync" to="." method="_on_v_sync_toggled"] +[connection signal="toggled" from="CanvasLayer/PanelContainer/Options/InputAccumulation" to="." method="_on_input_accumulation_toggled"] diff --git a/misc/graphics_tablet_input/icon.svg b/misc/graphics_tablet_input/icon.svg new file mode 100644 index 0000000000..4ccedb7859 --- /dev/null +++ b/misc/graphics_tablet_input/icon.svg @@ -0,0 +1 @@ + diff --git a/misc/graphics_tablet_input/icon.svg.import b/misc/graphics_tablet_input/icon.svg.import new file mode 100644 index 0000000000..92a5218d8a --- /dev/null +++ b/misc/graphics_tablet_input/icon.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://besl3a0sbq1v0" +path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.svg" +dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false diff --git a/misc/graphics_tablet_input/project.godot b/misc/graphics_tablet_input/project.godot new file mode 100644 index 0000000000..bd0bd74ce8 --- /dev/null +++ b/misc/graphics_tablet_input/project.godot @@ -0,0 +1,71 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Graphics Tablet Input" +config/description="A demo showing how to use graphics tablet input in Godot." +config/tags=PackedStringArray("2d", "demo", "input", "official", "porting") +run/main_scene="res://graphics_tablet_input.tscn" +config/features=PackedStringArray("4.3") +run/low_processor_mode=true +config/icon="res://icon.svg" + +[display] + +window/stretch/mode="canvas_items" +window/stretch/aspect="expand" +window/vsync/vsync_mode=0 + +[input] + +undo_last_line={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194308,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":true,"meta_pressed":false,"pressed":false,"keycode":90,"physical_keycode":0,"key_label":0,"unicode":122,"location":0,"echo":false,"script":null) +] +} +clear_all_lines={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":true,"meta_pressed":false,"pressed":false,"keycode":4194308,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +] +} +change_line_color={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":67,"physical_keycode":0,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null) +] +} +increase_line_width={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194437,"physical_keycode":0,"key_label":0,"unicode":43,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":61,"key_label":0,"unicode":61,"location":0,"echo":false,"script":null) +] +} +decrease_line_width={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194435,"physical_keycode":0,"key_label":0,"unicode":45,"location":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":45,"key_label":0,"unicode":41,"location":0,"echo":false,"script":null) +] +} +toggle_pressure_sensitive={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":80,"physical_keycode":0,"key_label":0,"unicode":112,"location":0,"echo":false,"script":null) +] +} +toggle_tilt_vector={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":84,"physical_keycode":0,"key_label":0,"unicode":116,"location":0,"echo":false,"script":null) +] +} + +[rendering] + +renderer/rendering_method="mobile" +anti_aliasing/quality/msaa_2d=3 diff --git a/misc/graphics_tablet_input/screenshots/.gdignore b/misc/graphics_tablet_input/screenshots/.gdignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/misc/graphics_tablet_input/screenshots/graphics_tablet_input.webp b/misc/graphics_tablet_input/screenshots/graphics_tablet_input.webp new file mode 100644 index 0000000000000000000000000000000000000000..c2c64a28aca0142bf6eed21102af69b2335c3e33 GIT binary patch literal 34206 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 literal 0 HcmV?d00001