diff src/luan_editor/menu.luan @ 37:b7ff52d45b9a default tip

copy from luan
author Franklin Schmidt <fschmidt@gmail.com>
date Mon, 21 Apr 2025 13:07:29 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan_editor/menu.luan	Mon Apr 21 13:07:29 2025 -0600
@@ -0,0 +1,231 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+local String = require "luan:String.luan"
+local to_number = String.to_number or error()
+local new_menu_item = require("luan:swing/Menu_item.luan").new or error()
+local new_check_box_menu_item = require("luan:swing/Check_box_menu_item.luan").new or error()
+local new_menu_bar = require("luan:swing/Menu_bar.luan").new or error()
+local Menu = require "luan:swing/Menu.luan"
+local new_menu = Menu.new or error()
+local separator = Menu.separator or error()
+local Option_pane = require "luan:swing/Option_pane.luan"
+local show_message_dialog = Option_pane.show_message_dialog or error()
+local show_input_dialog = Option_pane.show_input_dialog or error()
+local Spell_checker = require "classpath:luan_editor/Spell_checker.luan"
+local spell_check = Spell_checker.spell_check or error()
+
+
+local function action_listener(fn)
+	return function(_)
+		fn()
+	end
+end
+
+local function add_menu_bar(window)
+	local text_area = window.text_area
+	local document = text_area.document
+	local status_bar = window.status_bar
+	local revert = new_menu_item{
+		text = "Revert"
+		enabled = window.has_file
+		action_listener = action_listener(window.revert)
+	}
+	local undo = new_menu_item{
+		text = "Undo"
+		accelerator = "meta Z"
+		action_listener = action_listener(document.undo)
+	}
+	local redo = new_menu_item{
+		text = "Redo"
+		accelerator = "meta shift Z"
+		action_listener = action_listener(document.redo)
+	}
+	local function update_undo_redo()
+		undo.set_enabled(document.can_undo())
+		redo.set_enabled(document.can_redo())
+	end
+	window.update_undo_redo = update_undo_redo  -- dont gc
+	update_undo_redo()
+	document.add_undo_listener(update_undo_redo)
+
+	local find_menu_item = new_check_box_menu_item{
+		text = "Find and Replace"
+		accelerator = "meta F"
+		action_listener = function(event)
+			window.show_find_panel(event.source.state)
+		end
+	}
+	window.find_menu_item = find_menu_item
+
+	local menu_bar = new_menu_bar{
+		menus = {
+			new_menu{
+				text = "File"
+				menu_items = {
+					new_menu_item{
+						text = "New File"
+						accelerator = "meta N"
+						action_listener = action_listener(window.new)
+					}
+					new_menu_item{
+						text = "Open..."
+						accelerator = "meta O"
+						action_listener = action_listener(window.open)
+					}
+					new_menu_item{
+						text = "Save"
+						accelerator = "meta S"
+						action_listener = function(_)
+							if window.save() then
+								revert.set_enabled(true)
+							end
+						end
+					}
+					new_menu_item{
+						text = "Print"
+						action_listener = action_listener(text_area.print)
+					}
+					revert
+--[[
+					new_menu_item{
+						text = "Test"
+						action_listener = function(_)
+							local location = window.frame.location
+							location.y = location.y - 20
+							window.frame.location = location
+						end
+					}
+]]
+				}
+			}
+			new_menu{
+				text = "Edit"
+				menu_items = {
+					undo
+					redo
+					separator
+					new_menu_item{
+						text = "Cut"
+						accelerator = "meta X"
+						action_listener = action_listener(text_area.cut)
+					}
+					new_menu_item{
+						text = "Copy"
+						accelerator = "meta C"
+						action_listener = action_listener(text_area.copy)
+					}
+					new_menu_item{
+						text = "Paste"
+						accelerator = "meta V"
+						action_listener = action_listener(text_area.paste)
+					}
+					separator
+					new_menu_item{
+						text = "Indent"
+						accelerator = "meta CLOSE_BRACKET"
+						action_listener = action_listener(window.indent)
+					}
+					new_menu_item{
+						text = "Unindent"
+						accelerator = "meta OPEN_BRACKET"
+						action_listener = action_listener(window.unindent)
+					}
+					separator
+					new_menu_item{
+						text = "Select All"
+						accelerator = "meta A"
+						action_listener = action_listener(text_area.select_all)
+					}
+				}
+			}
+			new_menu{
+				text = "Find"
+				menu_items = {
+					find_menu_item
+					new_menu_item{
+						text = "Find Case Insensitive"
+						action_listener = window.find_case_insensitive
+					}
+					new_menu_item{
+						text = "Convert Leading Tabs to Spaces"
+						action_listener = window.tabs_to_spaces
+					}
+					new_menu_item{
+						text = "Convert Leading Spaces to Tabs"
+						action_listener = window.spaces_to_tabs
+					}
+				}
+			}
+			new_menu{
+				text = "View"
+				menu_items = {
+					new_check_box_menu_item{
+						text = "Word Wrap"
+						state = text_area.line_wrap
+						action_listener = function(event)
+							window.set_line_wrap(event.source.state)
+						end
+					}
+					new_check_box_menu_item{
+						text = "Show Whitespace"
+						accelerator = "meta W"
+						state = text_area.whitespace_visible
+						action_listener = function(event)
+							window.set_whitespace_visible(event.source.state)
+						end
+					}
+					new_check_box_menu_item{
+						text = "Spell Check"
+						accelerator = "meta SEMICOLON"
+						action_listener = function(event)
+							spell_check(text_area,event.source.state)
+						end
+					}
+					new_menu_item{
+						text = "Cursor Column"
+						accelerator = "meta B"
+						action_listener = function(_)
+							status_bar.text = "Cursor Column: "..window.cursor_column()
+						end
+					}
+					new_menu_item{
+						text = "Goto Line"
+						accelerator = "meta G"
+						action_listener = function(_)
+							local input = show_input_dialog( window.frame, "Goto line" )
+							if input == nil then
+								return
+							end
+							local line = to_number(input)
+							try
+								window.goto(line)
+								status_bar.text = "Went to line "..line
+							catch e
+								status_bar.text = "Invalid line: "..input
+							end
+						end
+					}
+					new_menu_item{
+						text = "Tab Size"
+						action_listener = function(_)
+							local input = show_input_dialog( window.frame, "Tab size", text_area.tab_size )
+							if input == nil then
+								return
+							end
+							local size = to_number(input)
+							try
+								window.set_tab_size(size)
+								status_bar.text = "Set tab size to "..size
+							catch e
+								status_bar.text = "Invalid tab size: "..input
+							end
+						end
+					}
+				}
+			}
+		}
+	}
+	window.frame.set_menu_bar(menu_bar)
+end
+
+return add_menu_bar