Add files via upload
This commit is contained in:
committed by
GitHub
parent
c2825f22d3
commit
011b668b2b
438
Penpot2Godot/DesignerFrame.gd
Normal file
438
Penpot2Godot/DesignerFrame.gd
Normal file
@@ -0,0 +1,438 @@
|
||||
@tool
|
||||
class_name DesignerFrame
|
||||
extends ScrollContainer
|
||||
|
||||
var script_dir:String = get_script().get_path().get_base_dir()
|
||||
var frameShaderPath:String = script_dir + "/shader/vertextApplyShader.gdshader"
|
||||
var is_scene_ready:bool = false
|
||||
var the_name:String
|
||||
var the_id:String
|
||||
var isInAutoContainer:bool = false
|
||||
var disable_size_update:bool = false
|
||||
@export_category("Frame Controls")
|
||||
## Select the node that will be the content container for the ScrollContainer.
|
||||
@export var inner_container: NodePath : set = update_props
|
||||
## This differs from the default Godot anchors in that changing the anchors does not change the position or size of the frame/node.
|
||||
@export_enum("Left","Center","Right","Left and Right") var horizontalAnchor: String = "Left" : set = set_anchor_horizontal
|
||||
## This differs from the default Godot anchors in that changing the anchors does not change the position or size of the frame/node.
|
||||
@export_enum("Top","Center","Bottom","Top and Bottom") var verticalAnchor: String = "Top" : set = set_anchor_vertical
|
||||
@export_group("Size")
|
||||
## Determines how the node will scale when in an auto layout.
|
||||
@export_enum("FIXED", "FILL", "HUG") var widthSizeMode: String = "FIXED" : set = set_wSizing
|
||||
## Determines how the node will scale when in an auto layout.
|
||||
@export_enum("FIXED", "FILL", "HUG") var heightSizeMode: String = "FIXED" : set = set_hSizing
|
||||
##If you want to manually control dimensions in auto-layouts, you do so by setting minimum size.
|
||||
@export var minSize:Vector2 = Vector2(1.0,1.0) : set = set_minimum_size
|
||||
@export var maxSize:Vector2 = Vector2(10000.0,10000.0) :
|
||||
set(value):
|
||||
maxSize = value
|
||||
@export_range(-180.0, 180.0, 0.1) var frameRotation:float :
|
||||
set(value):
|
||||
if is_scene_ready:
|
||||
self.set_rotation_degrees(value)
|
||||
frameRotation = value
|
||||
## Centers the rotation/transform pivot point. This will be maintain even when changing the node size.
|
||||
@export var center_rotation:bool = false : set = center_the_rotation
|
||||
## Note that in Godot, clipping will not rotate with the frame/node.
|
||||
@export var clipFrameContents:bool = false : set = set_clipping
|
||||
@export_enum("None","Horizontal","Vertical","Both") var scrollingMode: String = "None" : set = set_scrolling
|
||||
@export_group("Style and Padding")
|
||||
## If you find changing one node is changing others, click this to break the style link. This will duplicate the Stylebox and shader to break it free of others.
|
||||
@export var breakStyleLinks:bool : set = break_the_style_link
|
||||
@export_subgroup("Fill Color")
|
||||
@export var fill_color:Color = Color(0.6,0.6,0.6,1.0): set = set_background_fill
|
||||
## When placing an image with transparency, this option determines if the fill color appears behind it.
|
||||
@export var use_solid_fill:bool : set = set_use_solid
|
||||
@export var fill_gradient:GradientTexture2D: set = set_background_gradient
|
||||
## If there is a fill image, you can set whether it appears in front of or behind that image.
|
||||
@export var gradient_behind_image:bool : set = set_gradientBehindImage
|
||||
@export_subgroup("Fill Image")
|
||||
@export var fill_texture: Texture : set = set_background_image
|
||||
##Expands the image when using edge anti-aliasing.
|
||||
@export_range(0.001, 1.0, 0.001) var edge_fill: float = 0.001 : set = update_edge_tolerance
|
||||
## Godot will repeat the edge of pixels if there is not transparency and image does not fill the frame.
|
||||
@export_enum("Fill", "Fit", "Stretch", "Keep Size") var textureSizeMode: String = "Fill" : set = set_image_sizing
|
||||
@export var flip_x:bool : set = set_image_flipx
|
||||
@export var flip_y:bool : set = set_image_flipy
|
||||
@export_range(0.0, 6.0, 0.01) var zoom: float = 1.0 : set = update_fill_zoom
|
||||
@export var tile_texture:bool : set = update_text_tile
|
||||
@export var size_stretch:Vector2 = Vector2(1.0,1.0) : set = update_size_stretch
|
||||
@export var position_offset:Vector2 = Vector2(0.0,0.0) : set = update_position_offset
|
||||
@export var tint_color:Color = Color(1.0,1.0,1.0,1.0) : set = set_tint_color
|
||||
@export_subgroup("Border Stroke")
|
||||
@export var border_line_weight_all:int : set = set_borders
|
||||
## An array of 4 border weights. Top, Right, Bottom, Left.
|
||||
@export var border_weights:Array : set = add_border
|
||||
@export var border_color:Color : set = add_border_color
|
||||
## Smooths the border line. This can create color artifacts if using fill textures. See Edge Fill.
|
||||
@export var anti_alias_border:bool = false : set = set_border_alias
|
||||
@export_enum("inner", "center", "outer") var border_align: String = "inside" : set = set_border_align
|
||||
@export_subgroup("Corners")
|
||||
@export var corner_radius_all:int : set = change_all_corners
|
||||
## An array of 4 corner radius. Top, Right, Bottom, Left.
|
||||
@export var corner_radius:Array : set = round_the_corners
|
||||
@export_subgroup("Padding")
|
||||
@export var padding_all:int : set = padding_override
|
||||
## An array of 4 paddings. Top, Right, Bottom, Left.
|
||||
@export var padding:Array : set = update_padding
|
||||
@export_subgroup("Shadow")
|
||||
@export var shadow_color:Color = Color(0.0,0.0,0.0,0.5): set = update_shadow_color
|
||||
@export var shadow_size:int : set = update_shadow_size
|
||||
@export var shadow_offest:Vector2 = Vector2(0.0,0.0) : set = update_shadow_offest
|
||||
@export_group("Auto Layout")
|
||||
## Creates or changes the direction and type of auto layout. This will swap the inner container node with the appropriate Godot control node.
|
||||
@export_enum("NONE", "VERTICAL", "HORIZONTAL","GRID") var layoutMode: String = "NONE" : set = set_layout_mode
|
||||
@export_enum("NO_WRAP", "WRAP") var layoutWrap: String = "NO_WRAP" : set = set_layout_wrap
|
||||
## Changes the child node positioning. This is different from default Godot as it is changing each child's positioning when needed vs just modifying the parent container.
|
||||
@export_enum("Left", "Center", "Right") var hLayoutAlign: String = "Left" : set = set_h_alignm
|
||||
## Changes the child node positioning. This is different from default Godot as it is changing each child's positioning when needed vs just modifying the parent container.
|
||||
@export_enum("Top", "Center", "Bottom") var vLayoutAlign: String = "Top" : set = set_v_alignm
|
||||
@export var spacing:int = 0 : set = set_gap_space
|
||||
## In some containers you can change the horizontal and vertical spacing.
|
||||
@export var secondary_spacing:int = 0 : set = set_vgap_space
|
||||
## This option will expand the space of children to automatically fit the space. Only works in Vertical and Horizontal NO_WRAP.
|
||||
@export var autoSpace:bool = false : set = space_override
|
||||
## The the number of columns in Grid mode.
|
||||
@export var grid_columns:int = 1 : set = set_grid_col
|
||||
|
||||
var styleBox: StyleBoxFlat
|
||||
|
||||
func _ready():
|
||||
self.resized.connect(_on_control_resized)
|
||||
if !has_theme_stylebox_override("panel"):
|
||||
var newstylebox = StyleBoxFlat.new()
|
||||
add_theme_stylebox_override("panel", newstylebox)
|
||||
styleBox = get_theme_stylebox("panel")
|
||||
else:
|
||||
styleBox = get_theme_stylebox("panel").duplicate()
|
||||
#if Engine.is_editor_hint():
|
||||
is_scene_ready = true
|
||||
|
||||
func _validate_property(property : Dictionary) -> void:
|
||||
if property.name == "textureSizeMode" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "flip_x" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "flip_y" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "zoom" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "tile_texture" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "size_stretch" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "position_offset" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "tint_color" and fill_texture == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "gradient_behind_image" and fill_gradient == null:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "edge_fill" and anti_alias_border == false:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "layoutMode" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "layoutWrap" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "hLayoutAlign" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "vLayoutAlign" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "spacing" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "secondary_spacing" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "autoSpace" and inner_container == NodePath(""):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "grid_columns" and (inner_container == NodePath("") || layoutMode != "GRID"):
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "horizontalAnchor" and isInAutoContainer == true:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "verticalAnchor" and isInAutoContainer == true:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "framePosition" and isInAutoContainer == true:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "frameRotation" and isInAutoContainer == true:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "center_rotation" and isInAutoContainer == true:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
if property.name == "frameSize" and isInAutoContainer == true:
|
||||
property.usage |= PROPERTY_USAGE_READ_ONLY
|
||||
|
||||
func _on_control_resized():
|
||||
UIDesignTools.restrictMaxSize(self,maxSize)
|
||||
UIDesignTools.centerOnResize(self,center_rotation)
|
||||
if UIDesignTools.shaderNameMatches(self,frameShaderPath):
|
||||
self.material.set_shader_parameter("node_size", Vector2(self.size))
|
||||
#if self.heightSizeMode == "HUG":
|
||||
#self.size_flags_vertical = SIZE_SHRINK_CENTER
|
||||
#self.size.y = 0.0
|
||||
#if self.widthSizeMode == "HUG":
|
||||
#self.size_flags_horizontal = SIZE_SHRINK_CENTER
|
||||
#self.size.x = 0.0
|
||||
|
||||
|
||||
func break_the_style_link(theValue):
|
||||
UIDesignTools.break_the_style_link(self,frameShaderPath)
|
||||
|
||||
func update_props(theNode):
|
||||
inner_container = theNode
|
||||
notify_property_list_changed()
|
||||
|
||||
func center_the_rotation(theVar):
|
||||
center_rotation = theVar
|
||||
UIDesignTools.center_the_rotation_s(self, is_scene_ready, center_rotation)
|
||||
|
||||
func update_shadow_color(theVar):
|
||||
shadow_color = theVar
|
||||
if is_scene_ready:
|
||||
styleBox.set("shadow_color", shadow_color)
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func update_shadow_size(theVar):
|
||||
shadow_size = theVar
|
||||
if is_scene_ready:
|
||||
styleBox.set("shadow_size", shadow_size)
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func update_shadow_offest(theVar):
|
||||
shadow_offest = theVar
|
||||
if is_scene_ready:
|
||||
styleBox.set("shadow_offset", shadow_offest)
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func set_tint_color(theVar):
|
||||
tint_color = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("tint_color", tint_color)
|
||||
|
||||
func update_position_offset(theVar):
|
||||
position_offset = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("offset", position_offset)
|
||||
|
||||
func update_size_stretch(theVar):
|
||||
size_stretch = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("stretch", size_stretch)
|
||||
|
||||
func update_text_tile(theVar):
|
||||
tile_texture = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("tile_texture", tile_texture)
|
||||
|
||||
func update_fill_zoom(theVar):
|
||||
zoom = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("texture_scale", zoom)
|
||||
|
||||
func set_image_flipx(theVar):
|
||||
flip_x = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("flip_x", flip_x)
|
||||
|
||||
func set_image_flipy(theVar):
|
||||
flip_y = theVar
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("flip_y", flip_y)
|
||||
|
||||
func update_edge_tolerance(newTol):
|
||||
edge_fill = newTol
|
||||
if fill_texture != null && UIDesignTools.shaderNameMatches(self,frameShaderPath) && is_scene_ready:
|
||||
self.material.set_shader_parameter("tolerance", newTol)
|
||||
|
||||
func set_image_sizing(theSizing):
|
||||
textureSizeMode = theSizing
|
||||
UIDesignTools.set_image_sizing(self,textureSizeMode,frameShaderPath)
|
||||
|
||||
func set_use_solid(theVar):
|
||||
use_solid_fill = theVar
|
||||
if UIDesignTools.shaderNameMatches(self,frameShaderPath):
|
||||
self.material.set_shader_parameter("use_solid", use_solid_fill)
|
||||
|
||||
func set_gradientBehindImage(theVar):
|
||||
gradient_behind_image = theVar
|
||||
if UIDesignTools.shaderNameMatches(self,frameShaderPath):
|
||||
self.material.set_shader_parameter("gradient_behind", gradient_behind_image)
|
||||
|
||||
func set_background_gradient(_theGradient):
|
||||
fill_gradient = _theGradient
|
||||
UIDesignTools.set_background_gradient(self,is_scene_ready,fill_gradient,frameShaderPath)
|
||||
|
||||
func set_background_image(_theTexture):
|
||||
fill_texture = _theTexture
|
||||
UIDesignTools.set_background_image(self,is_scene_ready,fill_texture,frameShaderPath)
|
||||
|
||||
func set_wSizing(_theSize):
|
||||
widthSizeMode = _theSize
|
||||
UIDesignTools.set_wSizing(self,is_scene_ready,widthSizeMode)
|
||||
|
||||
func set_hSizing(_theSize):
|
||||
heightSizeMode = _theSize
|
||||
UIDesignTools.set_hSizing(self,is_scene_ready,heightSizeMode)
|
||||
|
||||
func set_scrolling(_theScroll):
|
||||
scrollingMode = _theScroll
|
||||
UIDesignTools.set_scrolling(self,is_scene_ready,scrollingMode)
|
||||
|
||||
func set_max_size(_theSize):
|
||||
maxSize = _theSize
|
||||
|
||||
func set_minimum_size(_theSize):
|
||||
minSize = _theSize
|
||||
if is_scene_ready:
|
||||
self.custom_minimum_size = minSize
|
||||
|
||||
func set_anchor_horizontal(_theAnchorString):
|
||||
horizontalAnchor = _theAnchorString
|
||||
UIDesignTools.set_anchor_horizontal(self,is_scene_ready,horizontalAnchor)
|
||||
|
||||
func set_anchor_vertical(_theAnchorString):
|
||||
verticalAnchor = _theAnchorString
|
||||
UIDesignTools.set_anchor_vertical(self,is_scene_ready,verticalAnchor)
|
||||
|
||||
func set_clipping(_theVar):
|
||||
clipFrameContents = _theVar
|
||||
self.clip_contents = clipFrameContents
|
||||
|
||||
func set_layout_wrap(_theVar):
|
||||
layoutWrap = _theVar
|
||||
if is_scene_ready:
|
||||
UIDesignTools.change_layout(self,inner_container)
|
||||
|
||||
func set_layout_mode(_theVar):
|
||||
layoutMode = _theVar
|
||||
if layoutMode == "NONE":
|
||||
layoutWrap = "NO_WRAP"
|
||||
if is_scene_ready:
|
||||
UIDesignTools.change_layout(self,inner_container)
|
||||
|
||||
func set_h_alignm(_theVar):
|
||||
hLayoutAlign = _theVar
|
||||
if is_scene_ready:
|
||||
UIDesignTools.container_align_adjust(self,inner_container)
|
||||
UIDesignTools.children_halign_adjust(self,inner_container)
|
||||
UIDesignTools.update_gap_space(self,inner_container)
|
||||
|
||||
|
||||
func set_v_alignm(_theVar):
|
||||
vLayoutAlign = _theVar
|
||||
if is_scene_ready:
|
||||
UIDesignTools.container_align_adjust(self,inner_container)
|
||||
UIDesignTools.children_valign_adjust(self,inner_container)
|
||||
UIDesignTools.update_gap_space(self,inner_container)
|
||||
|
||||
func round_the_corners(_theRound):
|
||||
corner_radius = _theRound
|
||||
if is_scene_ready:
|
||||
if corner_radius != []:
|
||||
styleBox.set("corner_radius_top_left", corner_radius[0])
|
||||
styleBox.set("corner_radius_top_right", corner_radius[1])
|
||||
styleBox.set("corner_radius_bottom_right", corner_radius[2])
|
||||
styleBox.set("corner_radius_bottom_left", corner_radius[3])
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func change_all_corners(_theRound):
|
||||
corner_radius_all = _theRound
|
||||
if is_scene_ready:
|
||||
corner_radius = [corner_radius_all,corner_radius_all,corner_radius_all,corner_radius_all]
|
||||
|
||||
func set_background_fill(_theFill):
|
||||
fill_color = _theFill
|
||||
if is_scene_ready:
|
||||
if UIDesignTools.shaderNameMatches(self,frameShaderPath):
|
||||
styleBox.set("bg_color", Color(0.6,0.6,0.6,1.0))
|
||||
self.material.set_shader_parameter("new_bg_color", fill_color)
|
||||
else:
|
||||
styleBox.set("bg_color", Color(fill_color))
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func add_border(_theBorder):
|
||||
border_weights = _theBorder
|
||||
if is_scene_ready:
|
||||
if border_weights != []:
|
||||
styleBox.set("border_width_top", border_weights[0])
|
||||
styleBox.set("border_width_right", border_weights[1])
|
||||
styleBox.set("border_width_bottom", border_weights[2])
|
||||
styleBox.set("border_width_left", border_weights[3])
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
update_padding(padding)
|
||||
|
||||
func set_border_align(theVar):
|
||||
border_align = theVar
|
||||
if is_scene_ready:
|
||||
match border_align:
|
||||
"inner":
|
||||
styleBox.set("expand_margin_left", 0)
|
||||
styleBox.set("expand_margin_top", 0)
|
||||
styleBox.set("expand_margin_right", 0)
|
||||
styleBox.set("expand_margin_bottom", 0)
|
||||
"center":
|
||||
clipFrameContents = false
|
||||
styleBox.set("expand_margin_left", border_weights[3] / 2)
|
||||
styleBox.set("expand_margin_top", border_weights[0] / 2)
|
||||
styleBox.set("expand_margin_right", border_weights[1] / 2)
|
||||
styleBox.set("expand_margin_bottom", border_weights[2] / 2)
|
||||
"outer":
|
||||
clipFrameContents = false
|
||||
styleBox.set("expand_margin_left", border_weights[3])
|
||||
styleBox.set("expand_margin_top", border_weights[0])
|
||||
styleBox.set("expand_margin_right", border_weights[1])
|
||||
styleBox.set("expand_margin_bottom", border_weights[2])
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
notify_property_list_changed()
|
||||
|
||||
func set_border_alias(theVar):
|
||||
anti_alias_border = theVar
|
||||
if is_scene_ready:
|
||||
styleBox.set("anti_aliasing", theVar)
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
if theVar == false:
|
||||
edge_fill = 0.001
|
||||
notify_property_list_changed()
|
||||
|
||||
func set_borders(_borderSize):
|
||||
border_line_weight_all = _borderSize
|
||||
if is_scene_ready:
|
||||
add_border([border_line_weight_all,border_line_weight_all,border_line_weight_all,border_line_weight_all])
|
||||
|
||||
func add_border_color(_theBorderColor):
|
||||
border_color = _theBorderColor
|
||||
if is_scene_ready:
|
||||
styleBox.set("border_color", border_color)
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func update_padding(_thePadding):
|
||||
padding = _thePadding
|
||||
if is_scene_ready:
|
||||
if padding == []:
|
||||
padding = [0,0,0,0]
|
||||
styleBox.set("content_margin_top", padding[0])
|
||||
styleBox.set("content_margin_right", padding[1])
|
||||
styleBox.set("content_margin_bottom", padding[2])
|
||||
styleBox.set("content_margin_left", padding[3])
|
||||
add_theme_stylebox_override("panel", styleBox)
|
||||
|
||||
func padding_override(_thePadding):
|
||||
padding_all = _thePadding
|
||||
if is_scene_ready:
|
||||
padding = [padding_all,padding_all,padding_all,padding_all]
|
||||
|
||||
func set_grid_col(_newCol):
|
||||
grid_columns = _newCol
|
||||
if layoutMode == "GRID" && is_scene_ready:
|
||||
get_node(inner_container).columns = grid_columns
|
||||
|
||||
func set_gap_space(_newGapSpace):
|
||||
spacing = _newGapSpace
|
||||
if is_scene_ready:
|
||||
UIDesignTools.update_gap_space(self,inner_container)
|
||||
|
||||
func set_vgap_space(_newGapSpace):
|
||||
secondary_spacing = _newGapSpace
|
||||
if is_scene_ready:
|
||||
UIDesignTools.update_gap_space(self,inner_container)
|
||||
|
||||
func space_override(_theVar):
|
||||
autoSpace = _theVar
|
||||
if is_scene_ready:
|
||||
UIDesignTools.update_gap_space(self,inner_container)
|
||||
470
Penpot2Godot/designcontrols.gd
Normal file
470
Penpot2Godot/designcontrols.gd
Normal file
@@ -0,0 +1,470 @@
|
||||
extends Control
|
||||
class_name UIDesignTools
|
||||
|
||||
#var script_dir:String = get_script().get_path().get_base_dir()
|
||||
#const frameShaderPath:String = "res://shader/vertextApplyShader.gdshader"
|
||||
|
||||
static func center_the_rotation_s(theNode:Control, is_scene_ready:bool, center_rotation:bool)->void:
|
||||
if is_scene_ready:
|
||||
var cur_pos = theNode.position
|
||||
var cur_offset = theNode.pivot_offset
|
||||
var global_position_before = theNode.global_position
|
||||
if (center_rotation == true):
|
||||
theNode.pivot_offset.x = theNode.size.x / 2
|
||||
theNode.pivot_offset.y = theNode.size.y / 2
|
||||
var new_pivot_offset = theNode.pivot_offset
|
||||
var local_offset_change = (new_pivot_offset - cur_offset).rotated(theNode.rotation)
|
||||
theNode.position -= local_offset_change
|
||||
theNode.global_position = global_position_before
|
||||
else:
|
||||
theNode.pivot_offset.x = 0.0
|
||||
theNode.pivot_offset.y = 0.0
|
||||
var new_pivot_offset = theNode.pivot_offset
|
||||
var local_offset_change = (new_pivot_offset - cur_offset).rotated(theNode.rotation)
|
||||
theNode.position += local_offset_change
|
||||
theNode.global_position = global_position_before
|
||||
|
||||
static func centerOnResize(theNode:Control, center_rotation:bool)->void:
|
||||
if center_rotation:
|
||||
theNode.pivot_offset.x = theNode.size.x / 2
|
||||
theNode.pivot_offset.y = theNode.size.y / 2
|
||||
|
||||
static func restrictMaxSize(theNode:Control, maxSize:Vector2)->void:
|
||||
if theNode.size.x > maxSize.x && maxSize.x != null :
|
||||
theNode.size.x = maxSize.x
|
||||
if theNode.size.y > maxSize.y && maxSize.y != null :
|
||||
theNode.size.y = maxSize.y
|
||||
|
||||
static func shaderNameMatches(theNode:Control,frameShaderPath:String)->bool:
|
||||
var shader_material = theNode.material
|
||||
if shader_material and shader_material is ShaderMaterial:
|
||||
var shader = shader_material.shader
|
||||
if shader:
|
||||
var shader_path = shader.resource_path
|
||||
if shader_path == frameShaderPath:
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
else:
|
||||
return false
|
||||
else:
|
||||
return false
|
||||
|
||||
static func set_background_gradient(theNode:Control,is_scene_ready:bool,fill_gradient,frameShaderPath:String)->void:
|
||||
if is_scene_ready:
|
||||
if fill_gradient == null:
|
||||
pass
|
||||
if shaderNameMatches(theNode,frameShaderPath):
|
||||
theNode.material.set_shader_parameter("use_gradient", false)
|
||||
if theNode.fill_texture == null:
|
||||
theNode.material = null
|
||||
theNode.styleBox.set("bg_color", theNode.fill_color)
|
||||
theNode.add_theme_stylebox_override("panel", theNode.styleBox)
|
||||
theNode.use_solid_fill = true
|
||||
theNode.notify_property_list_changed()
|
||||
elif !shaderNameMatches(theNode,frameShaderPath):
|
||||
var imageShader = load(frameShaderPath)
|
||||
var shader_material = ShaderMaterial.new()
|
||||
shader_material.shader = imageShader
|
||||
theNode.material = shader_material
|
||||
bgGradientActivate(theNode,fill_gradient)
|
||||
elif shaderNameMatches(theNode,frameShaderPath):
|
||||
bgGradientActivate(theNode,fill_gradient)
|
||||
|
||||
static func bgGradientActivate(theNode:Control,fill_gradient)->void:
|
||||
theNode.material.set_shader_parameter("gradient_texture", fill_gradient)
|
||||
theNode.material.set_shader_parameter("use_gradient", true)
|
||||
theNode.styleBox.set("bg_color", Color(0.6,0.6,0.6,1.0))
|
||||
theNode.material.set_shader_parameter("new_bg_color", theNode.fill_color)
|
||||
theNode.add_theme_stylebox_override("panel", theNode.styleBox)
|
||||
theNode.use_solid_fill = false
|
||||
theNode.notify_property_list_changed()
|
||||
|
||||
static func set_background_image(theNode:Control,is_scene_ready:bool,fill_texture:Texture,frameShaderPath:String)->void:
|
||||
if is_scene_ready:
|
||||
if fill_texture == null:
|
||||
if shaderNameMatches(theNode,frameShaderPath):
|
||||
theNode.material.set_shader_parameter("use_image", false)
|
||||
if theNode.fill_gradient == null:
|
||||
theNode.material = null
|
||||
theNode.styleBox.set("bg_color", theNode.fill_color)
|
||||
theNode.add_theme_stylebox_override("panel", theNode.styleBox)
|
||||
resetTextureDefaults(theNode)
|
||||
theNode.notify_property_list_changed()
|
||||
elif !shaderNameMatches(theNode,frameShaderPath):
|
||||
var imageShader = load(frameShaderPath)
|
||||
var shader_material = ShaderMaterial.new()
|
||||
shader_material.shader = imageShader
|
||||
theNode.material = shader_material
|
||||
bgImageActivate(theNode,fill_texture)
|
||||
elif shaderNameMatches(theNode,frameShaderPath):
|
||||
bgImageActivate(theNode,fill_texture)
|
||||
|
||||
static func bgImageActivate(theNode:Control,fill_texture:Texture)->void:
|
||||
theNode.material.set_shader_parameter("image_texture", fill_texture)
|
||||
theNode.material.set_shader_parameter("use_image", true)
|
||||
theNode.material.set_shader_parameter("node_size", Vector2(theNode.size))
|
||||
theNode.material.set_shader_parameter("texture_size", fill_texture.get_size())
|
||||
theNode.styleBox.set("bg_color", Color(0.6,0.6,0.6,1.0))
|
||||
theNode.material.set_shader_parameter("new_bg_color", theNode.fill_color)
|
||||
theNode.add_theme_stylebox_override("panel", theNode.styleBox)
|
||||
theNode.use_solid_fill = theNode.use_solid_fill
|
||||
theNode.notify_property_list_changed()
|
||||
|
||||
static func resetTextureDefaults(theNode:Control)->void:
|
||||
theNode.textureSizeMode = "Fill"
|
||||
theNode.flip_x = false
|
||||
theNode.flip_y = false
|
||||
theNode.zoom = 1.0
|
||||
theNode.tile_texture = false
|
||||
theNode.size_stretch = Vector2(1.0,1.0)
|
||||
theNode.position_offset = Vector2(0.0,0.0)
|
||||
theNode.tint_color = Color(1.0,1.0,1.0,1.0)
|
||||
|
||||
static func set_image_sizing(theNode:Control,textureSizeMode:String,frameShaderPath:String)->void:
|
||||
if theNode.fill_texture != null && shaderNameMatches(theNode,frameShaderPath):
|
||||
match textureSizeMode:
|
||||
"Fill":
|
||||
theNode.zoom = 1.0
|
||||
theNode.size_stretch = Vector2(1.0,1.0)
|
||||
theNode.position_offset = Vector2(0.0,0.0)
|
||||
theNode.material.set_shader_parameter("keep_aspect", true)
|
||||
theNode.material.set_shader_parameter("fill_rect", true)
|
||||
theNode.material.set_shader_parameter("manual_scale", false)
|
||||
"Fit":
|
||||
theNode.zoom = 1.0
|
||||
theNode.size_stretch = Vector2(1.0,1.0)
|
||||
theNode.position_offset = Vector2(0.0,0.0)
|
||||
theNode.material.set_shader_parameter("keep_aspect", true)
|
||||
theNode.material.set_shader_parameter("fill_rect", false)
|
||||
theNode.material.set_shader_parameter("manual_scale", false)
|
||||
"Stretch":
|
||||
theNode.zoom = 1.0
|
||||
theNode.size_stretch = Vector2(1.0,1.0)
|
||||
theNode.position_offset = Vector2(0.0,0.0)
|
||||
theNode.material.set_shader_parameter("keep_aspect", false)
|
||||
theNode.material.set_shader_parameter("fill_rect", false)
|
||||
theNode.material.set_shader_parameter("manual_scale", false)
|
||||
"Keep Size":
|
||||
theNode.material.set_shader_parameter("keep_aspect", true)
|
||||
theNode.material.set_shader_parameter("fill_rect", false)
|
||||
theNode.material.set_shader_parameter("manual_scale", true)
|
||||
|
||||
static func break_the_style_link(theNode:Control,frameShaderPath:String)->void:
|
||||
theNode.styleBox = theNode.get_theme_stylebox("panel").duplicate()
|
||||
if shaderNameMatches(theNode,frameShaderPath):
|
||||
theNode.material = theNode.material.duplicate()
|
||||
if theNode.fill_gradient != null:
|
||||
theNode.fill_gradient = theNode.fill_gradient.duplicate()
|
||||
|
||||
static func set_wSizing(theNode:Control,is_scene_ready:bool,widthSizeMode:String)->void:
|
||||
if is_scene_ready:
|
||||
match widthSizeMode:
|
||||
"HUG", "auto":
|
||||
theNode.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
if theNode is ScrollContainer:
|
||||
theNode.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
theNode.minSize.x = 0.0
|
||||
theNode.size.x = 0.0
|
||||
"FIXED", "fix":
|
||||
theNode.minSize.x = theNode.size.x
|
||||
theNode.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
if theNode is ScrollContainer:
|
||||
set_scrolling(theNode,is_scene_ready,theNode.scrollingMode)
|
||||
"FILL", "fill":
|
||||
theNode.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
||||
static func set_hSizing(theNode:Control,is_scene_ready:bool,heightSizeMode:String)->void:
|
||||
if is_scene_ready:
|
||||
match heightSizeMode:
|
||||
"HUG", "auto":
|
||||
theNode.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
if theNode is ScrollContainer:
|
||||
theNode.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||||
theNode.minSize.y = 0.0
|
||||
theNode.size.y = 0.0
|
||||
"FIXED", "fix":
|
||||
theNode.minSize.y = theNode.size.y
|
||||
theNode.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
if theNode is ScrollContainer:
|
||||
set_scrolling(theNode,is_scene_ready,theNode.scrollingMode)
|
||||
"FILL", "fill":
|
||||
theNode.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
static func set_scrolling(theNode:Control,is_scene_ready:bool,scrollingMode:String):
|
||||
if is_scene_ready:
|
||||
match scrollingMode:
|
||||
"None":
|
||||
if theNode.widthSizeMode != "HUG":
|
||||
theNode.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
|
||||
if theNode.heightSizeMode != "HUG":
|
||||
theNode.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
|
||||
"Horizontal":
|
||||
if theNode.widthSizeMode != "HUG":
|
||||
theNode.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO
|
||||
if theNode.heightSizeMode != "HUG":
|
||||
theNode.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
|
||||
"Vertical":
|
||||
if theNode.widthSizeMode != "HUG":
|
||||
theNode.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER
|
||||
if theNode.heightSizeMode != "HUG":
|
||||
theNode.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO
|
||||
"Both":
|
||||
if theNode.widthSizeMode != "HUG":
|
||||
theNode.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO
|
||||
if theNode.heightSizeMode != "HUG":
|
||||
theNode.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO
|
||||
|
||||
static func set_anchor_horizontal(theNode:Control,is_scene_ready:bool,horizontalAnchor:String):
|
||||
if is_scene_ready:
|
||||
var my_width = theNode.size.x
|
||||
var myHpos = theNode.position.x
|
||||
match horizontalAnchor:
|
||||
"Left":
|
||||
theNode.anchor_left = 0.0
|
||||
theNode.anchor_right = 0.0
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
"Center":
|
||||
theNode.anchor_left = 0.5
|
||||
theNode.anchor_right = 0.5
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
"Right":
|
||||
theNode.anchor_left = 1.0
|
||||
theNode.anchor_right = 1.0
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
"Left and Right":
|
||||
theNode.anchor_left = 0.0
|
||||
theNode.anchor_right = 1.0
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
theNode.grow_horizontal = Control.GROW_DIRECTION_BOTH
|
||||
"Scale":
|
||||
pass
|
||||
#need object bounds
|
||||
|
||||
static func set_anchor_vertical(theNode:Control,is_scene_ready:bool,verticalAnchor:String):
|
||||
if is_scene_ready:
|
||||
var my_height = theNode.size.y
|
||||
var myVpos = theNode.position.y
|
||||
match verticalAnchor:
|
||||
"Top":
|
||||
theNode.anchor_top = 0.0
|
||||
theNode.anchor_bottom = 0.0
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
"Center":
|
||||
theNode.anchor_top = 0.5
|
||||
theNode.anchor_bottom = 0.5
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
"Bottom":
|
||||
theNode.anchor_top = 1.0
|
||||
theNode.anchor_bottom = 1.0
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
"Top and Bottom":
|
||||
theNode.anchor_top = 0.0
|
||||
theNode.anchor_bottom = 1.0
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
theNode.grow_vertical = Control.GROW_DIRECTION_BOTH
|
||||
"Scale":
|
||||
pass
|
||||
|
||||
static func change_layout(theNode:Control,inner_container:NodePath)->void:
|
||||
if !theNode.is_scene_ready:
|
||||
return
|
||||
if theNode.layoutWrap == "NO_WRAP":
|
||||
match theNode.layoutMode:
|
||||
"NONE":
|
||||
var ControlClass = Control.new()
|
||||
ControlClass.name = theNode.get_node(inner_container).name
|
||||
ControlClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
ControlClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(ControlClass, true)
|
||||
"VERTICAL":
|
||||
var VBoxClass = VBoxContainer.new()
|
||||
VBoxClass.name = theNode.get_node(inner_container).name
|
||||
VBoxClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
VBoxClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(VBoxClass, true)
|
||||
"HORIZONTAL":
|
||||
var HBoxClass = HBoxContainer.new()
|
||||
HBoxClass.name = theNode.get_node(inner_container).name
|
||||
HBoxClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
HBoxClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(HBoxClass, true)
|
||||
"GRID":
|
||||
var GBoxClass = GridContainer.new()
|
||||
GBoxClass.name = theNode.get_node(inner_container).name
|
||||
GBoxClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
GBoxClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(GBoxClass, true)
|
||||
set_grid_col(theNode,theNode.grid_columns,inner_container)
|
||||
change_child_layouts(theNode,inner_container)
|
||||
elif theNode.layoutWrap == "WRAP":
|
||||
match theNode.layoutMode:
|
||||
"NONE":
|
||||
theNode.layoutMode = "HORIZONTAL"
|
||||
"VERTICAL":
|
||||
var VFlowClass = VFlowContainer.new()
|
||||
VFlowClass.name = theNode.get_node(inner_container).name
|
||||
VFlowClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
VFlowClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(VFlowClass, true)
|
||||
"HORIZONTAL":
|
||||
var HFlowClass = HFlowContainer.new()
|
||||
HFlowClass.name = theNode.get_node(inner_container).name
|
||||
HFlowClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
HFlowClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(HFlowClass, true)
|
||||
"GRID":
|
||||
var GBoxClass = GridContainer.new()
|
||||
GBoxClass.name = theNode.get_node(inner_container).name
|
||||
GBoxClass.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
GBoxClass.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
theNode.get_node(inner_container).replace_by(GBoxClass, true)
|
||||
set_grid_col(theNode,theNode.grid_columns,inner_container)
|
||||
container_align_adjust(theNode,inner_container)
|
||||
update_gap_space(theNode,inner_container)
|
||||
theNode.notify_property_list_changed()
|
||||
|
||||
static func change_child_layouts(theNode:Control,inner_container:NodePath)->void:
|
||||
for c_node in theNode.get_node(inner_container).get_children():
|
||||
if c_node.get("layoutMode") != null:
|
||||
pass
|
||||
#print(layoutMode + " : " + c_node.name)
|
||||
elif c_node.get("layout_mode") != null:
|
||||
match theNode.layoutMode:
|
||||
"NONE":
|
||||
#c_node.layout_mode = 1
|
||||
c_node.size = c_node.custom_minimum_size
|
||||
c_node.anchor_left = 0.0
|
||||
c_node.anchor_right = 0.0
|
||||
c_node.anchor_top = 0.0
|
||||
c_node.anchor_bottom = 0.0
|
||||
"VERTICAL":
|
||||
c_node.layout_mode = 2
|
||||
"HORIZONTAL":
|
||||
c_node.layout_mode = 2
|
||||
"GRID":
|
||||
c_node.layout_mode = 2
|
||||
container_align_adjust(theNode,inner_container)
|
||||
children_valign_adjust(theNode,inner_container)
|
||||
children_halign_adjust(theNode,inner_container)
|
||||
update_gap_space(theNode,inner_container)
|
||||
|
||||
static func set_grid_col(theNode:Control,grid_columns:int,inner_container:NodePath):
|
||||
if theNode.layoutMode == "GRID":
|
||||
theNode.get_node(inner_container).columns = grid_columns
|
||||
|
||||
static func update_gap_space(theNode:Control,inner_container:NodePath)->void:
|
||||
if !theNode.is_scene_ready:
|
||||
return
|
||||
if (theNode.layoutWrap == "NO_WRAP" && theNode.layoutMode == "HORIZONTAL") || (theNode.layoutWrap == "NO_WRAP" && theNode.layoutMode == "VERTICAL"):
|
||||
if theNode.autoSpace:
|
||||
theNode.get_node(inner_container).add_theme_constant_override("separation", 0)
|
||||
var the_total:int = theNode.get_node(inner_container).get_child_count()
|
||||
var the_count:int = 0
|
||||
for c_node in theNode.get_node(inner_container).get_children():
|
||||
the_count += 1
|
||||
if the_count < the_total:
|
||||
match theNode.layoutMode:
|
||||
"VERTICAL":
|
||||
c_node.size_flags_vertical = Control.SIZE_EXPAND
|
||||
"HORIZONTAL":
|
||||
c_node.size_flags_horizontal = Control.SIZE_EXPAND
|
||||
else:
|
||||
children_valign_adjust(theNode,inner_container)
|
||||
children_halign_adjust(theNode,inner_container)
|
||||
theNode.get_node(inner_container).add_theme_constant_override("separation", theNode.spacing)
|
||||
elif theNode.layoutWrap == "WRAP" || theNode.layoutMode == "GRID":
|
||||
theNode.get_node(inner_container).add_theme_constant_override("h_separation", theNode.spacing)
|
||||
theNode.get_node(inner_container).add_theme_constant_override("v_separation", theNode.secondary_spacing)
|
||||
|
||||
static func container_align_adjust(theNode:Control,inner_container:NodePath)->void:
|
||||
if !theNode.is_scene_ready:
|
||||
return
|
||||
var the_container = theNode.get_node(inner_container)
|
||||
match theNode.layoutMode:
|
||||
"VERTICAL":
|
||||
if the_container.is_class("VFlowContainer"):
|
||||
match theNode.hLayoutAlign:
|
||||
"Left":
|
||||
the_container.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN | Control.SIZE_EXPAND
|
||||
"Center":
|
||||
the_container.size_flags_horizontal = Control.SIZE_SHRINK_CENTER | Control.SIZE_EXPAND
|
||||
"Right":
|
||||
the_container.size_flags_horizontal = Control.SIZE_SHRINK_END | Control.SIZE_EXPAND
|
||||
match theNode.vLayoutAlign:
|
||||
"Top":
|
||||
the_container.alignment = BoxContainer.AlignmentMode.ALIGNMENT_BEGIN
|
||||
"Center":
|
||||
the_container.alignment = BoxContainer.AlignmentMode.ALIGNMENT_CENTER
|
||||
"Bottom":
|
||||
the_container.alignment = BoxContainer.AlignmentMode.ALIGNMENT_END
|
||||
"HORIZONTAL":
|
||||
if the_container.is_class("HFlowContainer"):
|
||||
match theNode.vLayoutAlign:
|
||||
"Top":
|
||||
the_container.size_flags_vertical = Control.SIZE_SHRINK_BEGIN | Control.SIZE_EXPAND
|
||||
"Center":
|
||||
the_container.size_flags_vertical = Control.SIZE_SHRINK_CENTER | Control.SIZE_EXPAND
|
||||
"Bottom":
|
||||
the_container.size_flags_vertical = Control.SIZE_SHRINK_END | Control.SIZE_EXPAND
|
||||
match theNode.hLayoutAlign:
|
||||
"Left":
|
||||
the_container.alignment = BoxContainer.AlignmentMode.ALIGNMENT_BEGIN
|
||||
"Center":
|
||||
the_container.alignment = BoxContainer.AlignmentMode.ALIGNMENT_CENTER
|
||||
"Right":
|
||||
the_container.alignment = BoxContainer.AlignmentMode.ALIGNMENT_END
|
||||
|
||||
static func children_halign_adjust(theNode:Control,inner_container:NodePath)->void:
|
||||
if !theNode.is_scene_ready:
|
||||
return
|
||||
for c_node in theNode.get_node(inner_container).get_children():
|
||||
if c_node.size_flags_horizontal != Control.SIZE_FILL && c_node.size_flags_horizontal != Control.SIZE_EXPAND_FILL:
|
||||
match theNode.layoutMode:
|
||||
"VERTICAL":
|
||||
match theNode.hLayoutAlign:
|
||||
"Left":
|
||||
c_node.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
"Center":
|
||||
c_node.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
"Right":
|
||||
c_node.size_flags_horizontal = Control.SIZE_SHRINK_END
|
||||
"HORIZONTAL":
|
||||
match theNode.vLayoutAlign:
|
||||
"Top":
|
||||
c_node.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
"Center":
|
||||
c_node.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
|
||||
"Bottom":
|
||||
c_node.size_flags_horizontal = Control.SIZE_SHRINK_END
|
||||
|
||||
static func children_valign_adjust(theNode:Control,inner_container:NodePath)->void:
|
||||
if !theNode.is_scene_ready:
|
||||
return
|
||||
for c_node in theNode.get_node(inner_container).get_children():
|
||||
if c_node.size_flags_vertical != Control.SIZE_FILL && c_node.size_flags_vertical != Control.SIZE_EXPAND_FILL:
|
||||
match theNode.layoutMode:
|
||||
"VERTICAL":
|
||||
match theNode.hLayoutAlign:
|
||||
"Left":
|
||||
c_node.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
"Center":
|
||||
c_node.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
"Right":
|
||||
c_node.size_flags_vertical = Control.SIZE_SHRINK_END
|
||||
"HORIZONTAL":
|
||||
match theNode.vLayoutAlign:
|
||||
"Top":
|
||||
c_node.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
"Center":
|
||||
c_node.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
"Bottom":
|
||||
c_node.size_flags_vertical = Control.SIZE_SHRINK_END
|
||||
BIN
Penpot2Godot/errorTexture.png
Normal file
BIN
Penpot2Godot/errorTexture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
546
Penpot2Godot/penpot_process.gd
Normal file
546
Penpot2Godot/penpot_process.gd
Normal file
@@ -0,0 +1,546 @@
|
||||
@tool
|
||||
extends Control
|
||||
|
||||
var script_dir:String = get_script().get_path().get_base_dir()
|
||||
|
||||
@export_global_file("*.penpot") var penpot_file
|
||||
@export_global_dir var unzip_target
|
||||
@export_tool_button("Extract Penpot") var unzip_button = extract_all_from_zip
|
||||
@export_dir var fonts_folder
|
||||
@export_dir var images_folder :
|
||||
set(value):
|
||||
images_folder = value
|
||||
if images_folder == null || images_folder == "" || images_folder == " ":
|
||||
autoPlaceImages = false
|
||||
else:
|
||||
autoPlaceImages = true
|
||||
notify_property_list_changed()
|
||||
## Select or deselect if you want the importer to automatically import images.
|
||||
@export var autoPlaceImages:bool = false
|
||||
@export_tool_button("Process Penpot") var processBtn = dir_contents_trigger
|
||||
@export var SelectPage : String : set = changePageSelect
|
||||
@export var SelectBoard : String :
|
||||
set(value):
|
||||
SelectBoard = value
|
||||
if SelectBoard != "" && SelectBoard != "Select Board" && tool_ready:
|
||||
board_id_to_proc = strip_to_id(SelectBoard)
|
||||
notify_property_list_changed()
|
||||
@export_tool_button("Import Board") var importBoardBtn = process_board_from_button
|
||||
|
||||
var page_hints:String
|
||||
var frame_hints:String
|
||||
var pen_file_id:String
|
||||
var tool_ready:bool = false
|
||||
var board_id_to_proc:String
|
||||
var name_dictionary:Dictionary
|
||||
var parent_dictionary:Dictionary
|
||||
var lineage_dictionary:Dictionary
|
||||
var auto_layout_check:Dictionary
|
||||
var main_parent_pos:Vector2 = Vector2(0.0,0.0)
|
||||
|
||||
func _ready() -> void:
|
||||
pass
|
||||
SelectBoard = ""
|
||||
SelectPage = ""
|
||||
tool_ready = true
|
||||
|
||||
func _validate_property(property : Dictionary) -> void:
|
||||
if property.name == &"SelectPage":
|
||||
property.hint = PROPERTY_HINT_ENUM
|
||||
property.hint_string = page_hints
|
||||
if property.name == &"SelectBoard":
|
||||
property.hint = PROPERTY_HINT_ENUM
|
||||
property.hint_string = frame_hints
|
||||
|
||||
|
||||
func process_board_from_button():
|
||||
process_object(board_id_to_proc,true)
|
||||
|
||||
func process_object(the_board_id,position_override:bool):
|
||||
pass
|
||||
var the_page_id = strip_to_id(SelectPage)
|
||||
var path = unzip_target + "/files/" + pen_file_id + "/pages/" + the_page_id + "/" + the_board_id + ".json"
|
||||
var data_file = FileAccess.open(path, FileAccess.READ)
|
||||
var data_parsed = JSON.parse_string(data_file.get_as_text())
|
||||
var parent_cycle:String = ""
|
||||
var parent_lineage:String = ""
|
||||
#print(data_parsed["name"] + ": " + data_parsed["id"])
|
||||
name_dictionary[data_parsed["id"]] = data_parsed["name"]
|
||||
parent_dictionary[data_parsed["id"]] = data_parsed["parentId"]
|
||||
parent_cycle = data_parsed["parentId"]
|
||||
while parent_cycle != "00000000-0000-0000-0000-000000000000":
|
||||
parent_lineage = parent_cycle + "/InnerContainer/" + parent_lineage
|
||||
parent_cycle = parent_dictionary[parent_cycle]
|
||||
if parent_lineage != "":
|
||||
parent_lineage = parent_lineage.erase(parent_lineage.length()-1,1)
|
||||
lineage_dictionary[data_parsed["id"]] = parent_lineage
|
||||
var make_min_size:bool = false
|
||||
var process_forward:bool = true
|
||||
if data_parsed.has("layout") && (data_parsed["layout"] == "grid" || data_parsed["layout"] == "flex"):
|
||||
auto_layout_check[data_parsed["id"]] = true
|
||||
process_forward = false
|
||||
if auto_layout_check.has(data_parsed["parentId"]):
|
||||
make_min_size = auto_layout_check[data_parsed["parentId"]]
|
||||
match data_parsed["type"]:
|
||||
"frame", "rect":
|
||||
render_frame(data_parsed,parent_lineage,position_override,make_min_size)
|
||||
if data_parsed.has("shapes"):
|
||||
var shape_array = data_parsed["shapes"]
|
||||
if shape_array != null && shape_array.size() > 0:
|
||||
if process_forward:
|
||||
for the_count in shape_array:
|
||||
process_object(the_count,false)
|
||||
else:
|
||||
var the_count = shape_array.size()
|
||||
while the_count > 0:
|
||||
the_count -= 1
|
||||
process_object(shape_array[the_count],false)
|
||||
"text":
|
||||
render_text_frame(data_parsed,parent_lineage,position_override,make_min_size)
|
||||
"path":
|
||||
print("PATH")
|
||||
|
||||
func render_frame(data_parsed,the_parent,position_override:bool,set_min_sizes:bool):
|
||||
pass
|
||||
var newFrame
|
||||
newFrame = DesignerFrame.new()
|
||||
#newFrame.name = data_parsed["name"]+" xIDx"+ data_parsed["id"]+"x"
|
||||
newFrame.name = data_parsed["id"]
|
||||
if the_parent != null && the_parent != "":
|
||||
var parent = get_node(the_parent)
|
||||
parent.add_child(newFrame)
|
||||
else:
|
||||
add_child(newFrame)
|
||||
newFrame.set_owner(get_tree().get_edited_scene_root())
|
||||
newFrame.use_solid_fill = false
|
||||
newFrame.scrollingMode = "None"
|
||||
var newControl = Control.new()
|
||||
newControl.name = "InnerContainer"
|
||||
newFrame.add_child(newControl)
|
||||
newFrame.inner_container = newControl.get_path()
|
||||
newFrame.get_node(newFrame.inner_container).set_owner(get_tree().get_edited_scene_root())
|
||||
newFrame.get_node(newFrame.inner_container).size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
newFrame.get_node(newFrame.inner_container).size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
newFrame.the_id = data_parsed["id"]
|
||||
newFrame.set_deferred("center_rotation", true)
|
||||
if data_parsed.has("layoutItemHSizing"):
|
||||
newFrame.widthSizeMode = data_parsed["layoutItemHSizing"]
|
||||
if data_parsed.has("layoutItemVSizing"):
|
||||
newFrame.heightSizeMode = data_parsed["layoutItemVSizing"]
|
||||
if set_min_sizes:
|
||||
newFrame.minSize.x = data_parsed["width"]
|
||||
newFrame.minSize.y = data_parsed["height"]
|
||||
newFrame.set_deferred("size", Vector2(data_parsed["width"],data_parsed["height"]))
|
||||
if position_override:
|
||||
newFrame.set_deferred("global_position", Vector2(0.0,0.0))
|
||||
main_parent_pos = Vector2(data_parsed["x"],data_parsed["y"])
|
||||
else:
|
||||
newFrame.set_deferred("global_position", Vector2(data_parsed["x"] - main_parent_pos.x, data_parsed["y"] - main_parent_pos.y))
|
||||
newFrame.set_deferred("rotation_degrees", data_parsed["rotation"] * 1)
|
||||
if data_parsed.has("constraintsH"):
|
||||
match data_parsed["constraintsH"]:
|
||||
"left":
|
||||
newFrame.set_deferred("horizontalAnchor","Left")
|
||||
"right":
|
||||
newFrame.set_deferred("horizontalAnchor","Right")
|
||||
"leftright":
|
||||
newFrame.set_deferred("horizontalAnchor","Left and Right")
|
||||
"center":
|
||||
newFrame.set_deferred("horizontalAnchor","Center")
|
||||
"scale":
|
||||
newFrame.set_deferred("horizontalAnchor","Scale")
|
||||
if data_parsed.has("constraintsV"):
|
||||
match data_parsed["constraintsV"]:
|
||||
"top":
|
||||
newFrame.set_deferred("verticalAnchor","Top")
|
||||
"bottom":
|
||||
newFrame.set_deferred("verticalAnchor","Bottom")
|
||||
"topbottom":
|
||||
newFrame.set_deferred("verticalAnchor","Top and Bottom")
|
||||
"center":
|
||||
newFrame.set_deferred("verticalAnchor","Center")
|
||||
"scale":
|
||||
newFrame.set_deferred("verticalAnchor","Scale")
|
||||
if data_parsed.has("fills"):
|
||||
newFrame.fill_color = Color(0,0,0,0)
|
||||
for cur_fill in data_parsed["fills"]:
|
||||
if cur_fill.has("fillColor") && cur_fill.has("fillOpacity"):
|
||||
newFrame.fill_color = Color(Color.html(cur_fill["fillColor"]),cur_fill["fillOpacity"])
|
||||
newFrame.use_solid_fill = true
|
||||
if cur_fill.has("fillImage"):
|
||||
var image_texture_id = cur_fill["fillImage"]["id"]
|
||||
var image_json = unzip_target + "/files/" + pen_file_id + "/media/" + image_texture_id +".json"
|
||||
var the_image_file = find_image_from_json(image_json)
|
||||
var image_texture = load(unzip_target + "/objects/" + the_image_file) as Texture
|
||||
newFrame.fill_texture = image_texture
|
||||
if cur_fill.has("fillColorGradient"):
|
||||
var gradient = Gradient.new()
|
||||
for color_stop in cur_fill["fillColorGradient"]["stops"]:
|
||||
gradient.add_point(color_stop["offset"], Color(Color.html(color_stop["color"]), color_stop["opacity"]))
|
||||
gradient.remove_point(1)
|
||||
gradient.remove_point(0)
|
||||
var gradient_texture = GradientTexture2D.new()
|
||||
gradient_texture.gradient = gradient
|
||||
match cur_fill["fillColorGradient"]["type"]:
|
||||
"linear":
|
||||
gradient_texture.fill = GradientTexture2D.FILL_LINEAR
|
||||
"radial":
|
||||
gradient_texture.fill = GradientTexture2D.FILL_RADIAL
|
||||
gradient_texture.width = 64
|
||||
gradient_texture.height = 64
|
||||
gradient_texture.fill_from = Vector2(cur_fill["fillColorGradient"]["startX"],cur_fill["fillColorGradient"]["startY"])
|
||||
gradient_texture.fill_to = Vector2(cur_fill["fillColorGradient"]["endX"],cur_fill["fillColorGradient"]["endY"])
|
||||
newFrame.fill_gradient = gradient_texture
|
||||
if data_parsed.has("strokes"):
|
||||
if data_parsed["strokes"].size() > 0:
|
||||
newFrame.border_color = Color(Color.html(data_parsed["strokes"][0]["strokeColor"]),data_parsed["strokes"][0]["strokeOpacity"])
|
||||
newFrame.border_weights = [data_parsed["strokes"][0]["strokeWidth"],data_parsed["strokes"][0]["strokeWidth"],data_parsed["strokes"][0]["strokeWidth"],data_parsed["strokes"][0]["strokeWidth"]]
|
||||
newFrame.border_align = data_parsed["strokes"][0]["strokeAlignment"]
|
||||
newFrame.corner_radius = [data_parsed["r1"],data_parsed["r2"],data_parsed["r3"],data_parsed["r4"]]
|
||||
if data_parsed.has("layoutPadding"):
|
||||
newFrame.padding = [data_parsed["layoutPadding"]["p1"],data_parsed["layoutPadding"]["p2"],data_parsed["layoutPadding"]["p3"],data_parsed["layoutPadding"]["p4"]]
|
||||
if data_parsed.has("layout"):
|
||||
match data_parsed["layout"]:
|
||||
"flex":
|
||||
pass
|
||||
match data_parsed["layoutFlexDir"]:
|
||||
"row":
|
||||
newFrame.layoutMode = "HORIZONTAL"
|
||||
"column":
|
||||
newFrame.layoutMode = "VERTICAL"
|
||||
match data_parsed["layoutWrapType"]:
|
||||
"nowrap":
|
||||
newFrame.layoutWrap = "NO_WRAP"
|
||||
"wrap":
|
||||
newFrame.layoutWrap = "WRAP"
|
||||
newFrame.spacing = data_parsed["layoutGap"]["columnGap"]
|
||||
newFrame.secondary_spacing = data_parsed["layoutGap"]["rowGap"]
|
||||
match data_parsed["layoutAlignContent"]:
|
||||
"start":
|
||||
newFrame.set_deferred("hLayoutAlign", "Left")
|
||||
"center":
|
||||
newFrame.set_deferred("hLayoutAlign", "Center")
|
||||
"end":
|
||||
newFrame.set_deferred("hLayoutAlign", "Right")
|
||||
match data_parsed["layoutJustifyContent"]:
|
||||
"start":
|
||||
newFrame.set_deferred("vLayoutAlign", "Top")
|
||||
"end":
|
||||
newFrame.set_deferred("vLayoutAlign", "Bottom")
|
||||
"center":
|
||||
newFrame.set_deferred("vLayoutAlign", "Center")
|
||||
"grid":
|
||||
newFrame.layoutMode = "GRID"
|
||||
newFrame.spacing = data_parsed["layoutGap"]["columnGap"]
|
||||
newFrame.secondary_spacing = data_parsed["layoutGap"]["rowGap"]
|
||||
newFrame.grid_columns = data_parsed["layoutGridColumns"].size()
|
||||
if data_parsed.has("showContent"):
|
||||
newFrame.clipFrameContents = !data_parsed["showContent"]
|
||||
else:
|
||||
newFrame.clipFrameContents = false
|
||||
|
||||
func find_image_from_json(path):
|
||||
var data_file = FileAccess.open(path, FileAccess.READ)
|
||||
var data_parsed = JSON.parse_string(data_file.get_as_text())
|
||||
var file_type:String
|
||||
var file_name:String
|
||||
if data_parsed.has("mtype"):
|
||||
file_type = String(data_parsed["mtype"]).right(3)
|
||||
if data_parsed.has("mediaId"):
|
||||
file_name = data_parsed["mediaId"]
|
||||
var full_file_name:String = file_name + "." + file_type
|
||||
return full_file_name
|
||||
|
||||
func render_text_frame(data_parsed,the_parent,position_override:bool,set_min_sizes:bool):
|
||||
var newFrame = Label.new()
|
||||
var newLabelSettings = LabelSettings.new()
|
||||
|
||||
if fonts_folder != null and fonts_folder != "":
|
||||
var dynamic_font = FontFile.new()
|
||||
var font_name = str(data_parsed["positionData"][0]["fontFamily"]).replace(" ", "")
|
||||
var font_weight = str(data_parsed["positionData"][0]["fontWeight"]).replace(" ", "")
|
||||
var font_style = str(data_parsed["positionData"][0]["fontStyle"]).replace(" ", "")
|
||||
match font_weight:
|
||||
"100":
|
||||
font_weight = "Thin"
|
||||
"200":
|
||||
font_weight = "ExtraLight"
|
||||
"300":
|
||||
font_weight = "Light"
|
||||
"400":
|
||||
font_weight = "Regular"
|
||||
"500":
|
||||
font_weight = "Medium"
|
||||
"600":
|
||||
font_weight = "SemiBold"
|
||||
"700":
|
||||
font_weight = "Bold"
|
||||
"800":
|
||||
font_weight = "ExtraBold"
|
||||
"900":
|
||||
font_weight = "Black"
|
||||
match font_style:
|
||||
"italic":
|
||||
font_style = "Italic"
|
||||
_:
|
||||
font_style = ""
|
||||
var font_style_transformed:String = font_weight + font_style
|
||||
var font_location:String = fonts_folder + "/" + font_name + "-" + font_style_transformed + ".ttf"
|
||||
if FileAccess.file_exists(font_location):
|
||||
newLabelSettings.font = load(font_location)
|
||||
if data_parsed.has("constraintsH"):
|
||||
set_anchor_horizontal(data_parsed["constraintsH"],newFrame)
|
||||
if data_parsed.has("constraintsV"):
|
||||
set_anchor_vertical(data_parsed["constraintsV"],newFrame)
|
||||
var font_size_change = data_parsed["positionData"][0]["fontSize"]
|
||||
font_size_change = font_size_change.substr(0, font_size_change.length() - 2)
|
||||
newLabelSettings.font_size = int(font_size_change)
|
||||
if data_parsed.has("content") && data_parsed["content"].has("children") and data_parsed["content"]["children"].size() > 0 && data_parsed["content"]["children"][0].has("children") && data_parsed["content"]["children"][0]["children"].size() > 0 && data_parsed["content"]["children"][0]["children"][0].has("lineHeight"):
|
||||
newLabelSettings.line_spacing = float(font_size_change) - (float(font_size_change) * float(data_parsed["content"]["children"][0]["children"][0]["lineHeight"]))
|
||||
else:
|
||||
newLabelSettings.line_spacing = 0
|
||||
if data_parsed["positionData"][0].has("fills"):
|
||||
newLabelSettings.font_color = Color(Color.html(data_parsed["positionData"][0]["fills"][0]["fillColor"]),data_parsed["positionData"][0]["fills"][0]["fillOpacity"])
|
||||
newFrame.name = data_parsed["id"] #xIDx"+ make_safeName(p_id)+"x"
|
||||
var parent = get_node(the_parent)
|
||||
parent.add_child(newFrame)
|
||||
newFrame.set_label_settings(newLabelSettings)
|
||||
newFrame.set_owner(get_tree().get_edited_scene_root())
|
||||
newFrame.set_deferred("size", Vector2(data_parsed["width"],data_parsed["height"]))
|
||||
newFrame.set_deferred("autowrap_mode", TextServer.AUTOWRAP_WORD_SMART)
|
||||
#if data_parsed.has("content") && data_parsed["content"].has("children") and data_parsed["content"]["children"].size() > 0 && data_parsed["content"]["children"][0].has("children") && data_parsed["content"]["children"][0]["children"].size() > 0 && data_parsed["content"]["children"][0]["children"][0].has("children") && data_parsed["content"]["children"][0]["children"][0]["children"].size() > 0 && data_parsed["content"]["children"][0]["children"][0]["children"][0].has("text"):
|
||||
#newFrame.set_deferred("text",data_parsed["content"]["children"][0]["children"][0]["children"][0]["text"])
|
||||
var temp_text:String
|
||||
if data_parsed.has("positionData"):
|
||||
for pdat in data_parsed["positionData"]:
|
||||
temp_text += pdat["text"]
|
||||
newFrame.set_deferred("text",temp_text)
|
||||
#else:
|
||||
#newFrame.text = data_parsed["positionData"][0]["text"]
|
||||
if position_override:
|
||||
newFrame.set_deferred("global_position", Vector2(0.0,0.0))
|
||||
main_parent_pos = Vector2(data_parsed["x"],data_parsed["y"])
|
||||
else:
|
||||
newFrame.set_deferred("global_position", Vector2(data_parsed["x"] - main_parent_pos.x, data_parsed["y"] - main_parent_pos.y))
|
||||
newFrame.set_deferred("pivot_offset", Vector2(data_parsed["width"] / 2, data_parsed["height"] / 2))
|
||||
newFrame.set_deferred("rotation_degrees", data_parsed["rotation"] * 1)
|
||||
if data_parsed.has("content") && data_parsed["content"].has("children") and data_parsed["content"]["children"].size() > 0 && data_parsed["content"]["children"][0].has("children") && data_parsed["content"]["children"][0]["children"].size() > 0 && data_parsed["content"]["children"][0]["children"][0].has("textAlign"):
|
||||
update_textHAlign(data_parsed["content"]["children"][0]["children"][0]["textAlign"],newFrame)
|
||||
if data_parsed.has("content") && data_parsed["content"].has("verticalAlign"):
|
||||
update_textVAlign(data_parsed["content"]["verticalAlign"],newFrame)
|
||||
newFrame.custom_minimum_size = Vector2(data_parsed["width"],data_parsed["height"])
|
||||
if data_parsed.has("layoutItemHSizing"):
|
||||
set_textwSize(data_parsed["layoutItemHSizing"],newFrame,data_parsed["width"])
|
||||
if data_parsed.has("layoutItemVSizing"):
|
||||
set_texthSize(data_parsed["layoutItemVSizing"],newFrame,data_parsed["height"])
|
||||
|
||||
func update_textHAlign(_theVar,theNode):
|
||||
match _theVar:
|
||||
"left":
|
||||
theNode.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||
"center":
|
||||
theNode.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
"right":
|
||||
theNode.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
|
||||
func update_textVAlign(_theVar,theNode):
|
||||
match _theVar:
|
||||
"top":
|
||||
theNode.vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
||||
"center":
|
||||
theNode.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
"bottom":
|
||||
theNode.vertical_alignment = VERTICAL_ALIGNMENT_BOTTOM
|
||||
|
||||
func set_textwSize(widthSizeMode,theNode,theNodeWidth)->void:
|
||||
match widthSizeMode:
|
||||
"auto":
|
||||
theNode.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
theNode.size.x = 0.0
|
||||
"fix":
|
||||
theNode.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
||||
theNode.custom_minimum_size.x = theNodeWidth
|
||||
"fill":
|
||||
theNode.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
|
||||
func set_texthSize(heightSizeMode,theNode,theNodeHeight)->void:
|
||||
match heightSizeMode:
|
||||
"auto":
|
||||
theNode.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
theNode.size.y = 0.0
|
||||
"fix":
|
||||
theNode.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
||||
theNode.custom_minimum_size.y = theNodeHeight
|
||||
"fill":
|
||||
theNode.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||||
|
||||
func set_anchor_horizontal(horizontalAnchor:String,theNode)->void:
|
||||
var my_width = theNode.size.x
|
||||
var myHpos = theNode.position.x
|
||||
match horizontalAnchor:
|
||||
"left":
|
||||
theNode.anchor_left = 0.0
|
||||
theNode.anchor_right = 0.0
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
"center":
|
||||
theNode.anchor_left = 0.5
|
||||
theNode.anchor_right = 0.5
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
"right":
|
||||
theNode.anchor_left = 1.0
|
||||
theNode.anchor_right = 1.0
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
"leftright":
|
||||
theNode.anchor_left = 0.0
|
||||
theNode.anchor_right = 1.0
|
||||
theNode.position.x = myHpos
|
||||
theNode.size.x = my_width
|
||||
theNode.grow_horizontal = Control.GROW_DIRECTION_BOTH
|
||||
"scale":
|
||||
pass
|
||||
#need object bounds
|
||||
|
||||
func set_anchor_vertical(verticalAnchor:String,theNode)->void:
|
||||
var my_height = theNode.size.y
|
||||
var myVpos = theNode.position.y
|
||||
match verticalAnchor:
|
||||
"top":
|
||||
theNode.anchor_top = 0.0
|
||||
theNode.anchor_bottom = 0.0
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
"center":
|
||||
theNode.anchor_top = 0.5
|
||||
theNode.anchor_bottom = 0.5
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
"bottom":
|
||||
theNode.anchor_top = 1.0
|
||||
theNode.anchor_bottom = 1.0
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
"topbottom":
|
||||
theNode.anchor_top = 0.0
|
||||
theNode.anchor_bottom = 1.0
|
||||
theNode.position.y = myVpos
|
||||
theNode.size.y = my_height
|
||||
theNode.grow_vertical = Control.GROW_DIRECTION_BOTH
|
||||
"scale":
|
||||
pass
|
||||
#need object bounds
|
||||
# Extract all files from a ZIP archive, preserving the directories within.
|
||||
# This acts like the "Extract all" functionality from most archive managers.
|
||||
func extract_all_from_zip():
|
||||
var reader = ZIPReader.new()
|
||||
if penpot_file == null:
|
||||
print("no file")
|
||||
return
|
||||
reader.open(penpot_file)
|
||||
# Destination directory for the extracted files (this folder must exist before extraction).
|
||||
# Not all ZIP archives put everything in a single root folder,
|
||||
# which means several files/folders may be created in `root_dir` after extraction!
|
||||
if unzip_target == null:
|
||||
print("no extract directory")
|
||||
return
|
||||
var root_dir = DirAccess.open(unzip_target)
|
||||
|
||||
var files = reader.get_files()
|
||||
for file_path in files:
|
||||
# If the current entry is a directory.
|
||||
if file_path.ends_with("/"):
|
||||
root_dir.make_dir_recursive(file_path)
|
||||
continue
|
||||
# Write file contents, creating folders automatically when needed.
|
||||
# Not all ZIP archives are strictly ordered, so we need to do this in case
|
||||
# the file entry comes before the folder entry.
|
||||
root_dir.make_dir_recursive(root_dir.get_current_dir().path_join(file_path).get_base_dir())
|
||||
var file = FileAccess.open(root_dir.get_current_dir().path_join(file_path), FileAccess.WRITE)
|
||||
var buffer = reader.read_file(file_path)
|
||||
file.store_buffer(buffer)
|
||||
EditorInterface.get_resource_filesystem().scan()
|
||||
print("Extraction Complete")
|
||||
|
||||
func dir_contents_trigger():
|
||||
dir_contents(unzip_target)
|
||||
|
||||
func dir_contents(path):
|
||||
var dir = DirAccess.open(path)
|
||||
if dir:
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if dir.current_is_dir():
|
||||
pass
|
||||
#print("Found directory: " + file_name)
|
||||
else:
|
||||
#print("Found file: " + file_name)
|
||||
if file_name == "manifest.json":
|
||||
#Load the file.
|
||||
var the_file_loc = path + "/" + file_name
|
||||
var data_file = FileAccess.open(the_file_loc, FileAccess.READ)
|
||||
#Parse the json file.
|
||||
var data_parsed = JSON.parse_string(data_file.get_as_text())
|
||||
process_manifest(data_parsed)
|
||||
return
|
||||
file_name = dir.get_next()
|
||||
else:
|
||||
print("An error occurred when trying to access the path.")
|
||||
|
||||
func process_manifest(json_data):
|
||||
page_hints = "Select Page,"
|
||||
SelectPage = "Select Page"
|
||||
pen_file_id = json_data["files"][0]["id"]
|
||||
var path = unzip_target + "/files/" + pen_file_id + "/pages"
|
||||
var dir = DirAccess.open(path)
|
||||
if dir:
|
||||
dir.list_dir_begin()
|
||||
var file_name = dir.get_next()
|
||||
while file_name != "":
|
||||
if dir.current_is_dir():
|
||||
pass
|
||||
#print("Found directory: " + file_name)
|
||||
else:
|
||||
if file_name.ends_with(".json"):
|
||||
var page_json = path + "/" + file_name
|
||||
get_page_id(page_json)
|
||||
file_name = dir.get_next()
|
||||
else:
|
||||
print("An error occurred when trying to access the path.")
|
||||
|
||||
func get_page_id(json_data):
|
||||
var data_file = FileAccess.open(json_data, FileAccess.READ)
|
||||
var data_parsed = JSON.parse_string(data_file.get_as_text())
|
||||
page_hints += data_parsed["name"]+" ----- xIDx"+data_parsed["id"]+"x,"
|
||||
notify_property_list_changed()
|
||||
|
||||
func changePageSelect(_stuff):
|
||||
SelectPage = _stuff
|
||||
if SelectPage != "Select Page" && SelectPage != "":
|
||||
var the_page_id = strip_to_id(SelectPage)
|
||||
frame_hints = "Select Board,"
|
||||
SelectBoard = "Select Board"
|
||||
if tool_ready:
|
||||
loadPageShapes(the_page_id)
|
||||
notify_property_list_changed()
|
||||
|
||||
func loadPageShapes(page_id):
|
||||
pass
|
||||
var path = unzip_target + "/files/" + pen_file_id + "/pages/" + page_id
|
||||
var data_file = FileAccess.open(path + "/00000000-0000-0000-0000-000000000000.json", FileAccess.READ)
|
||||
var data_parsed = JSON.parse_string(data_file.get_as_text())
|
||||
var shape_array:Array = data_parsed["shapes"]
|
||||
for the_id in shape_array.size():
|
||||
var shape_data_file = FileAccess.open(path + "/" + shape_array[the_id] + ".json", FileAccess.READ)
|
||||
var shape_data_parsed = JSON.parse_string(shape_data_file.get_as_text())
|
||||
frame_hints += shape_data_parsed["name"]+" ----- xIDx"+shape_data_parsed["id"]+"x,"
|
||||
|
||||
func strip_to_id(input_string:String):
|
||||
var start_pos = input_string.find("xIDx") + 4
|
||||
var end_pos = input_string.rfind("x")
|
||||
if start_pos < end_pos:
|
||||
return input_string.substr(start_pos, end_pos - start_pos)
|
||||
else:
|
||||
print("no id")
|
||||
45
Penpot2Godot/shader/polygonimage.gdshader
Normal file
45
Penpot2Godot/shader/polygonimage.gdshader
Normal file
@@ -0,0 +1,45 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D image_texture : source_color, filter_linear, repeat_disable;
|
||||
uniform sampler2D gradient_texture : source_color, filter_linear, repeat_disable;
|
||||
uniform bool use_gradient = false;
|
||||
uniform bool use_image = false;
|
||||
uniform bool use_solid = true;
|
||||
uniform bool gradient_behind = false;
|
||||
varying vec4 vertex_color;
|
||||
uniform vec4 new_bg_color : source_color = vec4(0.6, 0.6, 0.6, 1.0);
|
||||
uniform vec4 tint_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
uniform vec2 texture_size;
|
||||
uniform float texture_scale : hint_range(0.0, 6.0) = 1.0;
|
||||
uniform vec2 stretch = vec2(1.0);
|
||||
uniform vec2 offset = vec2(0.0);
|
||||
uniform bool flip_x = false;
|
||||
uniform bool flip_y = false;
|
||||
uniform bool tile_texture = false;
|
||||
|
||||
void fragment() {
|
||||
float x_dir = flip_x ? -1.0 : 1.0;
|
||||
float y_dir = flip_y ? -1.0 : 1.0;
|
||||
vec2 uv = (UV / stretch - offset);
|
||||
float texture_aspect = texture_size.x / texture_size.y;
|
||||
uv -= 0.5;
|
||||
uv *= vec2(x_dir, y_dir);
|
||||
uv /= texture_scale;
|
||||
uv += 0.5;
|
||||
if (tile_texture) {
|
||||
uv = fract(uv);
|
||||
}
|
||||
vec4 image = texture(image_texture, uv);
|
||||
vec4 gradient = texture(gradient_texture,uv);
|
||||
|
||||
if (use_solid) { COLOR = new_bg_color; }
|
||||
if (gradient_behind && use_gradient) {
|
||||
if (use_solid) { COLOR.rgb = mix(COLOR.rgb, gradient.rgb, gradient.a); } else { COLOR = gradient; }
|
||||
}
|
||||
if (use_image) {
|
||||
if (use_solid || gradient_behind) { COLOR = mix(COLOR, tint_color * image, image.a); } else { COLOR = tint_color * image; }
|
||||
}
|
||||
if (!gradient_behind && use_gradient) {
|
||||
if(use_image || use_solid) { COLOR.rgb = mix(COLOR.rgb, gradient.rgb, gradient.a); } else { COLOR = gradient; }
|
||||
}
|
||||
}
|
||||
82
Penpot2Godot/shader/vertextApplyShader.gdshader
Normal file
82
Penpot2Godot/shader/vertextApplyShader.gdshader
Normal file
@@ -0,0 +1,82 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D image_texture : source_color, filter_linear, repeat_disable;
|
||||
uniform sampler2D gradient_texture : source_color, filter_linear, repeat_disable;
|
||||
uniform bool use_gradient = false;
|
||||
uniform bool use_image = false;
|
||||
uniform bool use_solid = true;
|
||||
uniform bool gradient_behind = false;
|
||||
uniform vec4 target_color : source_color = vec4(0.6, 0.6, 0.6, 1.0);
|
||||
uniform float tolerance : hint_range(0.001, 1.0,0.001) = 0.001;
|
||||
uniform vec4 new_bg_color : source_color = vec4(0.6, 0.6, 0.6, 1.0);
|
||||
uniform vec4 tint_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
uniform vec2 node_size;
|
||||
uniform vec2 texture_size;
|
||||
uniform float texture_scale : hint_range(0.0, 6.0) = 1.0;
|
||||
uniform vec2 stretch = vec2(1.0);
|
||||
uniform vec2 offset = vec2(0.0);
|
||||
uniform bool flip_x = false;
|
||||
uniform bool flip_y = false;
|
||||
uniform bool keep_aspect = true;
|
||||
uniform bool fill_rect = true;
|
||||
uniform bool tile_texture = false;
|
||||
uniform bool manual_scale = false;
|
||||
uniform vec2 vert_offset = vec2(0.0, 0.0);
|
||||
|
||||
varying vec4 vertex_color;
|
||||
varying vec4 modulated_color;
|
||||
|
||||
void vertex() {
|
||||
vertex_color = COLOR;
|
||||
VERTEX.xy += vert_offset;
|
||||
modulated_color = vertex_color / target_color;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
float x_dir = flip_x ? -1.0 : 1.0;
|
||||
float y_dir = flip_y ? -1.0 : 1.0;
|
||||
vec2 uv = (UV / stretch - offset);
|
||||
float texture_aspect = texture_size.x / texture_size.y;
|
||||
float viewport_aspect = node_size.x / node_size.y;
|
||||
if (keep_aspect && !manual_scale) {
|
||||
if (fill_rect) {
|
||||
if (texture_aspect < viewport_aspect) {
|
||||
uv.y = (uv.y - 0.5) * (texture_aspect / viewport_aspect) + 0.5;
|
||||
} else {
|
||||
uv.x = (uv.x - 0.5) * (viewport_aspect / texture_aspect) + 0.5;
|
||||
}
|
||||
} else {
|
||||
if (texture_aspect > viewport_aspect) {
|
||||
uv.y = (uv.y - 0.5) * (texture_aspect / viewport_aspect) + 0.5;
|
||||
} else {
|
||||
uv.x = (uv.x - 0.5) * (viewport_aspect / texture_aspect) + 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
uv -= 0.5;
|
||||
uv *= vec2(x_dir, y_dir);
|
||||
if (manual_scale) {
|
||||
uv /= (vec2(texture_size) / vec2(node_size)) * texture_scale;
|
||||
} else {
|
||||
uv /= texture_scale;
|
||||
}
|
||||
uv += 0.5;
|
||||
if (tile_texture) {
|
||||
uv = fract(uv);
|
||||
}
|
||||
vec4 image = texture(image_texture, uv);
|
||||
vec4 gradient = texture(gradient_texture,UV);
|
||||
if (distance(vertex_color.rgb, target_color.rgb) < tolerance) {
|
||||
if (use_solid) { COLOR = new_bg_color; }
|
||||
if (gradient_behind && use_gradient) {
|
||||
if (use_solid) { COLOR.rgb = mix(COLOR.rgb, gradient.rgb, gradient.a); } else { COLOR = gradient; }
|
||||
}
|
||||
if (use_image) {
|
||||
if (use_solid || gradient_behind) { COLOR = mix(COLOR, tint_color * image, image.a); } else { COLOR = tint_color * image; }
|
||||
}
|
||||
if (!gradient_behind && use_gradient) {
|
||||
if(use_image || use_solid) { COLOR.rgb = mix(COLOR.rgb, gradient.rgb, gradient.a); } else { COLOR = gradient; }
|
||||
}
|
||||
COLOR *= modulated_color.a;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user