improve input styling, utility class handling, font weigh for width calc,

This commit is contained in:
Face
2025-08-19 09:11:04 +03:00
parent a8313ec3d8
commit 1761b05899
9 changed files with 259 additions and 28 deletions

View File

@@ -22,27 +22,27 @@
}
.container {
bg-[#262626] p-6 rounded-lg shadow-lg max-w-6xl mx-auto
bg-[#262626] p-6 rounded-lg shadow-lg max-w-6xl
}
.primary-btn {
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white
p-3 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white
}
.success-btn {
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#ef4444] text-white
p-3 rounded-lg font-medium cursor-pointer transition-colors bg-[#ef4444] text-white
}
.danger-btn {
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#b91c1c] text-white
p-3 rounded-lg font-medium cursor-pointer transition-colors bg-[#b91c1c] text-white
}
.secondary-btn {
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#525252] text-white w-32 h-12
p-3 rounded-lg font-medium cursor-pointer transition-colors bg-[#525252] text-white w-32 h-12
}
.warning-btn {
px-4 py-2 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white
p-3 rounded-lg font-medium cursor-pointer transition-colors bg-[#dc2626] text-white
}
.form-group {
@@ -50,11 +50,11 @@
}
.form-input {
w-full p-3 border border-gray-600 rounded-md bg-[#374151] text-white
w-full p-3 border border-gray-600 rounded-md bg-[#374151] text-white active:border-red-500
}
.card {
bg-[#262626] p-4 rounded-lg shadow border border-gray-700
bg-[#262626] p-6 rounded-lg shadow border border-gray-700
}
.stats-card {
@@ -103,7 +103,7 @@
</div>
<div style="card mb-6">
<h2>Register New Domain</h2>
<h2 style="mb-4">Register New Domain</h2>
<div style="form-group">
<p>Domain Name:</p>
<input id="domain-name" type="text" style="form-input" placeholder="myawesome" />

View File

@@ -7,8 +7,8 @@
<font name="roboto" src="https://fonts.gstatic.com/s/roboto/v48/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2" />
<style>
body { bg-[#1b1b1b] text-[#ffffff] font-roboto flex items-center justify-center p-4 }
.login-card { bg-[#2a2a2a] rounded-lg p-8 shadow-2xl mx-0 }
body { bg-[#2a2a2a] text-[#ffffff] font-roboto flex items-center justify-center p-4 }
.login-card { p-8 }
h1 { text-3xl font-bold text-center mb-6 text-[#ffffff] }
input {
bg-[#3b3b3b]
@@ -38,13 +38,12 @@
#log-output { text-white p-4 rounded-md mt-4 font-mono max-h-40 }
</style>
<script src="script.lua" />
</head>
<body>
<div style="login-card">
<h1>Login</h1>
<form id="login-form">
<form id="login-form" style="mx-auto">
<input id="username" type="text" placeholder="Username" required="true" />
<input id="password" type="password" placeholder="Password" required="true" />
<button type="submit" id="submit">Log In</button>

View File

@@ -115,7 +115,7 @@ theme_override_styles/hover = ExtResource("3_kjcxk")
theme_override_styles/pressed = ExtResource("3_kjcxk")
theme_override_styles/normal = ExtResource("4_ib6pj")
action_mode = 0
text = "(2) YouTube - STOP PLAYING WITH ME BITCHES FR"
text = "New Tab"
icon = ExtResource("5_ib6pj")
alignment = 0
text_overrun_behavior = 3

View File

@@ -261,7 +261,8 @@ class CSSStylesheet:
else:
# Exact match
parsed = parse_attribute_value(attribute_part, "=")
return element.get_attribute(parsed.name) == parsed.value
element_value = element.get_attribute(parsed.name)
return element_value == parsed.value
else:
# Just check if attribute exists
return element.has_attribute(attribute_part)
@@ -384,12 +385,15 @@ func parse_utility_class(rule: CSSRule, utility_name: String) -> void:
pseudo_rule.selector_type = "simple"
pseudo_rule.selector_parts = [rule.selector]
pseudo_rule.calculate_specificity()
pseudo_rule.specificity += 100
parse_utility_class_internal(pseudo_rule, actual_utility)
stylesheet.add_rule(pseudo_rule)
return
# Fallback to normal parsing
rule.calculate_specificity()
rule.specificity += 50
parse_utility_class_internal(rule, utility_name)
# Parses a utility class (e.g. "text-red-500") and adds properties to the rule (e.g. "color: red")
@@ -671,12 +675,18 @@ static func parse_utility_class_internal(rule: CSSRule, utility_name: String) ->
if utility_name.begins_with("p-[") and utility_name.ends_with("]"):
var val = SizeUtils.extract_bracket_content(utility_name, 2) # after 'p-'
var padding_value = SizeUtils.parse_size(val)
rule.properties["padding"] = padding_value
rule.properties["padding-left"] = padding_value
rule.properties["padding-right"] = padding_value
rule.properties["padding-top"] = padding_value
rule.properties["padding-bottom"] = padding_value
return
if utility_name.begins_with("p-"):
var val = utility_name.substr(2)
var padding_value = SizeUtils.parse_size(val)
rule.properties["padding"] = padding_value
rule.properties["padding-left"] = padding_value
rule.properties["padding-right"] = padding_value
rule.properties["padding-top"] = padding_value
rule.properties["padding-bottom"] = padding_value
return
if utility_name.begins_with("px-"):
var val = utility_name.substr(3)

View File

@@ -23,6 +23,9 @@ pre { text-xl font-mono }
button { text-[16px] bg-[#1b1b1b] rounded-md text-white hover:bg-[#2a2a2a] active:bg-[#101010] px-3 py-1.5 }
button[disabled] { bg-[#666666] text-[#999999] cursor-not-allowed }
input[type="text"] { text-[#000000] border border-[#000000] rounded-[3px] bg-transparent px-3 py-1.5 }
input[type="text"]:active { border-[3px] border-[#000000] }
"""
var HTML_CONTENT = """

View File

@@ -7,13 +7,25 @@ static func parse_size(val):
if val == null: return null
if typeof(val) == TYPE_INT or typeof(val) == TYPE_FLOAT:
return float(val)
# Handle bracketed values like [5px], [2rem], [50%]
if val.begins_with("[") and val.ends_with("]"):
var clean_val = val.replace("[", "").replace("]", "")
if clean_val.ends_with("px"):
return float(clean_val.replace("px", ""))
elif clean_val.ends_with("rem"):
return float(clean_val.replace("rem", "")) * 16.0
elif clean_val.ends_with("%"):
return clean_val
else:
return float(clean_val)
if val.ends_with("px"):
return float(val.replace("px", ""))
if val.ends_with("rem"):
return float(val.replace("rem", "")) * 16.0
if val.ends_with("%") or (val.ends_with("]") and "%" in val):
var clean_val = val.replace("[", "").replace("]", "")
return clean_val
if val.ends_with("%"):
return val
return float(val)
static func apply_element_styles(node: Control, element: HTMLParser.HTMLElement, parser: HTMLParser) -> Control:
@@ -98,8 +110,7 @@ static func apply_element_styles(node: Control, element: HTMLParser.HTMLElement,
# regular controls
SizingUtils.apply_regular_control_sizing(node, width, height, styles)
# Apply centering for FlexContainers
apply_flexcontainer_centering(node, styles)
apply_element_centering(node, styles)
if label and label != node:
label.anchors_preset = Control.PRESET_FULL_RECT
@@ -805,3 +816,34 @@ static func apply_flexcontainer_centering(node: Control, styles: Dictionary) ->
if should_center_h or should_center_v:
node.set_meta("size_flags_set_by_style_manager", true)
static func apply_element_centering(node: Control, styles: Dictionary) -> void:
var should_center_h = styles.has("mx-auto") or styles.has("justify-self-center") or (styles.has("text-align") and styles["text-align"] == "center")
var should_center_v = styles.has("my-auto") or styles.has("align-self-center")
# For FlexContainers, use the existing logic with metadata checks
if node is FlexContainer:
if should_center_h and not node.has_meta("size_flags_horizontal_set"):
node.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
if should_center_v and not node.has_meta("size_flags_vertical_set"):
node.size_flags_vertical = Control.SIZE_SHRINK_CENTER
if should_center_h or should_center_v:
node.set_meta("size_flags_set_by_style_manager", true)
else:
# For other controls, apply centering more directly
if should_center_h:
# Only apply if no explicit width was set, or if explicit sizing allows centering
var has_explicit_width = styles.has("width")
if not has_explicit_width or not node.has_meta("size_flags_horizontal_set"):
node.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
if should_center_v:
# Only apply if no explicit height was set, or if explicit sizing allows centering
var has_explicit_height = styles.has("height")
if not has_explicit_height or not node.has_meta("size_flags_vertical_set"):
node.size_flags_vertical = Control.SIZE_SHRINK_CENTER
if should_center_h or should_center_v:
node.set_meta("size_flags_set_by_style_manager", true)

View File

@@ -7,8 +7,12 @@ var custom_hex_input: LineEdit
var _file_text_content: String = ""
var _file_binary_content: PackedByteArray = PackedByteArray()
var _file_info: Dictionary = {}
var _element: HTMLParser.HTMLElement
var _parser: HTMLParser
func init(element: HTMLParser.HTMLElement, parser: HTMLParser) -> void:
_element = element
_parser = parser
var color_picker_button: ColorPickerButton = $ColorPickerButton
var picker: ColorPicker = color_picker_button.get_picker()
@@ -150,6 +154,15 @@ func init(element: HTMLParser.HTMLElement, parser: HTMLParser) -> void:
parser.register_dom_node(element, active_child)
else:
parser.register_dom_node(element, active_child)
if active_child is LineEdit:
active_child.focus_entered.connect(_on_input_focus_entered)
active_child.focus_exited.connect(_on_input_focus_exited)
elif active_child is SpinBox:
var line_edit = active_child.get_line_edit()
if line_edit:
line_edit.focus_entered.connect(_on_input_focus_entered)
line_edit.focus_exited.connect(_on_input_focus_exited)
func remove_unused_children(keep_child_name: String) -> void:
for child in get_children():
@@ -380,6 +393,38 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) ->
var styles = parser.get_element_styles_with_inheritance(element, "", [])
# Apply text color to the active input control
var active_child = null
for child in get_children():
if child.visible:
active_child = child
break
if active_child:
# Apply text color
if styles.has("color"):
var text_color = styles["color"] as Color
if active_child is LineEdit:
active_child.add_theme_color_override("font_color", text_color)
active_child.add_theme_color_override("caret_color", text_color)
# Also set placeholder color with reduced opacity
var placeholder_color = Color(text_color.r, text_color.g, text_color.b, text_color.a * 0.6)
active_child.add_theme_color_override("font_placeholder_color", placeholder_color)
elif active_child is SpinBox:
active_child.add_theme_color_override("font_color", text_color)
# Also apply to the LineEdit inside SpinBox
var line_edit = active_child.get_line_edit()
if line_edit:
line_edit.add_theme_color_override("font_color", text_color)
line_edit.add_theme_color_override("caret_color", text_color)
var placeholder_color = Color(text_color.r, text_color.g, text_color.b, text_color.a * 0.6)
line_edit.add_theme_color_override("font_placeholder_color", placeholder_color)
# Apply stylebox for borders, background, padding, etc.
if BackgroundUtils.needs_background_wrapper(styles):
apply_stylebox_to_input(active_child, styles)
var width = null
var height = null
@@ -395,12 +440,6 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) ->
if styles.has("height"):
height = SizingUtils.parse_size_value(styles["height"])
var active_child = null
for child in get_children():
if child.visible:
active_child = child
break
if active_child:
if width or height:
# Explicit sizing from CSS
@@ -455,3 +494,99 @@ func apply_input_styles(element: HTMLParser.HTMLElement, parser: HTMLParser) ->
if active_child.name == "DateButton":
active_child.anchors_preset = Control.PRESET_TOP_LEFT
active_child.position = Vector2.ZERO
func _on_input_focus_entered() -> void:
apply_active_styles()
func _on_input_focus_exited() -> void:
apply_normal_styles()
func apply_active_styles() -> void:
if not _element or not _parser:
return
# Get both normal and active styles, then merge them
var normal_styles = _parser.get_element_styles_with_inheritance(_element, "", [])
var active_styles = _parser.get_element_styles_with_inheritance(_element, "active", [])
# Merge normal styles with active styles (active styles override normal)
var merged_styles = normal_styles.duplicate()
for key in active_styles:
merged_styles[key] = active_styles[key]
# Find the active input control
var active_child = null
for child in get_children():
if child.visible:
active_child = child
break
if not active_child:
return
# Apply merged styles
if BackgroundUtils.needs_background_wrapper(merged_styles):
apply_stylebox_to_input(active_child, merged_styles)
func apply_normal_styles() -> void:
if not _element or not _parser:
return
var normal_styles = _parser.get_element_styles_with_inheritance(_element, "", [])
# Find the active input control
var active_child = null
for child in get_children():
if child.visible:
active_child = child
break
if not active_child:
return
# Apply normal border styles
if BackgroundUtils.needs_background_wrapper(normal_styles):
apply_stylebox_to_input(active_child, normal_styles)
else:
# Remove style overrides to use default theme
if active_child is LineEdit:
active_child.remove_theme_stylebox_override("normal")
active_child.remove_theme_stylebox_override("focus")
elif active_child is SpinBox:
active_child.remove_theme_stylebox_override("normal")
active_child.remove_theme_stylebox_override("focus")
elif active_child is Button:
active_child.remove_theme_stylebox_override("normal")
func apply_stylebox_to_input(control: Control, styles: Dictionary) -> void:
var style_box = BackgroundUtils.create_stylebox_from_styles(styles)
# Set appropriate content margins for inputs if no padding is specified
# Check for all possible padding-related styles
var has_left_padding = styles.has("padding") or styles.has("padding-left")
var has_right_padding = styles.has("padding") or styles.has("padding-right")
var has_top_padding = styles.has("padding") or styles.has("padding-top")
var has_bottom_padding = styles.has("padding") or styles.has("padding-bottom")
if not has_left_padding:
style_box.content_margin_left = 5.0
if not has_right_padding:
style_box.content_margin_right = 5.0
if not has_top_padding:
style_box.content_margin_top = 2.0
if not has_bottom_padding:
style_box.content_margin_bottom = 2.0
# Apply the style to the appropriate states
if control is LineEdit:
control.add_theme_stylebox_override("normal", style_box)
control.add_theme_stylebox_override("focus", style_box)
elif control is SpinBox:
control.add_theme_stylebox_override("normal", style_box)
control.add_theme_stylebox_override("focus", style_box)
elif control is Button:
control.add_theme_stylebox_override("normal", style_box)

View File

@@ -1,7 +1,11 @@
class_name HTMLP
extends RichTextLabel
var element_styles: Dictionary = {}
func init(element: HTMLParser.HTMLElement, parser: HTMLParser) -> void:
element_styles = parser.get_element_styles_with_inheritance(element, "", [])
text = "[font_size=24]%s[/font_size]" % element.get_bbcode_formatted_text(parser)
# Allow mouse events to pass through to parent containers for hover effects while keeping text selection
@@ -30,6 +34,10 @@ func _auto_resize_to_content():
await get_tree().process_frame
var natural_width = size.x
var font_weight_multiplier = _get_font_weight_multiplier()
natural_width *= font_weight_multiplier
var desired_width = clampf(natural_width, min_width, max_width)
autowrap_mode = original_autowrap
@@ -42,3 +50,26 @@ func _auto_resize_to_content():
custom_minimum_size = Vector2(desired_width, final_height)
queue_redraw()
func _get_font_weight_multiplier() -> float:
if element_styles.has("font-black"):
return 1.12
elif element_styles.has("font-extrabold"):
return 1.10
elif element_styles.has("font-bold"):
return 1.08
elif element_styles.has("font-semibold"):
return 1.06
elif element_styles.has("font-medium"):
return 1.03
elif element_styles.has("font-light"):
return 0.98
elif element_styles.has("font-extralight") or element_styles.has("font-thin"):
return 0.95
var text_content = get_parsed_text()
if text_content.contains("[b]"):
return 1.08
return 1.0

View File

@@ -76,10 +76,21 @@ static func create_stylebox_from_styles(styles: Dictionary = {}, container: Cont
style_box.set(property_name, parsed_width)
var border_color = Color.BLACK
var has_border_color = false
if styles.has("border-color"):
border_color = styles["border-color"]
has_border_color = true
elif container and container.has_meta("custom_css_border_color"):
border_color = container.get_meta("custom_css_border_color")
has_border_color = true
# If we have a border color but no width set, default to 1px
if has_border_color and not has_border:
has_border = true
style_box.border_width_top = 1
style_box.border_width_right = 1
style_box.border_width_bottom = 1
style_box.border_width_left = 1
if has_border:
style_box.border_color = border_color