mirror of
https://github.com/Orama-Interactive/Pixelorama.git
synced 2025-02-15 10:13:07 +00:00
Compare commits
4 commits
bb3fd7f6c8
...
221cac2907
Author | SHA1 | Date | |
---|---|---|---|
|
221cac2907 | ||
|
be8b7728e4 | ||
|
31981a1def | ||
|
5bfe44a202 |
264
installer/pixelorama pl.nsi
Normal file
264
installer/pixelorama pl.nsi
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
; Pixelorama Installer NSIS Script
|
||||||
|
; Copyright Xenofon Konitsas (huskee) 2021
|
||||||
|
; Licensed under the MIT License
|
||||||
|
|
||||||
|
|
||||||
|
; Helper variables so that we don't change 20 instances of the version for every update
|
||||||
|
|
||||||
|
!define APPNAME "Pixelorama"
|
||||||
|
!define APPVERSION "v0.11.3"
|
||||||
|
!define COMPANYNAME "Orama Interactive"
|
||||||
|
|
||||||
|
|
||||||
|
; Include the Modern UI library
|
||||||
|
|
||||||
|
!include "MUI2.nsh"
|
||||||
|
!include "x64.nsh"
|
||||||
|
|
||||||
|
|
||||||
|
; Basic Installer Info
|
||||||
|
|
||||||
|
Name "${APPNAME} ${APPVERSION}"
|
||||||
|
OutFile "${APPNAME}_${APPVERSION}_setup.exe"
|
||||||
|
Unicode True
|
||||||
|
|
||||||
|
|
||||||
|
; Default installation folder
|
||||||
|
|
||||||
|
InstallDir "$APPDATA\${COMPANYNAME}\${APPNAME}"
|
||||||
|
|
||||||
|
|
||||||
|
; Get installation folder from registry if available
|
||||||
|
|
||||||
|
InstallDirRegKey HKCU "Software\${COMPANYNAME}\${APPNAME}" "InstallDir"
|
||||||
|
|
||||||
|
|
||||||
|
; Request application privileges for Vista and later
|
||||||
|
|
||||||
|
RequestExecutionLevel admin
|
||||||
|
|
||||||
|
|
||||||
|
; Interface Settings
|
||||||
|
|
||||||
|
!define MUI_ICON "assets\pixel-install.ico"
|
||||||
|
!define MUI_UNICON "assets\pixel-uninstall.ico"
|
||||||
|
!define MUI_WELCOMEFINISHPAGE_BITMAP "assets\wizard.bmp"
|
||||||
|
!define MUI_UNWELCOMEFINISHPAGE_BITMAP "assets\wizard.bmp"
|
||||||
|
!define MUI_HEADERIMAGE
|
||||||
|
!define MUI_HEADERIMAGE_RIGHT
|
||||||
|
!define MUI_HEADERIMAGE_BITMAP "assets\header.bmp"
|
||||||
|
!define MUI_HEADERIMAGE_UNBITMAP "assets\header.bmp"
|
||||||
|
!define MUI_ABORTWARNING
|
||||||
|
!define MUI_COMPONENTSPAGE_SMALLDESC
|
||||||
|
!define MUI_FINISHPAGE_NOAUTOCLOSE
|
||||||
|
!define MUI_UNFINISHPAGE_NOAUTOCLOSE
|
||||||
|
!define MUI_FINISHPAGE_RUN "$INSTDIR\pixelorama.exe"
|
||||||
|
|
||||||
|
; Language selection settings
|
||||||
|
|
||||||
|
!define MUI_LANGDLL_ALLLANGUAGES
|
||||||
|
## Remember the installer language
|
||||||
|
!define MUI_LANGDLL_REGISTRY_ROOT HKCU
|
||||||
|
!define MUI_LANGDLL_REGISTRY_KEY "Software\${COMPANYNAME}\${APPNAME}"
|
||||||
|
!define MUI_LANGDLL_REGISTRY_VALUENAME "Język instalatora"
|
||||||
|
|
||||||
|
|
||||||
|
; Installer pages
|
||||||
|
|
||||||
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
|
!insertmacro MUI_PAGE_LICENSE "Licencja"
|
||||||
|
!insertmacro MUI_PAGE_COMPONENTS
|
||||||
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
!insertmacro MUI_PAGE_FINISH
|
||||||
|
|
||||||
|
!insertmacro MUI_UNPAGE_WELCOME
|
||||||
|
!insertmacro MUI_UNPAGE_COMPONENTS
|
||||||
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
|
!insertmacro MUI_UNPAGE_FINISH
|
||||||
|
|
||||||
|
|
||||||
|
; Multilingual support
|
||||||
|
|
||||||
|
!insertmacro MUI_LANGUAGE "Polski"
|
||||||
|
;@INSERT_TRANSLATIONS@
|
||||||
|
|
||||||
|
|
||||||
|
; Assign language strings to installer/uninstaller section names
|
||||||
|
|
||||||
|
LangString SecInstall ${LANG_ENGLISH} "Zainstaluj ${APPNAME}"
|
||||||
|
LangString SecStartmenu ${LANG_ENGLISH} "Utwórz skróty w menu Start (opcjonalnie)"
|
||||||
|
LangString SecDesktop ${LANG_ENGLISH} "Utwórz skrót na pulpicie (opcjonalnie)"
|
||||||
|
LangString un.SecUninstall ${LANG_ENGLISH} "Odinstaluj ${APPNAME} ${APPVERSION}"
|
||||||
|
LangString un.SecConfig ${LANG_ENGLISH} "Usuń pliki konfiguracyjne (opcjonalnie)"
|
||||||
|
|
||||||
|
|
||||||
|
; Installer sections
|
||||||
|
|
||||||
|
Section "$(SecInstall)" SecInstall ; Main install section
|
||||||
|
|
||||||
|
SectionIn RO ; Non optional section
|
||||||
|
|
||||||
|
; Set the installation folder as the output directory
|
||||||
|
SetOutPath "$INSTDIR"
|
||||||
|
|
||||||
|
; Copy all files to install directory
|
||||||
|
${If} ${RunningX64}
|
||||||
|
File "..\build\windows-64bit\pixelorama.exe"
|
||||||
|
File "..\build\windows-64bit\pixelorama.pck"
|
||||||
|
${Else}
|
||||||
|
File "..\build\windows-32bit\pixelorama.exe"
|
||||||
|
File "..\build\windows-32bit\pixelorama.pck"
|
||||||
|
${EndIf}
|
||||||
|
File "..\assets\graphics\icons\pxo.ico"
|
||||||
|
|
||||||
|
SetOutPath "$INSTDIR\pixelorama_data"
|
||||||
|
File /nonfatal /r "..\build\pixelorama_data\*"
|
||||||
|
|
||||||
|
; Store installation folder in the registry
|
||||||
|
WriteRegStr HKCU "Software\${COMPANYNAME}\${APPNAME}" "InstallDir" $INSTDIR
|
||||||
|
|
||||||
|
; Create uninstaller
|
||||||
|
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||||
|
|
||||||
|
; Create Add/Remove Programs entry
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"DisplayName" "${APPNAME}"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"UninstallString" "$INSTDIR\uninstall.exe"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"DisplayIcon" "$INSTDIR\pixelorama.exe,0"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"InstallLocation" "$INSTDIR"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"Publisher" "${COMPANYNAME}"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"HelpLink" "https://orama-interactive.github.io/Pixelorama-Docs"
|
||||||
|
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"DisplayVersion" "${APPVERSION}"
|
||||||
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"NoModify" 1
|
||||||
|
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" \
|
||||||
|
"NoRepair" 1
|
||||||
|
|
||||||
|
; Associate .pxo files with Pixelorama
|
||||||
|
WriteRegStr HKCR ".pxo" "" "Pixelorama project"
|
||||||
|
WriteRegStr HKCR ".pxo" "ContentType" "image/pixelorama"
|
||||||
|
WriteRegStr HKCR ".pxo" "PerceivedType" "document"
|
||||||
|
|
||||||
|
WriteRegStr HKCR "Pixelorama project" "" "Pixelorama project"
|
||||||
|
WriteRegStr HKCR "Pixelorama project\shell" "" "open"
|
||||||
|
WriteRegStr HKCR "Pixelorama project\DefaultIcon" "" "$INSTDIR\pxo.ico"
|
||||||
|
|
||||||
|
WriteRegStr HKCR "Pixelorama project\shell\open\command" "" '$INSTDIR\${APPNAME}.exe "%1"'
|
||||||
|
WriteRegStr HKCR "Pixelorama project\shell\edit" "" "Edytuj projekt w ${APPNAME}"
|
||||||
|
WriteRegStr HKCR "Pixelorama project\shell\edit\command" "" '$INSTDIR\${APPNAME}.exe "%1"'
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
|
||||||
|
Section /o "$(SecStartmenu)" SecStartmenu ; Create Start Menu shortcuts
|
||||||
|
|
||||||
|
; Create folder in Start Menu\Programs and create shortcuts for app and uninstaller
|
||||||
|
CreateDirectory "$SMPROGRAMS\${COMPANYNAME}"
|
||||||
|
|
||||||
|
CreateShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME} ${APPVERSION}.lnk" "$INSTDIR\Pixelorama.exe"
|
||||||
|
CreateShortCut "$SMPROGRAMS\${COMPANYNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
|
||||||
|
Section /o "$(SecDesktop)" SecDesktop ; Create Desktop shortcut
|
||||||
|
|
||||||
|
; Create shortcut for app on desktop
|
||||||
|
CreateShortCut "$DESKTOP\${APPNAME} ${APPVERSION}.lnk" "$INSTDIR\Pixelorama.exe"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
|
||||||
|
; Installer functions
|
||||||
|
|
||||||
|
Function .onInit
|
||||||
|
!insertmacro MUI_LANGDLL_DISPLAY
|
||||||
|
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
|
||||||
|
; Uninstaller sections
|
||||||
|
|
||||||
|
Section "un.$(un.SecUninstall)" un.SecUninstall ; Main uninstall section
|
||||||
|
|
||||||
|
SectionIn RO
|
||||||
|
|
||||||
|
; Delete all files and folders created by the installer
|
||||||
|
Delete "$INSTDIR\uninstall.exe"
|
||||||
|
Delete "$INSTDIR\Pixelorama.exe"
|
||||||
|
Delete "$INSTDIR\Pixelorama.pck"
|
||||||
|
Delete "$INSTDIR\pxo.ico"
|
||||||
|
RMDir /r "$INSTDIR\pixelorama_data"
|
||||||
|
RMDir "$INSTDIR"
|
||||||
|
|
||||||
|
; Delete shortcuts
|
||||||
|
RMDir /r "$SMPROGRAMS\${COMPANYNAME}"
|
||||||
|
Delete "$DESKTOP\${APPNAME} ${APPVERSION}.lnk"
|
||||||
|
|
||||||
|
; Delete the install folder
|
||||||
|
SetOutPath "$APPDATA"
|
||||||
|
RMDir /r "${COMPANYNAME}"
|
||||||
|
|
||||||
|
; If empty, delete the application's registry key
|
||||||
|
DeleteRegKey /ifempty HKCU "Software\${COMPANYNAME}\${APPNAME}"
|
||||||
|
|
||||||
|
; Delete the Add/Remove Programs entry
|
||||||
|
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
|
||||||
|
|
||||||
|
; Delete the .pxo file association
|
||||||
|
DeleteRegKey HKCR "Pixelorama project"
|
||||||
|
DeleteRegKey HKCR ".pxo"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
|
||||||
|
Section "un.$(un.SecConfig)" un.SecConfig ; Configuration removal section
|
||||||
|
|
||||||
|
; Delete the application's settings file
|
||||||
|
Delete "$APPDATA\Godot\app_userdata\${APPNAME}\cache.ini"
|
||||||
|
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
; Uninstaller functions
|
||||||
|
|
||||||
|
Function un.onInit
|
||||||
|
!insertmacro MUI_UNGETLANGUAGE
|
||||||
|
|
||||||
|
FunctionEnd
|
||||||
|
|
||||||
|
|
||||||
|
; Section description language strings for multilingual support
|
||||||
|
|
||||||
|
LangString DESC_SecInstall ${LANG_ENGLISH} "Instalowanie ${APPNAME} ${APPVERSION}."
|
||||||
|
LangString DESC_SecStartmenu ${LANG_ENGLISH} "Tworzenie skrótów w menu Start ${APPNAME}."
|
||||||
|
LangString DESC_SecDesktop ${LANG_ENGLISH} "Tworzenie skrótu na pulpicie dla ${APPNAME}."
|
||||||
|
LangString DESC_un.SecUninstall ${LANG_ENGLISH} "Odinstalowywanie ${APPNAME} ${APPVERSION} i usuwanie wszystkich skrótów."
|
||||||
|
LangString DESC_un.SecConfig ${LANG_ENGLISH} "Usuwanie plików konfiguracyjnych ${APPNAME}."
|
||||||
|
|
||||||
|
|
||||||
|
; Assign language strings to installer/uninstaller descriptions
|
||||||
|
|
||||||
|
!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
|
||||||
|
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${SecInstall} $(DESC_SecInstall)
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${SecStartmenu} $(DESC_SecStartmenu)
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} $(DESC_SecDesktop)
|
||||||
|
|
||||||
|
!insertmacro MUI_FUNCTION_DESCRIPTION_END
|
||||||
|
|
||||||
|
|
||||||
|
!insertmacro MUI_UNFUNCTION_DESCRIPTION_BEGIN
|
||||||
|
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${un.SecUninstall} $(DESC_un.SecUninstall)
|
||||||
|
!insertmacro MUI_DESCRIPTION_TEXT ${un.SecConfig} $(DESC_un.SecConfig)
|
||||||
|
|
||||||
|
!insertmacro MUI_UNFUNCTION_DESCRIPTION_END
|
||||||
|
|
||||||
|
|
|
@ -921,6 +921,10 @@ right_text_tool={
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":true,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
show_pixel_indices={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
|
|
||||||
[input_devices]
|
[input_devices]
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ enum ViewMenu {
|
||||||
MIRROR_VIEW,
|
MIRROR_VIEW,
|
||||||
SHOW_GRID,
|
SHOW_GRID,
|
||||||
SHOW_PIXEL_GRID,
|
SHOW_PIXEL_GRID,
|
||||||
|
SHOW_PIXEL_INDICES,
|
||||||
SHOW_RULERS,
|
SHOW_RULERS,
|
||||||
SHOW_GUIDES,
|
SHOW_GUIDES,
|
||||||
SHOW_MOUSE_GUIDES,
|
SHOW_MOUSE_GUIDES,
|
||||||
|
@ -555,6 +556,12 @@ var show_rulers := true:
|
||||||
var show_guides := true
|
var show_guides := true
|
||||||
## If [code]true[/code], the mouse guides are visible.
|
## If [code]true[/code], the mouse guides are visible.
|
||||||
var show_mouse_guides := false
|
var show_mouse_guides := false
|
||||||
|
## If [code]true[/code], the indices of color are shown.
|
||||||
|
var show_pixel_indices := false:
|
||||||
|
set(value):
|
||||||
|
show_pixel_indices = value
|
||||||
|
if is_instance_valid(canvas.color_index):
|
||||||
|
canvas.color_index.enabled = value
|
||||||
var display_layer_effects := true:
|
var display_layer_effects := true:
|
||||||
set(value):
|
set(value):
|
||||||
if value == display_layer_effects:
|
if value == display_layer_effects:
|
||||||
|
@ -749,6 +756,7 @@ func _ready() -> void:
|
||||||
Global.use_native_file_dialogs = true
|
Global.use_native_file_dialogs = true
|
||||||
await get_tree().process_frame
|
await get_tree().process_frame
|
||||||
project_switched.emit()
|
project_switched.emit()
|
||||||
|
canvas.color_index.enabled = show_pixel_indices # Initialize color index preview
|
||||||
|
|
||||||
|
|
||||||
func update_grids(grids_data: Dictionary):
|
func update_grids(grids_data: Dictionary):
|
||||||
|
|
|
@ -296,14 +296,14 @@ func current_palette_select_color(mouse_button: int, index: int) -> void:
|
||||||
if color == null:
|
if color == null:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
_select_color(mouse_button, index)
|
||||||
|
|
||||||
match mouse_button:
|
match mouse_button:
|
||||||
MOUSE_BUTTON_LEFT:
|
MOUSE_BUTTON_LEFT:
|
||||||
Tools.assign_color(color, mouse_button)
|
Tools.assign_color(color, mouse_button)
|
||||||
MOUSE_BUTTON_RIGHT:
|
MOUSE_BUTTON_RIGHT:
|
||||||
Tools.assign_color(color, mouse_button)
|
Tools.assign_color(color, mouse_button)
|
||||||
|
|
||||||
_select_color(mouse_button, index)
|
|
||||||
|
|
||||||
|
|
||||||
func _select_color(mouse_button: int, index: int) -> void:
|
func _select_color(mouse_button: int, index: int) -> void:
|
||||||
match mouse_button:
|
match mouse_button:
|
||||||
|
|
|
@ -12,6 +12,7 @@ enum Dynamics { NONE, PRESSURE, VELOCITY }
|
||||||
const XY_LINE := Vector2(-0.707107, 0.707107)
|
const XY_LINE := Vector2(-0.707107, 0.707107)
|
||||||
const X_MINUS_Y_LINE := Vector2(0.707107, 0.707107)
|
const X_MINUS_Y_LINE := Vector2(0.707107, 0.707107)
|
||||||
|
|
||||||
|
var active_button := -1
|
||||||
var picking_color_for := MOUSE_BUTTON_LEFT
|
var picking_color_for := MOUSE_BUTTON_LEFT
|
||||||
var horizontal_mirror := false
|
var horizontal_mirror := false
|
||||||
var vertical_mirror := false
|
var vertical_mirror := false
|
||||||
|
@ -238,7 +239,6 @@ var _right_tools_per_layer_type := {
|
||||||
Global.LayerTypes.THREE_D: "Pan",
|
Global.LayerTypes.THREE_D: "Pan",
|
||||||
}
|
}
|
||||||
var _tool_buttons: Node
|
var _tool_buttons: Node
|
||||||
var _active_button := -1
|
|
||||||
var _last_position := Vector2i(Vector2.INF)
|
var _last_position := Vector2i(Vector2.INF)
|
||||||
|
|
||||||
|
|
||||||
|
@ -627,32 +627,28 @@ func handle_draw(position: Vector2i, event: InputEvent) -> void:
|
||||||
change_layer_automatically(draw_pos)
|
change_layer_automatically(draw_pos)
|
||||||
return
|
return
|
||||||
|
|
||||||
if event.is_action_pressed(&"activate_left_tool") and _active_button == -1 and not pen_inverted:
|
if event.is_action_pressed(&"activate_left_tool") and active_button == -1 and not pen_inverted:
|
||||||
_active_button = MOUSE_BUTTON_LEFT
|
active_button = MOUSE_BUTTON_LEFT
|
||||||
_slots[_active_button].tool_node.draw_start(draw_pos)
|
_slots[active_button].tool_node.draw_start(draw_pos)
|
||||||
elif event.is_action_released(&"activate_left_tool") and _active_button == MOUSE_BUTTON_LEFT:
|
elif event.is_action_released(&"activate_left_tool") and active_button == MOUSE_BUTTON_LEFT:
|
||||||
_slots[_active_button].tool_node.draw_end(draw_pos)
|
_slots[active_button].tool_node.draw_end(draw_pos)
|
||||||
_active_button = -1
|
active_button = -1
|
||||||
elif (
|
elif (
|
||||||
(
|
(
|
||||||
event.is_action_pressed(&"activate_right_tool")
|
event.is_action_pressed(&"activate_right_tool")
|
||||||
and _active_button == -1
|
and active_button == -1
|
||||||
and not pen_inverted
|
and not pen_inverted
|
||||||
)
|
)
|
||||||
or (
|
or event.is_action_pressed(&"activate_left_tool") and active_button == -1 and pen_inverted
|
||||||
event.is_action_pressed(&"activate_left_tool") and _active_button == -1 and pen_inverted
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
_active_button = MOUSE_BUTTON_RIGHT
|
active_button = MOUSE_BUTTON_RIGHT
|
||||||
_slots[_active_button].tool_node.draw_start(draw_pos)
|
_slots[active_button].tool_node.draw_start(draw_pos)
|
||||||
elif (
|
elif (
|
||||||
(event.is_action_released(&"activate_right_tool") and _active_button == MOUSE_BUTTON_RIGHT)
|
(event.is_action_released(&"activate_right_tool") and active_button == MOUSE_BUTTON_RIGHT)
|
||||||
or (
|
or event.is_action_released(&"activate_left_tool") and active_button == MOUSE_BUTTON_RIGHT
|
||||||
event.is_action_released(&"activate_left_tool") and _active_button == MOUSE_BUTTON_RIGHT
|
|
||||||
)
|
|
||||||
):
|
):
|
||||||
_slots[_active_button].tool_node.draw_end(draw_pos)
|
_slots[active_button].tool_node.draw_end(draw_pos)
|
||||||
_active_button = -1
|
active_button = -1
|
||||||
|
|
||||||
if event is InputEventMouseMotion:
|
if event is InputEventMouseMotion:
|
||||||
pen_pressure = event.pressure
|
pen_pressure = event.pressure
|
||||||
|
@ -683,8 +679,8 @@ func handle_draw(position: Vector2i, event: InputEvent) -> void:
|
||||||
_last_position = position
|
_last_position = position
|
||||||
_slots[MOUSE_BUTTON_LEFT].tool_node.cursor_move(position)
|
_slots[MOUSE_BUTTON_LEFT].tool_node.cursor_move(position)
|
||||||
_slots[MOUSE_BUTTON_RIGHT].tool_node.cursor_move(position)
|
_slots[MOUSE_BUTTON_RIGHT].tool_node.cursor_move(position)
|
||||||
if _active_button != -1:
|
if active_button != -1:
|
||||||
_slots[_active_button].tool_node.draw_move(draw_pos)
|
_slots[active_button].tool_node.draw_move(draw_pos)
|
||||||
|
|
||||||
var project := Global.current_project
|
var project := Global.current_project
|
||||||
var text := "[%s×%s]" % [project.size.x, project.size.y]
|
var text := "[%s×%s]" % [project.size.x, project.size.y]
|
||||||
|
|
|
@ -80,7 +80,12 @@ func update_palette() -> void:
|
||||||
palette.resize(current_palette.colors_max)
|
palette.resize(current_palette.colors_max)
|
||||||
palette.fill(TRANSPARENT)
|
palette.fill(TRANSPARENT)
|
||||||
for i in current_palette.colors:
|
for i in current_palette.colors:
|
||||||
palette[i] = current_palette.colors[i].color
|
# Due to the decimal nature of the color values, some values get rounded off
|
||||||
|
# unintentionally.
|
||||||
|
# Even though the decimal values change, the HTML code remains the same after the change.
|
||||||
|
# So we're using this trick to convert the values back to how they are shown in
|
||||||
|
# the palette.
|
||||||
|
palette[i] = Color(current_palette.colors[i].color.to_html())
|
||||||
|
|
||||||
|
|
||||||
## Displays the actual RGBA values of each pixel in the image from indexed mode.
|
## Displays the actual RGBA values of each pixel in the image from indexed mode.
|
||||||
|
@ -126,13 +131,13 @@ func resize_indices() -> void:
|
||||||
indices_image.crop(get_width(), get_height())
|
indices_image.crop(get_width(), get_height())
|
||||||
|
|
||||||
|
|
||||||
## Equivalent of [method Image.set_pixel_custom],
|
## Equivalent of [method Image.set_pixel],
|
||||||
## but also handles the logic necessary for indexed mode.
|
## but also handles the logic necessary for indexed mode.
|
||||||
func set_pixel_custom(x: int, y: int, color: Color) -> void:
|
func set_pixel_custom(x: int, y: int, color: Color) -> void:
|
||||||
set_pixelv_custom(Vector2i(x, y), color)
|
set_pixelv_custom(Vector2i(x, y), color)
|
||||||
|
|
||||||
|
|
||||||
## Equivalent of [method Image.set_pixelv_custom],
|
## Equivalent of [method Image.set_pixelv],
|
||||||
## but also handles the logic necessary for indexed mode.
|
## but also handles the logic necessary for indexed mode.
|
||||||
func set_pixelv_custom(point: Vector2i, color: Color) -> void:
|
func set_pixelv_custom(point: Vector2i, color: Color) -> void:
|
||||||
var new_color := color
|
var new_color := color
|
||||||
|
@ -142,6 +147,13 @@ func set_pixelv_custom(point: Vector2i, color: Color) -> void:
|
||||||
if not color.is_equal_approx(TRANSPARENT):
|
if not color.is_equal_approx(TRANSPARENT):
|
||||||
if palette.has(color):
|
if palette.has(color):
|
||||||
color_index = palette.find(color)
|
color_index = palette.find(color)
|
||||||
|
# If the color selected in the palette is the same then it should take prioity.
|
||||||
|
var selected_index = Palettes.current_palette_get_selected_color_index(
|
||||||
|
Tools.active_button
|
||||||
|
)
|
||||||
|
if selected_index != -1:
|
||||||
|
if palette[selected_index].is_equal_approx(color):
|
||||||
|
color_index = selected_index
|
||||||
else: # Find the most similar color
|
else: # Find the most similar color
|
||||||
var smaller_distance := color_distance(color, palette[0])
|
var smaller_distance := color_distance(color, palette[0])
|
||||||
for i in palette.size():
|
for i in palette.size():
|
||||||
|
|
|
@ -34,6 +34,7 @@ var color_mode: int = Image.FORMAT_RGBA8:
|
||||||
image.resize_indices()
|
image.resize_indices()
|
||||||
image.select_palette("", false)
|
image.select_palette("", false)
|
||||||
image.convert_rgb_to_indexed()
|
image.convert_rgb_to_indexed()
|
||||||
|
Global.canvas.color_index.queue_redraw()
|
||||||
var fill_color := Color(0)
|
var fill_color := Color(0)
|
||||||
var has_changed := false:
|
var has_changed := false:
|
||||||
set(value):
|
set(value):
|
||||||
|
|
|
@ -601,6 +601,7 @@ func _exit_tree() -> void:
|
||||||
Global.config_cache.set_value("window", "size", get_window().size)
|
Global.config_cache.set_value("window", "size", get_window().size)
|
||||||
Global.config_cache.set_value("view_menu", "draw_grid", Global.draw_grid)
|
Global.config_cache.set_value("view_menu", "draw_grid", Global.draw_grid)
|
||||||
Global.config_cache.set_value("view_menu", "draw_pixel_grid", Global.draw_pixel_grid)
|
Global.config_cache.set_value("view_menu", "draw_pixel_grid", Global.draw_pixel_grid)
|
||||||
|
Global.config_cache.set_value("view_menu", "show_pixel_indices", Global.show_pixel_indices)
|
||||||
Global.config_cache.set_value("view_menu", "show_rulers", Global.show_rulers)
|
Global.config_cache.set_value("view_menu", "show_rulers", Global.show_rulers)
|
||||||
Global.config_cache.set_value("view_menu", "show_guides", Global.show_guides)
|
Global.config_cache.set_value("view_menu", "show_guides", Global.show_guides)
|
||||||
Global.config_cache.set_value("view_menu", "show_mouse_guides", Global.show_mouse_guides)
|
Global.config_cache.set_value("view_menu", "show_mouse_guides", Global.show_mouse_guides)
|
||||||
|
|
|
@ -82,17 +82,20 @@ func scroll_palette(origin: Vector2i) -> void:
|
||||||
|
|
||||||
## Called when the color changes, either the left or the right, determined by [param mouse_button].
|
## Called when the color changes, either the left or the right, determined by [param mouse_button].
|
||||||
## If current palette has [param target_color] as a [Color], then select it.
|
## If current palette has [param target_color] as a [Color], then select it.
|
||||||
|
## This is helpful when we select color indirectly (e.g through colorpicker)
|
||||||
func find_and_select_color(target_color: Color, mouse_button: int) -> void:
|
func find_and_select_color(target_color: Color, mouse_button: int) -> void:
|
||||||
if not is_instance_valid(current_palette):
|
if not is_instance_valid(current_palette):
|
||||||
return
|
return
|
||||||
var old_index := Palettes.current_palette_get_selected_color_index(mouse_button)
|
var selected_index := Palettes.current_palette_get_selected_color_index(mouse_button)
|
||||||
|
if get_swatch_color(selected_index) == target_color: # Color already selected
|
||||||
|
return
|
||||||
for color_ind in swatches.size():
|
for color_ind in swatches.size():
|
||||||
if (
|
if (
|
||||||
target_color.is_equal_approx(swatches[color_ind].color)
|
target_color.is_equal_approx(swatches[color_ind].color)
|
||||||
or target_color.to_html() == swatches[color_ind].color.to_html()
|
or target_color.to_html() == swatches[color_ind].color.to_html()
|
||||||
):
|
):
|
||||||
var index := convert_grid_index_to_palette_index(color_ind)
|
var index := convert_grid_index_to_palette_index(color_ind)
|
||||||
select_swatch(mouse_button, index, old_index)
|
select_swatch(mouse_button, index, selected_index)
|
||||||
match mouse_button:
|
match mouse_button:
|
||||||
MOUSE_BUTTON_LEFT:
|
MOUSE_BUTTON_LEFT:
|
||||||
Palettes.left_selected_color = index
|
Palettes.left_selected_color = index
|
||||||
|
|
|
@ -15,6 +15,7 @@ var layer_metadata_texture := ImageTexture.new()
|
||||||
@onready var currently_visible_frame := $CurrentlyVisibleFrame as SubViewport
|
@onready var currently_visible_frame := $CurrentlyVisibleFrame as SubViewport
|
||||||
@onready var current_frame_drawer := $CurrentlyVisibleFrame/CurrentFrameDrawer as Node2D
|
@onready var current_frame_drawer := $CurrentlyVisibleFrame/CurrentFrameDrawer as Node2D
|
||||||
@onready var tile_mode := $TileMode as Node2D
|
@onready var tile_mode := $TileMode as Node2D
|
||||||
|
@onready var color_index := $ColorIndex as Node2D
|
||||||
@onready var pixel_grid := $PixelGrid as Node2D
|
@onready var pixel_grid := $PixelGrid as Node2D
|
||||||
@onready var grid := $Grid as Node2D
|
@onready var grid := $Grid as Node2D
|
||||||
@onready var selection := $Selection as SelectionNode
|
@onready var selection := $Selection as SelectionNode
|
||||||
|
@ -67,6 +68,7 @@ func _draw() -> void:
|
||||||
current_frame_drawer.queue_redraw()
|
current_frame_drawer.queue_redraw()
|
||||||
tile_mode.queue_redraw()
|
tile_mode.queue_redraw()
|
||||||
draw_set_transform(position, rotation, scale)
|
draw_set_transform(position, rotation, scale)
|
||||||
|
color_index.queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
func _input(event: InputEvent) -> void:
|
func _input(event: InputEvent) -> void:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=22 format=3 uid="uid://ba24iuv55m4l3"]
|
[gd_scene load_steps=24 format=3 uid="uid://ba24iuv55m4l3"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://src/UI/Canvas/Canvas.gd" id="1"]
|
[ext_resource type="Script" path="res://src/UI/Canvas/Canvas.gd" id="1"]
|
||||||
[ext_resource type="Shader" path="res://src/Shaders/BlendLayers.gdshader" id="1_253dh"]
|
[ext_resource type="Shader" path="res://src/Shaders/BlendLayers.gdshader" id="1_253dh"]
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
[ext_resource type="Script" path="res://src/UI/Canvas/Measurements.gd" id="16_nxilb"]
|
[ext_resource type="Script" path="res://src/UI/Canvas/Measurements.gd" id="16_nxilb"]
|
||||||
[ext_resource type="Shader" path="res://src/Shaders/AutoInvertColors.gdshader" id="17_lowhf"]
|
[ext_resource type="Shader" path="res://src/Shaders/AutoInvertColors.gdshader" id="17_lowhf"]
|
||||||
[ext_resource type="Script" path="res://src/UI/Canvas/ReferenceImages.gd" id="17_qfjb4"]
|
[ext_resource type="Script" path="res://src/UI/Canvas/ReferenceImages.gd" id="17_qfjb4"]
|
||||||
|
[ext_resource type="Script" path="res://src/UI/Canvas/color_index.gd" id="18_o3xx2"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_6b0ox"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_6b0ox"]
|
||||||
shader = ExtResource("1_253dh")
|
shader = ExtResource("1_253dh")
|
||||||
|
@ -26,6 +27,11 @@ shader_parameter/origin_y_positive = true
|
||||||
[sub_resource type="CanvasItemMaterial" id="1"]
|
[sub_resource type="CanvasItemMaterial" id="1"]
|
||||||
blend_mode = 4
|
blend_mode = 4
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ascg6"]
|
||||||
|
shader = ExtResource("17_lowhf")
|
||||||
|
shader_parameter/width = 0.05
|
||||||
|
shader_parameter/hollow_shapes = false
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="2"]
|
[sub_resource type="ShaderMaterial" id="2"]
|
||||||
shader = ExtResource("9")
|
shader = ExtResource("9")
|
||||||
shader_parameter/width = 0.05
|
shader_parameter/width = 0.05
|
||||||
|
@ -59,6 +65,10 @@ show_behind_parent = true
|
||||||
material = SubResource("1")
|
material = SubResource("1")
|
||||||
script = ExtResource("4")
|
script = ExtResource("4")
|
||||||
|
|
||||||
|
[node name="ColorIndex" type="Node2D" parent="."]
|
||||||
|
material = SubResource("ShaderMaterial_ascg6")
|
||||||
|
script = ExtResource("18_o3xx2")
|
||||||
|
|
||||||
[node name="PixelGrid" type="Node2D" parent="."]
|
[node name="PixelGrid" type="Node2D" parent="."]
|
||||||
script = ExtResource("6")
|
script = ExtResource("6")
|
||||||
|
|
||||||
|
|
54
src/UI/Canvas/color_index.gd
Normal file
54
src/UI/Canvas/color_index.gd
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
extends Node2D
|
||||||
|
|
||||||
|
const FONT_SIZE = 16
|
||||||
|
|
||||||
|
var users := 1
|
||||||
|
var enabled: bool = false:
|
||||||
|
set(value):
|
||||||
|
enabled = value
|
||||||
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
Global.camera.zoom_changed.connect(queue_redraw)
|
||||||
|
|
||||||
|
|
||||||
|
func _draw() -> void:
|
||||||
|
if not enabled:
|
||||||
|
return
|
||||||
|
# when we zoom out there is a visual issue that inverts the text
|
||||||
|
# (kind of how you look through a magnifying glass)
|
||||||
|
# so we should restrict the rendering distance of this preview.
|
||||||
|
var zoom_percentage := 100.0 * Global.camera.zoom.x
|
||||||
|
if zoom_percentage < Global.pixel_grid_show_at_zoom:
|
||||||
|
return
|
||||||
|
var project = ExtensionsApi.project.current_project
|
||||||
|
var cel: BaseCel = project.frames[project.current_frame].cels[project.current_layer]
|
||||||
|
if not cel is PixelCel:
|
||||||
|
return
|
||||||
|
var index_image: Image = cel.image.indices_image
|
||||||
|
if index_image.get_size() != project.size or not cel.image.is_indexed:
|
||||||
|
return
|
||||||
|
|
||||||
|
var used_rect: Rect2i = cel.image.get_used_rect()
|
||||||
|
if used_rect.size != Vector2i.ZERO:
|
||||||
|
# use smaller image for optimization
|
||||||
|
index_image = index_image.get_region(used_rect)
|
||||||
|
|
||||||
|
var font: Font = ExtensionsApi.theme.get_theme().default_font
|
||||||
|
var offset = position + Vector2(used_rect.position)
|
||||||
|
draw_set_transform(offset, rotation, Vector2(0.05, 0.05))
|
||||||
|
for x in range(index_image.get_size().x):
|
||||||
|
for y in range(index_image.get_size().y):
|
||||||
|
var index := index_image.get_pixel(x, y).r8
|
||||||
|
if index == 0:
|
||||||
|
continue
|
||||||
|
draw_string(
|
||||||
|
font,
|
||||||
|
Vector2(x, y) * 20 + Vector2.DOWN * 16,
|
||||||
|
str(index),
|
||||||
|
HORIZONTAL_ALIGNMENT_LEFT,
|
||||||
|
-1,
|
||||||
|
FONT_SIZE if (index < 100) else int(FONT_SIZE / 1.5)
|
||||||
|
)
|
||||||
|
draw_set_transform(position, rotation, scale)
|
|
@ -232,6 +232,7 @@ func _setup_view_menu() -> void:
|
||||||
"Mirror View": "mirror_view",
|
"Mirror View": "mirror_view",
|
||||||
"Show Grid": "show_grid",
|
"Show Grid": "show_grid",
|
||||||
"Show Pixel Grid": "show_pixel_grid",
|
"Show Pixel Grid": "show_pixel_grid",
|
||||||
|
"Show Pixel Indices": "show_pixel_indices",
|
||||||
"Show Rulers": "show_rulers",
|
"Show Rulers": "show_rulers",
|
||||||
"Show Guides": "show_guides",
|
"Show Guides": "show_guides",
|
||||||
"Show Mouse Guides": "",
|
"Show Mouse Guides": "",
|
||||||
|
@ -261,6 +262,9 @@ func _setup_view_menu() -> void:
|
||||||
var draw_pixel_grid: bool = Global.config_cache.get_value(
|
var draw_pixel_grid: bool = Global.config_cache.get_value(
|
||||||
"view_menu", "draw_pixel_grid", Global.draw_pixel_grid
|
"view_menu", "draw_pixel_grid", Global.draw_pixel_grid
|
||||||
)
|
)
|
||||||
|
var show_pixel_indices: bool = Global.config_cache.get_value(
|
||||||
|
"view_menu", "show_pixel_indices", Global.show_pixel_indices
|
||||||
|
)
|
||||||
var show_rulers: bool = Global.config_cache.get_value(
|
var show_rulers: bool = Global.config_cache.get_value(
|
||||||
"view_menu", "show_rulers", Global.show_rulers
|
"view_menu", "show_rulers", Global.show_rulers
|
||||||
)
|
)
|
||||||
|
@ -295,6 +299,8 @@ func _setup_view_menu() -> void:
|
||||||
_toggle_show_guides()
|
_toggle_show_guides()
|
||||||
if show_mouse_guides != Global.show_mouse_guides:
|
if show_mouse_guides != Global.show_mouse_guides:
|
||||||
_toggle_show_mouse_guides()
|
_toggle_show_mouse_guides()
|
||||||
|
if show_pixel_indices != Global.show_pixel_indices:
|
||||||
|
_toggle_show_pixel_indices()
|
||||||
if display_layer_effects != Global.display_layer_effects:
|
if display_layer_effects != Global.display_layer_effects:
|
||||||
Global.display_layer_effects = display_layer_effects
|
Global.display_layer_effects = display_layer_effects
|
||||||
if snap_to_rectangular_grid_boundary != Global.snap_to_rectangular_grid_boundary:
|
if snap_to_rectangular_grid_boundary != Global.snap_to_rectangular_grid_boundary:
|
||||||
|
@ -666,6 +672,8 @@ func view_menu_id_pressed(id: int) -> void:
|
||||||
_toggle_show_guides()
|
_toggle_show_guides()
|
||||||
Global.ViewMenu.SHOW_MOUSE_GUIDES:
|
Global.ViewMenu.SHOW_MOUSE_GUIDES:
|
||||||
_toggle_show_mouse_guides()
|
_toggle_show_mouse_guides()
|
||||||
|
Global.ViewMenu.SHOW_PIXEL_INDICES:
|
||||||
|
_toggle_show_pixel_indices()
|
||||||
Global.ViewMenu.DISPLAY_LAYER_EFFECTS:
|
Global.ViewMenu.DISPLAY_LAYER_EFFECTS:
|
||||||
Global.display_layer_effects = not Global.display_layer_effects
|
Global.display_layer_effects = not Global.display_layer_effects
|
||||||
_:
|
_:
|
||||||
|
@ -820,6 +828,11 @@ func _toggle_show_pixel_grid() -> void:
|
||||||
view_menu.set_item_checked(Global.ViewMenu.SHOW_PIXEL_GRID, Global.draw_pixel_grid)
|
view_menu.set_item_checked(Global.ViewMenu.SHOW_PIXEL_GRID, Global.draw_pixel_grid)
|
||||||
|
|
||||||
|
|
||||||
|
func _toggle_show_pixel_indices() -> void:
|
||||||
|
Global.show_pixel_indices = !Global.show_pixel_indices
|
||||||
|
view_menu.set_item_checked(Global.ViewMenu.SHOW_PIXEL_INDICES, Global.show_pixel_indices)
|
||||||
|
|
||||||
|
|
||||||
func _toggle_show_rulers() -> void:
|
func _toggle_show_rulers() -> void:
|
||||||
Global.show_rulers = !Global.show_rulers
|
Global.show_rulers = !Global.show_rulers
|
||||||
view_menu.set_item_checked(Global.ViewMenu.SHOW_RULERS, Global.show_rulers)
|
view_menu.set_item_checked(Global.ViewMenu.SHOW_RULERS, Global.show_rulers)
|
||||||
|
|
Loading…
Reference in a new issue