├── LICENSE ├── README.md ├── addons └── GodotSTM │ ├── .gd │ ├── GodotSTM_icon.png │ ├── GodotSTM_plugin.gd │ ├── plugin.cfg │ └── simple_text_menu.gd ├── cave_font.fnt ├── cave_font.ttf ├── demo.gd ├── demo.tscn ├── engine.cfg ├── icon.png ├── icon.png.flags └── menu_example.png /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Henrique Lacreta Alves 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GodotSTM 2 | A Simple customizable Text Menu plugin for Godot. 3 | 4 | It adds a "SimpleTextMenu" node to Godot, in which you can easily create a retro-like text menu with as many options you want. 5 | 6 | Its main features: 7 | * Can add as much options you need. 8 | * Editor-friendly, you can check the menu changes in real-time. 9 | * Signal-friendly, it's easy to check which option is being selected. 10 | * Options to change the cursor side and menu orientation. 11 | 12 | ![](menu_example.png) 13 | *Menu example, used with [SimpleGodotCRTShader](https://github.com/henriquelalves/SimpleGodotCRTShader)* 14 | 15 | ## How to use 16 | Simply download this repository, and copy the GodotSTM folder to your Godot project; then enable the plugin on the 'Plugins' tab (on 'Project Settings'). 17 | 18 | To add options to your menu, edit the "options" variable of the node; each line will be a new option (this is the easiest way I found to add more options). 19 | 20 | This repository has a demo Scene you can check to see how the plugin works. 21 | 22 | ## License 23 | The "Cave-Story" font used in the demo was created by enigmansmp1824; it's CC-BY-SA licensed, and can be found in https://fontlibrary.org/pt/font/cave-story. 24 | 25 | The plugin uses the MIT License. 26 | -------------------------------------------------------------------------------- /addons/GodotSTM/.gd: -------------------------------------------------------------------------------- 1 | # MADE BY HENRIQUE ALVES 2 | # (MIT) LICENSE STUFF BLABLABLA 3 | 4 | tool 5 | extends Control 6 | 7 | # ========= Variables ========== 8 | export(String, MULTILINE) var options = "" setget set_options # The options on the menu, separated by line 9 | export(int, "Horizontal", "Vertical") var orientation = 0 setget set_orientation # Horizontal or Vertical menu 10 | export(int) var offset = 0 setget set_offset # Offset between options 11 | export(Font) var options_font = null setget set_font # Menu font 12 | export(int, "Number", "String") var signal_argument = 0 # Whether you receive the number of the option choosen or the string 13 | export(int) var initial_option = 0 setget set_cursor_option # Cursor starting position 14 | export(int, "Left", "Top", "Right", "Bottom") var cursor_side = 0 setget set_cursor_side # Which side the cursor will appear on the options 15 | export(int) var cursor_offset = 0 setget set_cursor_offset 16 | 17 | export(float) var blinking_cursor_rate = 0.0 setget set_blinking_cursor_rate# How many seconds for the cursor to blink (0 means he doesn't blink) 18 | export(Color) var options_color = Color(1.0,1.0,1.0,1.0) setget set_options_color 19 | export(Color) var cursor_color = Color(1.0,1.0,1.0,1.0) setget set_cursor_color 20 | export(bool) var menu_enabled = true setget set_enabled_menu 21 | 22 | var _current_option = 0 23 | var _cursor_timer = 0.0 24 | 25 | var __cursor = add_child(Label.new()) 26 | var _cursor = get_child(0) 27 | var __options = add_child(Label.new()) 28 | var _options = get_child(1) 29 | 30 | var ronaldo = 0 31 | 32 | # ========= 'Public' methods ========== 33 | func set_options(new_options): 34 | options = new_options 35 | 36 | _create_options() 37 | _update_style() 38 | _reposition_options() 39 | 40 | func set_orientation(new_orientation): 41 | orientation = new_orientation 42 | 43 | _reposition_options() 44 | _reposition_cursor() 45 | 46 | func set_offset(new_offset): 47 | offset = new_offset 48 | 49 | _reposition_options() 50 | _reposition_cursor() 51 | 52 | func set_font(new_font): 53 | options_font = new_font 54 | 55 | _update_font() 56 | _reposition_options() 57 | _reposition_cursor() 58 | 59 | func set_cursor_option(new_initial_option): 60 | _current_option = (abs(new_initial_option) % _options.get_child_count()) 61 | initial_option = _current_option 62 | _reposition_cursor() 63 | 64 | func set_blinking_cursor_rate(n): 65 | blinking_cursor_rate = n 66 | 67 | func set_cursor_offset(n): 68 | cursor_offset = n 69 | _reposition_cursor() 70 | 71 | func set_options_color(new_options_color): 72 | options_color = new_options_color 73 | _update_color() 74 | 75 | func set_cursor_color(new_cursor_color): 76 | cursor_color = new_cursor_color 77 | _update_color() 78 | 79 | func set_cursor_side(s): 80 | cursor_side = s 81 | _reposition_cursor() 82 | 83 | func set_enabled_menu(b): 84 | menu_enabled = b 85 | if (!menu_enabled): 86 | _cursor.set_lines_skipped(1) 87 | _cursor_timer = 0.0 88 | else: 89 | _cursor.set_lines_skipped(0) 90 | _cursor_timer = 0.0 91 | 92 | # ========= Internal functions ========== 93 | 94 | func _clear_options(): 95 | for i in _options.get_children(): 96 | i.free() 97 | 98 | func _create_options(): 99 | _clear_options() 100 | for s in options.split("\n"): 101 | var label = Label.new() 102 | label.set_text(s) 103 | _options.add_child(label) 104 | 105 | func _update_style(): 106 | _update_font() 107 | _update_color() 108 | pass 109 | 110 | func _update_color(): 111 | for i in _options.get_children(): 112 | i.add_color_override("font_color", options_color) 113 | _cursor.add_color_override("font_color", cursor_color) 114 | 115 | func _update_font(): 116 | if (options_font == null): 117 | return 118 | for i in _options.get_children(): 119 | i.add_font_override("font", options_font) 120 | _cursor.add_font_override("font", options_font) 121 | 122 | func _reposition_options(): 123 | var count = 0 124 | var width = 0.0 125 | var height = 0.0 126 | for i in _options.get_children(): 127 | if orientation == 0: 128 | i.set_pos(Vector2(width, 0)) 129 | width += offset + i.get_size().x 130 | height = max(height, i.get_size().y) 131 | elif orientation == 1: 132 | i.set_pos(Vector2(0, height)) 133 | height += offset + i.get_size().y 134 | width = max(width, i.get_size().x) 135 | count += 1 136 | set_size(Vector2(width, height)) 137 | 138 | func _reposition_cursor(): 139 | var option_pos = _options.get_child(_current_option).get_pos() 140 | var option_size = _options.get_child(_current_option).get_size() 141 | if (cursor_side == 0): 142 | _cursor.set_text(">") 143 | _cursor.set_pos(Vector2(option_pos.x - (cursor_offset + _cursor.get_size().x), option_pos.y)) 144 | elif (cursor_side == 1): 145 | _cursor.set_text("v") 146 | _cursor.set_pos(Vector2(option_pos.x + (option_size.x/2.0) - (_cursor.get_size().x/2.0), option_pos.y - (_cursor.get_size().y + cursor_offset))) 147 | elif (cursor_side == 2): 148 | _cursor.set_text("<") 149 | _cursor.set_pos(Vector2(option_pos.x + option_size.x + cursor_offset, option_pos.y)) 150 | elif (cursor_side == 3): 151 | _cursor.set_text("^") 152 | _cursor.set_pos(Vector2(option_pos.x + (option_size.x/2.0) - (_cursor.get_size().x/2.0), option_pos.y + _cursor.get_size().y + cursor_offset)) 153 | 154 | pass 155 | 156 | func _ready(): 157 | _reposition_options() 158 | _reposition_cursor() 159 | if !(get_tree().is_editor_hint()): 160 | set_fixed_process(true) 161 | set_process_input(true) 162 | # Option and cursor 163 | add_user_signal("option_selected") 164 | add_user_signal("option_changed") 165 | 166 | func _fixed_process(delta): 167 | # Blinking 168 | if(menu_enabled): 169 | if(blinking_cursor_rate > 0): 170 | _cursor_timer += delta 171 | if _cursor_timer > blinking_cursor_rate: 172 | _cursor_timer = 0.0 173 | _cursor.set_lines_skipped((_cursor.get_lines_skipped()+1)%2) 174 | pass 175 | 176 | func _input(event): 177 | if(menu_enabled): 178 | if (event.type == InputEvent.KEY and event.pressed): 179 | if event.scancode == KEY_UP: 180 | if(orientation == 1): 181 | set_cursor_option(_current_option + get_child_count() - 1) 182 | emit_signal("option_changed") 183 | if event.scancode == KEY_DOWN: 184 | if(orientation == 1): 185 | set_cursor_option(_current_option + 1) 186 | emit_signal("option_changed") 187 | if event.scancode == KEY_RIGHT: 188 | if(orientation == 0): 189 | set_cursor_option(_current_option + 1) 190 | emit_signal("option_changed") 191 | if event.scancode == KEY_LEFT: 192 | if(orientation == 0): 193 | set_cursor_option(_current_option + get_child_count() - 1) 194 | emit_signal("option_changed") 195 | if event.scancode == KEY_RETURN: 196 | if(signal_argument == 0): 197 | emit_signal("option_selected", _current_option) 198 | elif(signal_argument == 1): 199 | emit_signal("option_selected", get_child(_current_option).get_text()) 200 | _cursor_timer = 0.0 201 | _cursor.set_lines_skipped(0) 202 | -------------------------------------------------------------------------------- /addons/GodotSTM/GodotSTM_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henriquelalves/GodotSimpleTextMenu/1da3bb5a22ec2201f137661e396f824fab8a6ac2/addons/GodotSTM/GodotSTM_icon.png -------------------------------------------------------------------------------- /addons/GodotSTM/GodotSTM_plugin.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends EditorPlugin 3 | 4 | func _enter_tree(): 5 | # When this plugin node enters tree, add the custom type 6 | 7 | add_custom_type("SimpleTextMenu","Control",preload("res://addons/GodotSTM/simple_text_menu.gd"),preload("res://addons/GodotSTM/GodotSTM_icon.png")) 8 | 9 | func _exit_tree(): 10 | # When the plugin node exits the tree, remove the custom type 11 | 12 | remove_custom_type("SimpleTextMenu") 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /addons/GodotSTM/plugin.cfg: -------------------------------------------------------------------------------- 1 | [plugin] 2 | 3 | name="GodotSTM" 4 | description="Adds a Simple Text Menu node to Godot." 5 | author="Henrique Alves" 6 | version="1.0" 7 | script="GodotSTM_plugin.gd" 8 | 9 | -------------------------------------------------------------------------------- /addons/GodotSTM/simple_text_menu.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Control 3 | 4 | # ========= Variables ========== 5 | signal option_selected 6 | signal option_changed 7 | 8 | export(String, MULTILINE) var options = "" setget set_options # The options on the menu, separated by line 9 | export(int, "Horizontal", "Vertical") var orientation = 0 setget set_orientation # Horizontal or Vertical menu 10 | export(int) var offset = 0 setget set_offset # Offset between options 11 | export(Font) var options_font = null setget set_font # Menu font 12 | export(int, "Number", "String") var signal_argument = 0 # Whether you receive the number of the option choosen or the string 13 | export(int) var initial_option = 0 setget set_cursor_option # Cursor starting position 14 | export(int, "Left", "Top", "Right", "Bottom") var cursor_side = 0 setget set_cursor_side # Which side the cursor will appear on the options 15 | export(int) var cursor_offset = 0 setget set_cursor_offset 16 | 17 | export(float) var blinking_cursor_rate = 0.0 setget set_blinking_cursor_rate# How many seconds for the cursor to blink (0 means he doesn't blink) 18 | export(Color) var options_color = Color(1.0,1.0,1.0,1.0) setget set_options_color 19 | export(Color) var cursor_color = Color(1.0,1.0,1.0,1.0) setget set_cursor_color 20 | export(bool) var menu_enabled = true setget set_menu 21 | 22 | var _current_option = 0 23 | var _cursor_timer = 0.0 24 | 25 | var __cursor = add_child(Label.new()) 26 | var _cursor = get_child(0) 27 | var __options = add_child(Label.new()) 28 | var _options = get_child(1) 29 | 30 | var editor = true 31 | 32 | # ========= 'Public' methods ========== 33 | func set_options(new_options): 34 | options = new_options 35 | 36 | _create_options() 37 | _update_style() 38 | _reposition_options() 39 | 40 | func set_orientation(new_orientation): 41 | orientation = new_orientation 42 | 43 | _reposition_options() 44 | _reposition_cursor() 45 | 46 | func set_offset(new_offset): 47 | offset = new_offset 48 | 49 | _reposition_options() 50 | _reposition_cursor() 51 | 52 | func set_font(new_font): 53 | options_font = new_font 54 | 55 | _update_font() 56 | _reposition_options() 57 | _reposition_cursor() 58 | 59 | func set_cursor_option(new_initial_option): 60 | _current_option = (abs(new_initial_option) % _options.get_child_count()) 61 | initial_option = _current_option 62 | _reposition_cursor() 63 | 64 | func set_blinking_cursor_rate(n): 65 | blinking_cursor_rate = n 66 | 67 | func set_cursor_offset(n): 68 | cursor_offset = n 69 | _reposition_cursor() 70 | 71 | func set_options_color(new_options_color): 72 | options_color = new_options_color 73 | _update_color() 74 | 75 | func set_cursor_color(new_cursor_color): 76 | cursor_color = new_cursor_color 77 | _update_color() 78 | 79 | func set_cursor_side(s): 80 | cursor_side = s 81 | _reposition_cursor() 82 | 83 | func set_menu(b): 84 | if(menu_enabled == b): 85 | return 86 | menu_enabled = b 87 | if (menu_enabled == false): 88 | _cursor.hide() 89 | _cursor_timer = 0.0 90 | if (editor == false): 91 | set_fixed_process(false) 92 | set_process_input(false) 93 | else: 94 | _cursor.show() 95 | _cursor_timer = 0.0 96 | if (editor == false): 97 | set_fixed_process(true) 98 | set_process_input(true) 99 | 100 | # ========= Internal functions ========== 101 | 102 | func _clear_options(): 103 | for i in _options.get_children(): 104 | i.free() 105 | 106 | func _create_options(): 107 | _clear_options() 108 | for s in options.split("\n"): 109 | var label = Label.new() 110 | label.set_text(s) 111 | _options.add_child(label) 112 | 113 | func _update_style(): 114 | _update_font() 115 | _update_color() 116 | pass 117 | 118 | func _update_color(): 119 | for i in _options.get_children(): 120 | i.add_color_override("font_color", options_color) 121 | _cursor.add_color_override("font_color", cursor_color) 122 | 123 | func _update_font(): 124 | if (options_font == null): 125 | return 126 | for i in _options.get_children(): 127 | i.add_font_override("font", options_font) 128 | _cursor.add_font_override("font", options_font) 129 | 130 | func _reposition_options(): 131 | var count = 0 132 | var width = 0.0 133 | var height = 0.0 134 | for i in _options.get_children(): 135 | if orientation == 0: 136 | i.set_pos(Vector2(width, 0)) 137 | width += offset + i.get_size().x 138 | height = max(height, i.get_size().y) 139 | elif orientation == 1: 140 | i.set_pos(Vector2(0, height)) 141 | height += offset + i.get_size().y 142 | width = max(width, i.get_size().x) 143 | count += 1 144 | set_size(Vector2(width, height)) 145 | 146 | func _reposition_cursor(): 147 | var option_pos = _options.get_child(_current_option).get_pos() 148 | var option_size = _options.get_child(_current_option).get_size() 149 | if (cursor_side == 0): 150 | _cursor.set_text(">") 151 | _cursor.set_pos(Vector2(option_pos.x - (cursor_offset + _cursor.get_size().x), option_pos.y)) 152 | elif (cursor_side == 1): 153 | _cursor.set_text("v") 154 | _cursor.set_pos(Vector2(option_pos.x + (option_size.x/2.0) - (_cursor.get_size().x/2.0), option_pos.y - (_cursor.get_size().y + cursor_offset))) 155 | elif (cursor_side == 2): 156 | _cursor.set_text("<") 157 | _cursor.set_pos(Vector2(option_pos.x + option_size.x + cursor_offset, option_pos.y)) 158 | elif (cursor_side == 3): 159 | _cursor.set_text("^") 160 | _cursor.set_pos(Vector2(option_pos.x + (option_size.x/2.0) - (_cursor.get_size().x/2.0), option_pos.y + _cursor.get_size().y + cursor_offset)) 161 | 162 | pass 163 | 164 | func _ready(): 165 | _reposition_options() 166 | _reposition_cursor() 167 | if !(get_tree().is_editor_hint()): 168 | editor = false 169 | set_fixed_process(true) 170 | set_process_input(true) 171 | else: 172 | editor = true 173 | 174 | func _fixed_process(delta): 175 | # Blinking 176 | if(blinking_cursor_rate > 0): 177 | _cursor_timer += delta 178 | if _cursor_timer > blinking_cursor_rate: 179 | _cursor_timer = 0.0 180 | _cursor.set_lines_skipped((_cursor.get_lines_skipped()+1)%2) 181 | pass 182 | 183 | func _input(event): 184 | if (event.type == InputEvent.KEY and event.pressed): 185 | if event.scancode == KEY_UP: 186 | if(orientation == 1): 187 | set_cursor_option(_current_option + _options.get_child_count() - 1) 188 | emit_signal("option_changed") 189 | if event.scancode == KEY_DOWN: 190 | if(orientation == 1): 191 | set_cursor_option(_current_option + 1) 192 | emit_signal("option_changed") 193 | if event.scancode == KEY_RIGHT: 194 | if(orientation == 0): 195 | set_cursor_option(_current_option + 1) 196 | emit_signal("option_changed") 197 | if event.scancode == KEY_LEFT: 198 | if(orientation == 0): 199 | set_cursor_option(_current_option + _options.get_child_count() - 1) 200 | emit_signal("option_changed") 201 | if event.scancode == KEY_RETURN: 202 | if(signal_argument == 0): 203 | emit_signal("option_selected", _current_option) 204 | elif(signal_argument == 1): 205 | emit_signal("option_selected", _options.get_child(_current_option).get_text()) 206 | _cursor_timer = 0.0 207 | _cursor.set_lines_skipped(0) -------------------------------------------------------------------------------- /cave_font.fnt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henriquelalves/GodotSimpleTextMenu/1da3bb5a22ec2201f137661e396f824fab8a6ac2/cave_font.fnt -------------------------------------------------------------------------------- /cave_font.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henriquelalves/GodotSimpleTextMenu/1da3bb5a22ec2201f137661e396f824fab8a6ac2/cave_font.ttf -------------------------------------------------------------------------------- /demo.gd: -------------------------------------------------------------------------------- 1 | 2 | extends Control 3 | 4 | # member variables here, example: 5 | # var a=2 6 | # var b="textvar" 7 | 8 | func _ready(): 9 | for menu in get_node("menus").get_children(): 10 | menu.connect("option_selected", self, "selected") 11 | select_menu(0) 12 | pass 13 | 14 | func selected(o): 15 | print("Option selected: ",o) 16 | if(o == "Back"): 17 | select_menu(0) 18 | elif(o == "Go to Menu 1"): 19 | select_menu(1) 20 | elif(o == "Go to Menu 2"): 21 | select_menu(2) 22 | elif(o == "Go to Menu 3"): 23 | select_menu(3) 24 | 25 | func select_menu(n): 26 | for menu in range(0, get_node("menus").get_child_count()): 27 | get_node("menus").get_child(menu).set_menu(false) 28 | if menu == n: 29 | get_node("menus").get_child(menu).set_menu(true) 30 | -------------------------------------------------------------------------------- /demo.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=5 format=1] 2 | 3 | [ext_resource path="res://demo.gd" type="Script" id=1] 4 | [ext_resource path="res://addons/GodotSTM/simple_text_menu.gd" type="Script" id=2] 5 | [ext_resource path="res://addons/GodotSTM/GodotSTM_icon.png" type="Texture" id=3] 6 | [ext_resource path="res://cave_font.fnt" type="BitmapFont" id=4] 7 | 8 | [node name="Control" type="Control"] 9 | 10 | focus/ignore_mouse = false 11 | focus/stop_mouse = true 12 | size_flags/horizontal = 2 13 | size_flags/vertical = 2 14 | margin/left = 0.0 15 | margin/top = 0.0 16 | margin/right = 40.0 17 | margin/bottom = 40.0 18 | script/script = ExtResource( 1 ) 19 | 20 | [node name="menus" type="Control" parent="."] 21 | 22 | focus/ignore_mouse = false 23 | focus/stop_mouse = true 24 | size_flags/horizontal = 2 25 | size_flags/vertical = 2 26 | margin/left = 0.0 27 | margin/top = 0.0 28 | margin/right = 40.0 29 | margin/bottom = 40.0 30 | 31 | [node name="main_menu" type="Control" parent="menus"] 32 | 33 | focus/ignore_mouse = false 34 | focus/stop_mouse = true 35 | size_flags/horizontal = 2 36 | size_flags/vertical = 2 37 | margin/left = 394.0 38 | margin/top = 91.0 39 | margin/right = 539.0 40 | margin/bottom = 178.0 41 | script/script = ExtResource( 2 ) 42 | __meta__ = { "_editor_icon":ExtResource( 3 ) } 43 | options = "Go to Menu 1\nGo to Menu 2\nGo to Menu 3" 44 | orientation = 1 45 | offset = 10 46 | options_font = ExtResource( 4 ) 47 | signal_argument = 1 48 | initial_option = 0 49 | cursor_side = 0 50 | cursor_offset = 6 51 | blinking_cursor_rate = 0.4 52 | options_color = Color( 0, 0, 0, 1 ) 53 | cursor_color = Color( 0.992188, 1, 0, 1 ) 54 | menu_enabled = true 55 | 56 | [node name="menu_1" type="Control" parent="menus"] 57 | 58 | focus/ignore_mouse = false 59 | focus/stop_mouse = true 60 | size_flags/horizontal = 2 61 | size_flags/vertical = 2 62 | margin/left = 107.0 63 | margin/top = 262.0 64 | margin/right = 205.0 65 | margin/bottom = 422.0 66 | script/script = ExtResource( 2 ) 67 | __meta__ = { "_editor_icon":ExtResource( 3 ) } 68 | options = "Dummy 1\nDummy 2\nDummy 3\nBack" 69 | orientation = 1 70 | offset = 21 71 | options_font = ExtResource( 4 ) 72 | signal_argument = 1 73 | initial_option = 2 74 | cursor_side = 2 75 | cursor_offset = 31 76 | blinking_cursor_rate = 0.0 77 | options_color = Color( 0.0467396, 0.0336304, 0.453125, 1 ) 78 | cursor_color = Color( 1, 1, 1, 1 ) 79 | menu_enabled = true 80 | 81 | [node name="menu_2" type="Control" parent="menus"] 82 | 83 | focus/ignore_mouse = false 84 | focus/stop_mouse = true 85 | size_flags/horizontal = 2 86 | size_flags/vertical = 2 87 | margin/left = 319.0 88 | margin/top = 334.0 89 | margin/right = 589.0 90 | margin/bottom = 353.0 91 | script/script = ExtResource( 2 ) 92 | __meta__ = { "_editor_icon":ExtResource( 3 ) } 93 | options = "Dummy 4\nDummy 5\nBack" 94 | orientation = 0 95 | offset = 6 96 | options_font = ExtResource( 4 ) 97 | signal_argument = 1 98 | initial_option = 1 99 | cursor_side = 1 100 | cursor_offset = 6 101 | blinking_cursor_rate = 0.1 102 | options_color = Color( 0.010025, 0.855469, 0.0628653, 1 ) 103 | cursor_color = Color( 0.957031, 0.0635529, 0.817425, 1 ) 104 | menu_enabled = true 105 | 106 | [node name="menu_3" type="Control" parent="menus"] 107 | 108 | focus/ignore_mouse = false 109 | focus/stop_mouse = true 110 | size_flags/horizontal = 2 111 | size_flags/vertical = 2 112 | margin/left = 713.0 113 | margin/top = 281.0 114 | margin/right = 811.0 115 | margin/bottom = 347.0 116 | script/script = ExtResource( 2 ) 117 | __meta__ = { "_editor_icon":ExtResource( 3 ) } 118 | options = "Dummy 6\nBack" 119 | orientation = 1 120 | offset = 14 121 | options_font = ExtResource( 4 ) 122 | signal_argument = 1 123 | initial_option = 1 124 | cursor_side = 3 125 | cursor_offset = 0 126 | blinking_cursor_rate = 1.0 127 | options_color = Color( 0.785156, 0.0920105, 0, 1 ) 128 | cursor_color = Color( 0.17395, 0.218742, 0.890625, 1 ) 129 | menu_enabled = true 130 | 131 | [node name="labels" type="Control" parent="."] 132 | 133 | editor/display_folded = true 134 | focus/ignore_mouse = false 135 | focus/stop_mouse = true 136 | size_flags/horizontal = 2 137 | size_flags/vertical = 2 138 | margin/left = 0.0 139 | margin/top = 0.0 140 | margin/right = 40.0 141 | margin/bottom = 40.0 142 | 143 | [node name="main_menu" type="Label" parent="labels"] 144 | 145 | focus/ignore_mouse = true 146 | focus/stop_mouse = true 147 | size_flags/horizontal = 2 148 | size_flags/vertical = 0 149 | margin/left = 432.0 150 | margin/top = 65.0 151 | margin/right = 503.0 152 | margin/bottom = 79.0 153 | text = "Main Menu" 154 | percent_visible = 1.0 155 | lines_skipped = 0 156 | max_lines_visible = -1 157 | 158 | [node name="main_menu1" type="Label" parent="labels"] 159 | 160 | focus/ignore_mouse = true 161 | focus/stop_mouse = true 162 | size_flags/horizontal = 2 163 | size_flags/vertical = 0 164 | margin/left = 120.0 165 | margin/top = 238.0 166 | margin/right = 191.0 167 | margin/bottom = 252.0 168 | text = "Menu 1" 169 | percent_visible = 1.0 170 | lines_skipped = 0 171 | max_lines_visible = -1 172 | 173 | [node name="main_menu2" type="Label" parent="labels"] 174 | 175 | focus/ignore_mouse = true 176 | focus/stop_mouse = true 177 | size_flags/horizontal = 2 178 | size_flags/vertical = 0 179 | margin/left = 437.0 180 | margin/top = 292.0 181 | margin/right = 485.0 182 | margin/bottom = 306.0 183 | text = "Menu 2" 184 | percent_visible = 1.0 185 | lines_skipped = 0 186 | max_lines_visible = -1 187 | 188 | [node name="main_menu3" type="Label" parent="labels"] 189 | 190 | focus/ignore_mouse = true 191 | focus/stop_mouse = true 192 | size_flags/horizontal = 2 193 | size_flags/vertical = 0 194 | margin/left = 732.0 195 | margin/top = 256.0 196 | margin/right = 780.0 197 | margin/bottom = 270.0 198 | text = "Menu 3" 199 | percent_visible = 1.0 200 | lines_skipped = 0 201 | max_lines_visible = -1 202 | 203 | [node name="Label" type="Label" parent="."] 204 | 205 | focus/ignore_mouse = true 206 | focus/stop_mouse = true 207 | size_flags/horizontal = 2 208 | size_flags/vertical = 0 209 | margin/left = 10.0 210 | margin/top = 5.0 211 | margin/right = 375.0 212 | margin/bottom = 121.0 213 | text = "This demo uses the String signal to enable/disable\nthe corresponding menus.\n\nIt has the purpose of showing some of the \ncustomization options you can easily change \nusing the export variables.\n\nHope you like it!" 214 | percent_visible = 1.0 215 | lines_skipped = 0 216 | max_lines_visible = -1 217 | 218 | 219 | -------------------------------------------------------------------------------- /engine.cfg: -------------------------------------------------------------------------------- 1 | [application] 2 | 3 | name="GodotSimpleTextMenu" 4 | main_scene="res://demo.tscn" 5 | icon="res://icon.png" 6 | 7 | [editor_plugins] 8 | 9 | enabled=["GodotSTM", "SimpleTextMenu"] 10 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henriquelalves/GodotSimpleTextMenu/1da3bb5a22ec2201f137661e396f824fab8a6ac2/icon.png -------------------------------------------------------------------------------- /icon.png.flags: -------------------------------------------------------------------------------- 1 | gen_mipmaps=false 2 | -------------------------------------------------------------------------------- /menu_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/henriquelalves/GodotSimpleTextMenu/1da3bb5a22ec2201f137661e396f824fab8a6ac2/menu_example.png --------------------------------------------------------------------------------