input styling, globalize timer functions

This commit is contained in:
Face
2025-08-23 15:47:18 +03:00
parent e19d4b7f61
commit c4cb74eed8
14 changed files with 219 additions and 172 deletions

View File

@@ -119,7 +119,7 @@ visible = false
layout_mode = 2
[node name="FileButton" type="Button" parent="FileContainer"]
custom_minimum_size = Vector2(100, 0)
custom_minimum_size = Vector2(100, 32)
layout_mode = 2
theme = ExtResource("2_theme")
text = "Choose File"

View File

@@ -362,11 +362,24 @@ func parse_rule(rule_data: Dictionary) -> CSSRule:
var properties_text = rule_data.properties
var utility_classes = properties_text.split(" ")
var base_utilities = []
var pseudo_utilities = []
for utility_name in utility_classes:
utility_name = utility_name.strip_edges()
if utility_name.is_empty():
continue
if utility_name.begins_with("hover:") or utility_name.begins_with("active:"):
pseudo_utilities.append(utility_name)
else:
base_utilities.append(utility_name)
for utility_name in base_utilities:
parse_utility_class_internal(rule, utility_name)
for utility_name in pseudo_utilities:
parse_utility_class(rule, utility_name)
return rule
@@ -382,11 +395,14 @@ func parse_utility_class(rule: CSSRule, utility_name: String) -> void:
pseudo_rule.selector = rule.selector
pseudo_rule.event_prefix = pseudo
pseudo_rule.selector_type = "simple"
pseudo_rule.selector_parts = [rule.selector]
pseudo_rule.selector_type = rule.selector_type
pseudo_rule.selector_parts = rule.selector_parts.duplicate()
pseudo_rule.calculate_specificity()
pseudo_rule.specificity += 100
for property in rule.properties:
pseudo_rule.properties[property] = rule.properties[property]
parse_utility_class_internal(pseudo_rule, actual_utility)
stylesheet.add_rule(pseudo_rule)
return

View File

@@ -24,11 +24,14 @@ 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 { text-[#000000] border border-[#000000] rounded-[3px] bg-transparent px-3 py-1.5 }
input:active { border-[3px] border-[#000000] }
select { text-[#000000] border border-[#000000] rounded-[3px] bg-transparent px-3 py-1.5 }
select:active { text-[#000000] border-[3px] border-[#000000] }
input[type="color"] { w-32 }
input[type="range"] { w-32 }
input[type="text"] { w-64 }
input[type="number"] { w-32 text-[16px] bg-transparent border border-[#000000] rounded-[3px] text-[#000000] hover:border-[3px] hover:border-[#000000] px-3 py-1.5 }
input[type="date"] { w-28 text-[16px] bg-[#1b1b1b] rounded-md text-white hover:bg-[#2a2a2a] active:bg-[#101010] px-3 py-1.5 }
"""
var HTML_CONTENT = """

View File

@@ -774,7 +774,7 @@ static func apply_flexcontainer_centering(node: Control, styles: Dictionary) ->
if not node is FlexContainer:
return
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_h = styles.has("mx-auto") or styles.has("justify-self-center")
var should_center_v = styles.has("my-auto") or styles.has("align-self-center")
if should_center_h and not node.has_meta("size_flags_horizontal_set"):
@@ -787,7 +787,7 @@ static func apply_flexcontainer_centering(node: Control, styles: Dictionary) ->
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_h = styles.has("mx-auto") or styles.has("justify-self-center")
var should_center_v = styles.has("my-auto") or styles.has("align-self-center")
# For FlexContainers, use the existing logic with metadata checks

View File

@@ -603,9 +603,40 @@ func apply_stylebox_to_input(control: Control, styles: Dictionary) -> void:
if not has_bottom_padding:
style_box.content_margin_bottom = 2.0
var hover_styles = _parser.get_element_styles_with_inheritance(_element, "hover", [])
var active_styles = _parser.get_element_styles_with_inheritance(_element, "active", [])
var hover_style_box = null
var active_style_box = null
if not hover_styles.is_empty():
hover_style_box = BackgroundUtils.create_stylebox_from_styles(hover_styles)
if not hover_styles.has("padding") and not hover_styles.has("padding-left"):
hover_style_box.content_margin_left = 5.0
if not hover_styles.has("padding") and not hover_styles.has("padding-right"):
hover_style_box.content_margin_right = 5.0
if not hover_styles.has("padding") and not hover_styles.has("padding-top"):
hover_style_box.content_margin_top = 2.0
if not hover_styles.has("padding") and not hover_styles.has("padding-bottom"):
hover_style_box.content_margin_bottom = 2.0
if not active_styles.is_empty():
active_style_box = BackgroundUtils.create_stylebox_from_styles(active_styles)
if not active_styles.has("padding") and not active_styles.has("padding-left"):
active_style_box.content_margin_left = 5.0
if not active_styles.has("padding") and not active_styles.has("padding-right"):
active_style_box.content_margin_right = 5.0
if not active_styles.has("padding") and not active_styles.has("padding-top"):
active_style_box.content_margin_top = 2.0
if not active_styles.has("padding") and not active_styles.has("padding-bottom"):
active_style_box.content_margin_bottom = 2.0
if control is LineEdit:
control.add_theme_stylebox_override("normal", style_box)
control.add_theme_stylebox_override("focus", style_box)
if hover_style_box:
control.add_theme_stylebox_override("hover", hover_style_box)
if active_style_box:
control.add_theme_stylebox_override("pressed", active_style_box)
elif control is SpinBox:
# NOTE: currently broken, it goes over the buttons, dont have time to fix
#style_box.expand_margin_right += 32.0 # More space for stepper buttons
@@ -614,6 +645,14 @@ func apply_stylebox_to_input(control: Control, styles: Dictionary) -> void:
if line_edit:
line_edit.add_theme_stylebox_override("normal", style_box)
line_edit.add_theme_stylebox_override("focus", style_box)
if hover_style_box:
line_edit.add_theme_stylebox_override("hover", hover_style_box)
if active_style_box:
line_edit.add_theme_stylebox_override("pressed", active_style_box)
elif control is Button:
control.add_theme_stylebox_override("normal", style_box)
if hover_style_box:
control.add_theme_stylebox_override("hover", hover_style_box)
if active_style_box:
control.add_theme_stylebox_override("pressed", active_style_box)

View File

@@ -293,17 +293,18 @@ func _setup_threaded_gurt_api():
lua_vm.lua_pushcallable(_gurt_create_handler, "gurt.create")
lua_vm.lua_setfield(-2, "create")
lua_vm.lua_pushcallable(_set_timeout_handler, "gurt.setTimeout")
lua_vm.lua_setfield(-2, "setTimeout")
# Add timer functions as global functions
lua_vm.lua_pushcallable(_set_timeout_handler, "setTimeout")
lua_vm.lua_setglobal("setTimeout")
lua_vm.lua_pushcallable(lua_api._gurt_clear_timeout_handler, "gurt.clearTimeout")
lua_vm.lua_setfield(-2, "clearTimeout")
lua_vm.lua_pushcallable(lua_api._gurt_clear_timeout_handler, "clearTimeout")
lua_vm.lua_setglobal("clearTimeout")
lua_vm.lua_pushcallable(_set_interval_handler, "gurt.setInterval")
lua_vm.lua_setfield(-2, "setInterval")
lua_vm.lua_pushcallable(_set_interval_handler, "setInterval")
lua_vm.lua_setglobal("setInterval")
lua_vm.lua_pushcallable(lua_api._gurt_clear_interval_handler, "gurt.clearInterval")
lua_vm.lua_setfield(-2, "clearInterval")
lua_vm.lua_pushcallable(lua_api._gurt_clear_interval_handler, "clearInterval")
lua_vm.lua_setglobal("clearInterval")
lua_vm.lua_newtable()
lua_vm.lua_pushcallable(lua_api._gurt_location_reload_handler, "gurt.location.reload")

View File

@@ -1,32 +1,14 @@
[gd_scene load_steps=6 format=3 uid="uid://b6c1twaog7hui"]
[gd_scene load_steps=4 format=3 uid="uid://b6c1twaog7hui"]
[ext_resource type="Texture2D" uid="uid://mol3s1ujp0k2" path="res://Assets/Icons/calendar_16x16.svg" id="1_ef33s"]
[ext_resource type="Script" uid="uid://do548vwv7m0rq" path="res://addons/DatePicker/DateButton.gd" id="1_sskq5"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ef33s"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_ufs0o"]
content_margin_left = 4.0
bg_color = Color(0.105882, 0.105882, 0.105882, 1)
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pnupr"]
content_margin_left = 4.0
bg_color = Color(0.105882, 0.105882, 0.105882, 1)
corner_radius_top_left = 4
corner_radius_top_right = 4
corner_radius_bottom_right = 4
corner_radius_bottom_left = 4
[node name="DateButton" type="Button"]
offset_right = 115.0
offset_bottom = 34.0
theme_override_styles/focus = SubResource("StyleBoxEmpty_ef33s")
theme_override_styles/hover = SubResource("StyleBoxFlat_ufs0o")
theme_override_styles/normal = SubResource("StyleBoxFlat_pnupr")
action_mode = 0
text = "3/13/2025"
icon = ExtResource("1_ef33s")

View File

@@ -28,7 +28,7 @@ func init():
func scroll_to_current_year():
var year_container: VBoxContainer = %YearContainer
var scroll_container: ScrollContainer = $SmoothScrollContainer
var scroll_container: ScrollContainer = $ScrollContainer
var current_year = calendar.date_time.year
var target_button: Button = year_container.get_node_or_null("Year" + str(current_year))

View File

@@ -123,7 +123,7 @@
if not disabled then
targetButton:setAttribute('style', 'target-button ' .. randomColor .. ' text-white px-6 py-3 rounded-lg font-semibold hover:opacity-75')
gurt.setTimeout(function()
setTimeout(function()
targetButton:setAttribute('style', 'target-button bg-[#3b82f6] text-white px-6 py-3 rounded-lg font-semibold hover:bg-[#2563eb]')
end, 1000)
end
@@ -137,7 +137,7 @@
targetButton:setAttribute('data-value', 'initial')
-- Update status after setting initial attributes
gurt.setTimeout(function()
setTimeout(function()
updateStatus()
end, 100)
</script>

View File

@@ -33,7 +33,7 @@
controlledAudio.volume = 0.3
end)
local test = gurt.setTimeout(function()
local test = setTimeout(function()
print('removed')
programmaticAudio:play()
end, 3000)

View File

@@ -155,7 +155,7 @@
end)
-- Test: Auto-refresh every 2 seconds to show expiry
gurt.setInterval(function()
setInterval(function()
refresh_crumbs_display()
end, 2000)

View File

@@ -1,18 +1,23 @@
<head>
<title>My cool web</title>
<icon src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Google_%22G%22_logo.svg/768px-Google_%22G%22_logo.svg.png\">
<icon
src="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c1/Google_%22G%22_logo.svg/768px-Google_%22G%22_logo.svg.png">
<meta name=\"theme-color\" content=\"#000000\">
<meta name=\"description\" content=\"My cool web\">
<meta name="theme-color" content="#000000">
<meta name="description" content="My cool web">
<font name="roboto" src="https://fonts.gstatic.com/s/roboto/v48/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2" />
<font name="roboto"
src="https://fonts.gstatic.com/s/roboto/v48/KFO7CnqEu92Fr1ME7kSn66aGLdTylUAMa3KUBGEe.woff2" />
<style>
h1 { text-[#ff0000] font-italic hover:text-[#00ff00] }
button { hover:bg-[#FF6B35] hover:text-[#FFFFFF] active:bg-[#CC5429] active:text-[#F0F0F0] }
</style>
<style src=\"styles.css\">
<script src=\"script.lua\" />
<style>
h1 {
text-[#ff0000] font-italic hover:text-[#00ff00]
}
button {
hover:bg-[#FF6B35] hover:text-[#FFFFFF] active:bg-[#CC5429] active:text-[#F0F0F0]
}
</style>
</head>
<body>
@@ -22,24 +27,24 @@
<h4>Header 4</h4>
<h5>Header 5</h5>
<h6>Header 6</h6>
<separator />
<p>Normal font</p>
<p style="font-mono">Mono font</p>
<p style="font-sans">Sans font</p>
<p style="font-roboto">Custom font - Roboto</p>
<p>Hey there! this is a test</p>
<p>Hey there! this is a test</p>
<b>This is bold</b>
<i>This is italic <mark>actually, and it's pretty <u>cool</u></mark></i>
<u>This is underline</u>
<small>this is small</small>
<mark>this is marked</mark>
<code>this is code<span> THIS IS A SPAN AND SHOULDNT BE ANY DIFFERENT</span></code>
<p>
<a href="https://youtube.com">Hello gang</a>
<a href="https://youtube.com">Hello gang</a>
</p>
<pre>
@@ -49,9 +54,9 @@ font, and it preserves
both spaces and
line breaks
</pre>
<p style="text-center w-32 h-32">
So
So
</p>
<div>
@@ -66,7 +71,7 @@ line breaks
<!-- Test CSS Properties -->
<h2 style="text-center mt-6">🧪 CSS Properties Test</h2>
<div style="flex flex-col gap-2 justify-center items-center mt-2">
<div style="flex flex-col gap-2 justify-center items-center mt-2 mx-auto">
<div style="bg-[#ef4444] text-white p-4 rounded-lg opacity-75 z-10 cursor-pointer">
<p>Opacity 75% with cursor pointer and z-index 10 - Text should show pointer cursor, not I-beam</p>
</div>
@@ -89,9 +94,9 @@ line breaks
<p>Cursor not-allowed - Text should show forbidden cursor</p>
</div>
</div>
<separator direction="horizontal" />
<!-- Test cursor inheritance -->
<h2 style="text-center mt-6">🖱️ Cursor Inheritance Test</h2>
<div style="cursor-pointer bg-[#1e293b] p-4 rounded-lg">
@@ -129,125 +134,126 @@ line breaks
<div style="border border-blue-400 p-2 mb-2">border-blue-400</div>
<div style="border border-yellow-300 p-2 mb-2">border-yellow-300</div>
<select style=\"text-center max-w-5 max-h-32\">
<option value=\"test1\">Test 1</option>
<option value=\"test2\" selected=\"true\">Test 2</option>
<option value=\"test3\">Test 3</option>
<option value=\"test4\" disabled=\"true\">Test 4</option>
<option value=\"test5\">Test 5</option>
</select>
<select style="text-center max-w-5 max-h-32">
<option value="test1">Test 1</option>
<option value="test2" selected="true">Test 2</option>
<option value="test3">Test 3</option>
<option value="test4" disabled="true">Test 4</option>
<option value="test5">Test 5</option>
</select>
<textarea />
<textarea cols=\"30\" />
<textarea rows=\"2\" />
<textarea maxlength=\"20\" />
<textarea readonly=\"true\">le skibidi le toilet</textarea>
<textarea disabled=\"true\" value=\"DISABLED\" />
<textarea placeholder=\"this is a placeholder...\" />
<textarea />
<textarea cols="30" />
<textarea rows="2" />
<textarea maxlength="20" />
<textarea readonly="true">le skibidi le toilet</textarea>
<textarea disabled="true" value="DISABLED" />
<textarea placeholder="this is a placeholder..." />
<!-- action, method, and type=submit are for when we implement Lua -->
<form action=\"/submit\" method=\"POST\">
<span>Name:</span>
<input type=\"text\" placeholder=\"First name\" value=\"John\" maxlength=\"20\" minlength=\"3\" />
<span>Email regex:</span>
<input type=\"text\" placeholder=\"Last name\" value=\"Doe\" pattern=\"^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$\" />
<span>Smart:</span>
<input type=\"checkbox\" />
<input type=\"checkbox\" value=\"true\" />
<!-- action, method, and type=submit are for when we implement Lua -->
<form action="/submit" method="POST">
<span>Name:</span>
<input type="text" placeholder="First name" value="John" maxlength="20" minlength="3" />
<span>Email regex:</span>
<input type="text" placeholder="Last name" value="Doe" pattern="^[^@\s]+@[^@\s]+\.[^@\s]+$" />
<span>Smart:</span>
<input type="checkbox" />
<input type="checkbox" value="true" />
<p>favorite food</p>
<input type=\"radio\" group=\"food\" />
<span>Pizza</span>
<input type=\"radio\" group=\"food\" />
<span>Berry</span>
<input type=\"radio\" group=\"food\" />
<span>Gary</span>
<p>favorite food</p>
<input type="radio" group="food" />
<span>Pizza</span>
<input type="radio" group="food" />
<span>Berry</span>
<input type="radio" group="food" />
<span>Gary</span>
<h2>Color</h2>
<input type=\"color\" value=\"#ff0000\" />
<h2>Date</h2>
<input type=\"date\" value=\"2018-07-22\" />
<h2>Color</h2>
<input type="color" value="#ff0000" />
<h2>Date</h2>
<input type="date" value="2018-07-22" />
<h2>Range Slider</h2>
<input style=\"max-w-2 max-h-2\" type=\"range\" min=\"0\" max=\"100\" step=\"5\" value=\"50\" />
<h2>Number Input</h2>
<input type=\"number\" min=\"1\" max=\"10\" step=\"0.5\" value=\"5\" placeholder=\"Enter number\" />
<h2>File Upload</h2>
<input type=\"file\" accept=\".txt,.pdf,image/*\" />
</form>
<separator direction=\"horizontal\" />
# Ordered list
<ol>
<li>hello gang</li>
<li>this</li>
<li>is</li>
</ol>
<h2>Range Slider</h2>
<input style="max-w-2 max-h-2" type="range" min="0" max="100" step="5" value="50" />
<ol type=\"zero-lead\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<h2>Number Input</h2>
<input type="number" min="1" max="10" step="0.5" value="5" placeholder="Enter number" />
<ol type=\"lower-alpha\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<h2>File Upload</h2>
<input type="file" accept=".txt,.pdf,image/*" />
</form>
<separator direction="horizontal" />
<ol type=\"upper-alpha\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol>
<li>hello gang</li>
<li>this</li>
<li>is</li>
</ol>
<ol type="zero-lead">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol type="lower-alpha">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol type="upper-alpha">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol type=\"lower-roman\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol type="lower-roman">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol type=\"upper-roman\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ol type="upper-roman">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ol>
<ul>
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<ul>
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<ul type=\"circle\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<ul type=\"none\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<ul type=\"square\">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<img style=\"text-center max-w-24 max-h-24\" src=\"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQMNUPIKabszX0Js_c0kfa4cz_JQYKfGTuBUA&s\" />
<separator direction=\"vertical\" />
<ul type="circle">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<ul type="none">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<ul type="square">
<li>hello gang</li>
<li>this</li>
<li>is</li>
<li>a test</li>
</ul>
<img style="text-center max-w-24 max-h-24"
src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQMNUPIKabszX0Js_c0kfa4cz_JQYKfGTuBUA&s" />
<separator direction="vertical" />
<!-- FLEXBOX EXAMPLES -->
<h2>Flex Row (gap, justify-between, items-center)</h2>

View File

@@ -56,7 +56,7 @@
counter = 0
updateCounter()
intervalId = gurt.setInterval(function()
intervalId = setInterval(function()
counter = counter + 1
updateCounter()
addLog('⏱️ Counter updated to: ' .. counter)
@@ -72,7 +72,7 @@
return
end
gurt.clearInterval(intervalId)
clearInterval(intervalId)
addLog('🛑 Interval stopped (ID: ' .. intervalId .. ')')
intervalId = nil
end)
@@ -127,7 +127,7 @@
<div style="container mt-6">
<div style="info-box mb-6">
<h3 style="text-[#6d28d9] font-semibold mb-2">Testing Features:</h3>
<p><strong>Intervals:</strong> <code>gurt.setInterval(callback, delay)</code> and <code>gurt.clearInterval(id)</code></p>
<p><strong>Intervals:</strong> <code>setInterval(callback, delay)</code> and <code>clearInterval(id)</code></p>
<p><strong>Network Images:</strong> <code>fetch()</code> with binary data and dynamic <code>&lt;img&gt;</code> creation</p>
</div>

View File

@@ -98,12 +98,12 @@
})
gurt.body:append(temp_element)
local test = gurt.setTimeout(function()
local test = setTimeout(function()
print('removed')
temp_element:remove()
end, 3000)
-- gurt.clearTimeout(test)
-- clearTimeout(test)
local addBtn = gurt.select('#add-class')
local removeBtn = gurt.select('#remove-class')