Add files via upload

This commit is contained in:
Mighty Mochi Games
2025-04-21 21:19:28 -07:00
committed by GitHub
parent c2825f22d3
commit 011b668b2b
6 changed files with 1581 additions and 0 deletions

View 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)

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View 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")

View 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; }
}
}

View 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;
}
}