mirror of
https://github.com/Relintai/broken_seals.git
synced 2025-01-08 01:49:35 +01:00
Ported EditorZoomWidget from godot4.
This commit is contained in:
parent
855b1120ab
commit
3524c3bf7f
219
game/addons/world_generator/widgets/EditorZoomWidget.gd
Normal file
219
game/addons/world_generator/widgets/EditorZoomWidget.gd
Normal file
@ -0,0 +1,219 @@
|
||||
tool
|
||||
extends HBoxContainer
|
||||
|
||||
#This is a port of godot 4.0's EditorZoomWidget
|
||||
|
||||
#/*************************************************************************/
|
||||
#/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
|
||||
#/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
#/* */
|
||||
#/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
#/* a copy of this software and associated documentation files (the */
|
||||
#/* "Software"), to deal in the Software without restriction, including */
|
||||
#/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
#/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
#/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
#/* the following conditions: */
|
||||
#/* */
|
||||
#/* The above copyright notice and this permission notice shall be */
|
||||
#/* included in all copies or substantial portions of the Software. */
|
||||
#/* */
|
||||
#/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
#/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
#/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
#/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
#/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
#/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
#/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#/*************************************************************************/
|
||||
|
||||
var zoom_minus : Button
|
||||
var zoom_reset : Button
|
||||
var zoom_plus : Button
|
||||
|
||||
var EDSCALE : float = 1
|
||||
|
||||
export(float) var zoom : float = 1.0 setget set_zoom, get_zoom
|
||||
|
||||
signal zoom_changed(zoom)
|
||||
|
||||
func _init() -> void:
|
||||
# Zoom buttons
|
||||
zoom_minus = Button.new()
|
||||
zoom_minus.set_flat(true)
|
||||
add_child(zoom_minus)
|
||||
zoom_minus.connect("pressed", self, "_button_zoom_minus")
|
||||
zoom_minus.set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_minus", tr("Zoom Out"), KEY_MASK_CMD | KEY_MINUS))
|
||||
zoom_minus.set_focus_mode(FOCUS_NONE)
|
||||
|
||||
zoom_reset = Button.new()
|
||||
zoom_reset.set_flat(true)
|
||||
add_child(zoom_reset)
|
||||
zoom_reset.add_constant_override("outline_size", 1)
|
||||
zoom_reset.add_color_override("font_outline_color", Color(0, 0, 0))
|
||||
zoom_reset.add_color_override("font_color", Color(1, 1, 1))
|
||||
zoom_reset.connect("pressed", self, "_button_zoom_reset")
|
||||
zoom_reset.set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_reset", tr("Zoom Reset"), KEY_MASK_CMD | KEY_0))
|
||||
zoom_reset.set_focus_mode(FOCUS_NONE)
|
||||
#Prevent the button's size from changing when the text size changes
|
||||
zoom_reset.set_custom_minimum_size(Vector2(75, 0))
|
||||
|
||||
zoom_plus = Button.new()
|
||||
zoom_plus.set_flat(true)
|
||||
add_child(zoom_plus)
|
||||
zoom_plus.connect("pressed", self, "_button_zoom_plus")
|
||||
zoom_plus.set_shortcut(ED_SHORTCUT("canvas_item_editor/zoom_plus", tr("Zoom In"), KEY_MASK_CMD | KEY_EQUAL)) # Usually direct access key for PLUS
|
||||
zoom_plus.set_focus_mode(FOCUS_NONE)
|
||||
|
||||
_update_zoom_label()
|
||||
|
||||
add_constant_override("separation", round(-8))
|
||||
|
||||
func get_zoom() -> float:
|
||||
return zoom
|
||||
|
||||
func set_zoom(p_zoom : float) -> void:
|
||||
if (p_zoom > 0 && p_zoom != zoom):
|
||||
zoom = p_zoom;
|
||||
_update_zoom_label();
|
||||
|
||||
func set_zoom_by_increments(p_increment_count : int, p_integer_only : bool) -> void:
|
||||
# Remove editor scale from the index computation.
|
||||
var zoom_noscale : float = zoom / max(1, EDSCALE)
|
||||
var CMP_EPSILON : float = 0.00001
|
||||
|
||||
if (p_integer_only):
|
||||
# Only visit integer scaling factors above 100%, and fractions with an integer denominator below 100%
|
||||
# (1/2 = 50%, 1/3 = 33.33%, 1/4 = 25%, …).
|
||||
# This is useful when working on pixel art projects to avoid distortion.
|
||||
# This algorithm is designed to handle fractional start zoom values correctly
|
||||
# (e.g. 190% will zoom up to 200% and down to 100%).
|
||||
if (zoom_noscale + p_increment_count * 0.001 >= 1.0 - CMP_EPSILON):
|
||||
# New zoom is certain to be above 100%.
|
||||
if (p_increment_count >= 1):
|
||||
# Zooming.
|
||||
set_zoom(floor(zoom_noscale + p_increment_count) * max(1, EDSCALE))
|
||||
else:
|
||||
# Dezooming.
|
||||
set_zoom(ceil(zoom_noscale + p_increment_count) * max(1, EDSCALE))
|
||||
else:
|
||||
if (p_increment_count >= 1):
|
||||
# Zooming. Convert the current zoom into a denominator.
|
||||
var new_zoom : float = 1.0 / ceil(1.0 / zoom_noscale - p_increment_count)
|
||||
if (is_equal_approx(zoom_noscale, new_zoom)):
|
||||
# New zoom is identical to the old zoom, so try again.
|
||||
# This can happen due to floating-point precision issues.
|
||||
new_zoom = 1.0 / ceil(1.0 / zoom_noscale - p_increment_count - 1)
|
||||
|
||||
set_zoom(new_zoom * max(1, EDSCALE));
|
||||
else:
|
||||
# Dezooming. Convert the current zoom into a denominator.
|
||||
var new_zoom : float = 1.0 / floor(1.0 / zoom_noscale - p_increment_count)
|
||||
if (is_equal_approx(zoom_noscale, new_zoom)):
|
||||
# New zoom is identical to the old zoom, so try again.
|
||||
# This can happen due to floating-point precision issues.
|
||||
new_zoom = 1.0 / floor(1.0 / zoom_noscale - p_increment_count + 1)
|
||||
|
||||
set_zoom(new_zoom * max(1, EDSCALE))
|
||||
else:
|
||||
# Base increment factor defined as the twelveth root of two.
|
||||
# This allow a smooth geometric evolution of the zoom, with the advantage of
|
||||
# visiting all integer power of two scale factors.
|
||||
# note: this is analogous to the 'semitones' interval in the music world
|
||||
# In order to avoid numerical imprecisions, we compute and edit a zoom index
|
||||
# with the following relation: zoom = 2 ^ (index / 12)
|
||||
|
||||
if (zoom < CMP_EPSILON || p_increment_count == 0):
|
||||
return
|
||||
|
||||
# zoom = 2**(index/12) => log2(zoom) = index/12
|
||||
var closest_zoom_index : float = round(log(zoom_noscale) * 12.0 / log(2.0))
|
||||
|
||||
var new_zoom_index : float = closest_zoom_index + p_increment_count
|
||||
var new_zoom : float = pow(2.0, new_zoom_index / 12.0)
|
||||
|
||||
# Restore Editor scale transformation
|
||||
new_zoom *= max(1, EDSCALE)
|
||||
|
||||
set_zoom(new_zoom)
|
||||
|
||||
|
||||
func _update_zoom_label() -> void:
|
||||
var zoom_text : String = ""
|
||||
|
||||
# The zoom level displayed is relative to the editor scale
|
||||
# (like in most image editors). Its lower bound is clamped to 1 as some people
|
||||
# lower the editor scale to increase the available real estate,
|
||||
# even if their display doesn't have a particularly low DPI.
|
||||
|
||||
if (zoom >= 10):
|
||||
# Don't show a decimal when the zoom level is higher than 1000 %.
|
||||
#zoom_text = (rtos(round((zoom / max(1, EDSCALE)) * 100))) + " %"
|
||||
zoom_text = (String(round((zoom / max(1, EDSCALE)) * 100))) + " %"
|
||||
else:
|
||||
var v : float = (zoom / max(1, EDSCALE)) * 100
|
||||
var val : float = floor(v / 0.1 + 0.5) * 0.1
|
||||
|
||||
# zoom_text = (rtos(val)) + " %"
|
||||
zoom_text = (String(val)) + " %"
|
||||
|
||||
zoom_reset.set_text(zoom_text)
|
||||
|
||||
func _button_zoom_minus() -> void:
|
||||
set_zoom_by_increments(-6, Input.is_key_pressed(KEY_ALT));
|
||||
emit_signal("zoom_changed", zoom);
|
||||
|
||||
func _button_zoom_reset() -> void:
|
||||
set_zoom(1.0 * max(1, EDSCALE));
|
||||
emit_signal("zoom_changed", zoom);
|
||||
|
||||
func _button_zoom_plus() -> void:
|
||||
set_zoom_by_increments(6, Input.is_key_pressed(KEY_ALT));
|
||||
emit_signal("zoom_changed", zoom);
|
||||
|
||||
func _notification(p_what : int) -> void:
|
||||
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED):
|
||||
print(get_icon("ZoomLess", "EditorIcons"))
|
||||
zoom_minus.icon = get_icon("ZoomLess", "EditorIcons")
|
||||
zoom_plus.icon = get_icon("ZoomMore", "EditorIcons")
|
||||
|
||||
#from godot editor/editor_Settings.cpp
|
||||
func ED_SHORTCUT(p_path : String, p_name : String, p_keycode : int, editor_settings : EditorSettings = null) -> ShortCut:
|
||||
if OS.get_name() == "OSX":
|
||||
# Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
|
||||
if (p_keycode == KEY_DELETE):
|
||||
p_keycode = KEY_MASK_CMD | KEY_BACKSPACE
|
||||
|
||||
var ie : InputEventKey = null
|
||||
if (p_keycode):
|
||||
ie = InputEventKey.new()
|
||||
|
||||
ie.set_unicode(p_keycode & KEY_CODE_MASK)
|
||||
ie.set_scancode(p_keycode & KEY_CODE_MASK)
|
||||
ie.set_shift(bool(p_keycode & KEY_MASK_SHIFT))
|
||||
ie.set_alt(bool(p_keycode & KEY_MASK_ALT))
|
||||
ie.set_control(bool(p_keycode & KEY_MASK_CTRL))
|
||||
ie.set_metakey(bool(p_keycode & KEY_MASK_META))
|
||||
|
||||
if (!editor_settings):
|
||||
var sc : ShortCut
|
||||
sc = ShortCut.new()
|
||||
sc.set_name(p_name)
|
||||
sc.set_shortcut(ie)
|
||||
sc.set_meta("original", ie)
|
||||
return sc
|
||||
|
||||
var sc : ShortCut = editor_settings.get_shortcut(p_path)
|
||||
if (sc.is_valid()):
|
||||
sc.set_name(p_name); #keep name (the ones that come from disk have no name)
|
||||
sc.set_meta("original", ie); #to compare against changes
|
||||
return sc;
|
||||
|
||||
sc = ShortCut.new()
|
||||
sc.set_name(p_name)
|
||||
sc.set_shortcut(ie)
|
||||
sc.set_meta("original", ie) #to compare against changes
|
||||
editor_settings.add_shortcut(p_path, sc)
|
||||
|
||||
return sc
|
||||
|
@ -0,0 +1,8 @@
|
||||
[gd_scene load_steps=2 format=2]
|
||||
|
||||
[ext_resource path="res://addons/world_generator/widgets/EditorZoomWidget.gd" type="Script" id=1]
|
||||
|
||||
[node name="EditorZoomWidget" type="HBoxContainer"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( 1 )
|
Loading…
Reference in New Issue
Block a user