mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 01:02:45 +00:00 
			
		
		
		
	LibGUI: Add layout spacer support to GML
This is a bit of a hack, but it is an easy way to finally get spacers into GML. This will translate well if spacers are later to become child objects of the continer widget.
This commit is contained in:
		
							parent
							
								
									d1d5602132
								
							
						
					
					
						commit
						8081a8a5de
					
				
					 13 changed files with 106 additions and 99 deletions
				
			
		|  | @ -94,8 +94,7 @@ | ||||||
|             fixed_width: 150 |             fixed_width: 150 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // HACK: We need something like Layout::add_spacer() in GML! :^) |         @GUI::Layout::Spacer {} | ||||||
|         @GUI::Widget {} |  | ||||||
| 
 | 
 | ||||||
|         @GUI::Button { |         @GUI::Button { | ||||||
|             name: "close_button" |             name: "close_button" | ||||||
|  |  | ||||||
|  | @ -41,8 +41,7 @@ | ||||||
|         layout: @GUI::HorizontalBoxLayout {} |         layout: @GUI::HorizontalBoxLayout {} | ||||||
|         fixed_height: 22 |         fixed_height: 22 | ||||||
| 
 | 
 | ||||||
|         // HACK: using an empty widget as a spacer |         @GUI::Layout::Spacer {} | ||||||
|         @GUI::Widget {} |  | ||||||
| 
 | 
 | ||||||
|         @GUI::Button { |         @GUI::Button { | ||||||
|             name: "ok_button" |             name: "ok_button" | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
|             spacing: 10 |             spacing: 10 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|         @GUI::Button { |         @GUI::Button { | ||||||
|             name: "add_button" |             name: "add_button" | ||||||
|  | @ -30,6 +30,6 @@ | ||||||
|             fixed_width: 70 |             fixed_width: 70 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ | ||||||
|                 text: "Next Tip" |                 text: "Next Tip" | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             @GUI::Widget {} |             @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|             @GUI::HorizontalSeparator { |             @GUI::HorizontalSeparator { | ||||||
|                 fixed_height: 2 |                 fixed_height: 2 | ||||||
|  | @ -107,7 +107,7 @@ | ||||||
|             autosize: true |             autosize: true | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|         @GUI::Button { |         @GUI::Button { | ||||||
|             name: "close_button" |             name: "close_button" | ||||||
|  |  | ||||||
|  | @ -28,6 +28,5 @@ | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Spacer |     @GUI::Layout::Spacer {} | ||||||
|     @GUI::Widget {} |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -14,6 +14,5 @@ | ||||||
|         fixed_height: 28 |         fixed_height: 28 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Spacer |     @GUI::Layout::Spacer {} | ||||||
|     @GUI::Widget {} |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -92,7 +92,7 @@ | ||||||
|             @GUI::Widget { |             @GUI::Widget { | ||||||
|                 layout: @GUI::VerticalBoxLayout {} |                 layout: @GUI::VerticalBoxLayout {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Button { |                 @GUI::Button { | ||||||
|                     name: "normal_button" |                     name: "normal_button" | ||||||
|  | @ -105,7 +105,7 @@ | ||||||
|                     enabled: "false" |                     enabled: "false" | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             @GUI::VerticalSeparator {} |             @GUI::VerticalSeparator {} | ||||||
|  | @ -113,7 +113,7 @@ | ||||||
|             @GUI::Widget { |             @GUI::Widget { | ||||||
|                 layout: @GUI::VerticalBoxLayout {} |                 layout: @GUI::VerticalBoxLayout {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Button { |                 @GUI::Button { | ||||||
|                     name: "enabled_coolbar_button" |                     name: "enabled_coolbar_button" | ||||||
|  | @ -128,7 +128,7 @@ | ||||||
|                     button_style: "Coolbar" |                     button_style: "Coolbar" | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -144,7 +144,7 @@ | ||||||
|                     fixed_width: 60 |                     fixed_width: 60 | ||||||
|                     layout: @GUI::VerticalBoxLayout {} |                     layout: @GUI::VerticalBoxLayout {} | ||||||
| 
 | 
 | ||||||
|                     @GUI::Widget {} |                     @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                     @GUI::RadioButton { |                     @GUI::RadioButton { | ||||||
|                         name: "top_radiobutton" |                         name: "top_radiobutton" | ||||||
|  | @ -157,16 +157,16 @@ | ||||||
|                         text: "Radio 2" |                         text: "Radio 2" | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     @GUI::Widget {} |                     @GUI::Layout::Spacer {} | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget { |                 @GUI::Widget { | ||||||
|                     fixed_width: 70 |                     fixed_width: 70 | ||||||
|                     layout: @GUI::VerticalBoxLayout {} |                     layout: @GUI::VerticalBoxLayout {} | ||||||
| 
 | 
 | ||||||
|                     @GUI::Widget {} |                     @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                     @GUI::CheckBox { |                     @GUI::CheckBox { | ||||||
|                         name: "top_checkbox" |                         name: "top_checkbox" | ||||||
|  | @ -179,10 +179,10 @@ | ||||||
|                         enabled: false |                         enabled: false | ||||||
|                     } |                     } | ||||||
| 
 | 
 | ||||||
|                     @GUI::Widget {} |                     @GUI::Layout::Spacer {} | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             @GUI::VerticalSeparator {} |             @GUI::VerticalSeparator {} | ||||||
|  | @ -190,7 +190,7 @@ | ||||||
|             @GUI::Widget { |             @GUI::Widget { | ||||||
|                 layout: @GUI::VerticalBoxLayout {} |                 layout: @GUI::VerticalBoxLayout {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Button { |                 @GUI::Button { | ||||||
|                     name: "icon_button" |                     name: "icon_button" | ||||||
|  | @ -203,7 +203,7 @@ | ||||||
|                     enabled: "false" |                     enabled: "false" | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -278,7 +278,7 @@ | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Button { |                 @GUI::Button { | ||||||
|                     name: "font_button" |                     name: "font_button" | ||||||
|  | @ -295,7 +295,7 @@ | ||||||
|                     text: "Input dialog..." |                     text: "Input dialog..." | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -56,7 +56,7 @@ | ||||||
|             margins: [0, 8] |             margins: [0, 8] | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|         @GUI::Scrollbar { |         @GUI::Scrollbar { | ||||||
|             name: "enabled_scrollbar" |             name: "enabled_scrollbar" | ||||||
|  | @ -67,11 +67,11 @@ | ||||||
|             value: 50 |             value: 50 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|         @GUI::HorizontalSeparator {} |         @GUI::HorizontalSeparator {} | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|         @GUI::Scrollbar { |         @GUI::Scrollbar { | ||||||
|             name: "disabled_scrollbar" |             name: "disabled_scrollbar" | ||||||
|  | @ -79,7 +79,7 @@ | ||||||
|             fixed_width: -1 |             fixed_width: -1 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @GUI::GroupBox { |     @GUI::GroupBox { | ||||||
|  |  | ||||||
|  | @ -80,7 +80,7 @@ | ||||||
|                 fixed_height: 22 |                 fixed_height: 22 | ||||||
|                 layout: @GUI::HorizontalBoxLayout {} |                 layout: @GUI::HorizontalBoxLayout {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Widget {} |                 @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|                 @GUI::Button { |                 @GUI::Button { | ||||||
|                     name: "cancel_button" |                     name: "cancel_button" | ||||||
|  |  | ||||||
|  | @ -42,8 +42,7 @@ static ErrorOr<NonnullRefPtr<Object>> parse_gml_object(Queue<Token>& tokens) | ||||||
|     auto class_name = tokens.dequeue(); |     auto class_name = tokens.dequeue(); | ||||||
|     object->set_name(class_name.m_view); |     object->set_name(class_name.m_view); | ||||||
| 
 | 
 | ||||||
|     if (peek() != Token::Type::LeftCurly) |     if (peek() == Token::Type::LeftCurly) { | ||||||
|         return Error::from_string_literal("Expected {{"sv); |  | ||||||
| 
 | 
 | ||||||
|         tokens.dequeue(); |         tokens.dequeue(); | ||||||
| 
 | 
 | ||||||
|  | @ -58,14 +57,14 @@ static ErrorOr<NonnullRefPtr<Object>> parse_gml_object(Queue<Token>& tokens) | ||||||
|                 // It's a child object.
 |                 // It's a child object.
 | ||||||
| 
 | 
 | ||||||
|                 while (!pending_comments.is_empty()) |                 while (!pending_comments.is_empty()) | ||||||
|                 TRY(object->add_sub_object_child(pending_comments.take_first())); |                     TRY(object->add_sub_object_child(pending_comments.take_last())); | ||||||
| 
 | 
 | ||||||
|                 TRY(object->add_sub_object_child(TRY(parse_gml_object(tokens)))); |                 TRY(object->add_sub_object_child(TRY(parse_gml_object(tokens)))); | ||||||
|             } else if (peek() == Token::Type::Identifier) { |             } else if (peek() == Token::Type::Identifier) { | ||||||
|                 // It's a property.
 |                 // It's a property.
 | ||||||
| 
 | 
 | ||||||
|                 while (!pending_comments.is_empty()) |                 while (!pending_comments.is_empty()) | ||||||
|                 TRY(object->add_property_child(pending_comments.take_first())); |                     TRY(object->add_property_child(pending_comments.take_last())); | ||||||
| 
 | 
 | ||||||
|                 auto property_name = tokens.dequeue(); |                 auto property_name = tokens.dequeue(); | ||||||
| 
 | 
 | ||||||
|  | @ -100,6 +99,7 @@ static ErrorOr<NonnullRefPtr<Object>> parse_gml_object(Queue<Token>& tokens) | ||||||
|             return Error::from_string_literal("Expected }}"sv); |             return Error::from_string_literal("Expected }}"sv); | ||||||
| 
 | 
 | ||||||
|         tokens.dequeue(); |         tokens.dequeue(); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     return object; |     return object; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget {} |         @GUI::Layout::Spacer {} | ||||||
| 
 | 
 | ||||||
|         @GUI::Widget { |         @GUI::Widget { | ||||||
|             shrink_to_fit: true |             shrink_to_fit: true | ||||||
|  |  | ||||||
|  | @ -1131,6 +1131,14 @@ bool Widget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::O | ||||||
|     object->for_each_child_object_interruptible([&](auto child_data) { |     object->for_each_child_object_interruptible([&](auto child_data) { | ||||||
|         auto class_name = child_data->name(); |         auto class_name = child_data->name(); | ||||||
| 
 | 
 | ||||||
|  |         // It is very questionable if this pseudo object should exist, but it works fine like this for now.
 | ||||||
|  |         if (class_name == "GUI::Layout::Spacer") { | ||||||
|  |             if (!this->layout()) { | ||||||
|  |                 dbgln("Specified GUI::Layout::Spacer in GML, but the parent has no Layout."); | ||||||
|  |                 return IterationDecision::Break; | ||||||
|  |             } | ||||||
|  |             this->layout()->add_spacer(); | ||||||
|  |         } else { | ||||||
|             RefPtr<Core::Object> child; |             RefPtr<Core::Object> child; | ||||||
|             if (auto* registration = Core::ObjectClassRegistration::find(class_name)) { |             if (auto* registration = Core::ObjectClassRegistration::find(class_name)) { | ||||||
|                 child = registration->construct(); |                 child = registration->construct(); | ||||||
|  | @ -1143,8 +1151,8 @@ bool Widget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::O | ||||||
|             } |             } | ||||||
|             if (!child) |             if (!child) | ||||||
|                 return IterationDecision::Break; |                 return IterationDecision::Break; | ||||||
| 
 |  | ||||||
|             add_child(*child); |             add_child(*child); | ||||||
|  | 
 | ||||||
|             // This is possible as we ensure that Widget is a base class above.
 |             // This is possible as we ensure that Widget is a base class above.
 | ||||||
|             static_ptr_cast<Widget>(child)->load_from_gml_ast(child_data, unregistered_child_handler); |             static_ptr_cast<Widget>(child)->load_from_gml_ast(child_data, unregistered_child_handler); | ||||||
| 
 | 
 | ||||||
|  | @ -1153,6 +1161,7 @@ bool Widget::load_from_gml_ast(NonnullRefPtr<GUI::GML::Node> ast, RefPtr<Core::O | ||||||
|                 remove_child(*child); |                 remove_child(*child); | ||||||
|                 reinterpret_cast<TabWidget*>(this)->add_widget(*static_ptr_cast<Widget>(child)); |                 reinterpret_cast<TabWidget*>(this)->add_widget(*static_ptr_cast<Widget>(child)); | ||||||
|             } |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         return IterationDecision::Continue; |         return IterationDecision::Continue; | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  | @ -30,6 +30,8 @@ | ||||||
|                 text_alignment: "CenterLeft" |                 text_alignment: "CenterLeft" | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             @GUI::Layout::Spacer {} | ||||||
|  | 
 | ||||||
|             @GUI::Button { |             @GUI::Button { | ||||||
|                 name: "log_in" |                 name: "log_in" | ||||||
|                 text: "Log in" |                 text: "Log in" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 FrHun
						FrHun