Mercurial Hosting > editor
comparison editor.luan @ 21:79f060db4d79
work
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Tue, 08 Apr 2025 19:43:16 -0600 |
| parents | 1bfd4a2d6d4e |
| children | b2d9b3836c2b |
comparison
equal
deleted
inserted
replaced
| 20:1bfd4a2d6d4e | 21:79f060db4d79 |
|---|---|
| 17 local new_label = require("luan:swing/Label.luan").new or error() | 17 local new_label = require("luan:swing/Label.luan").new or error() |
| 18 local new_text_area = require("luan:swing/Text_area.luan").new or error() | 18 local new_text_area = require("luan:swing/Text_area.luan").new or error() |
| 19 local new_scroll_pane = require("luan:swing/Scroll_pane.luan").new or error() | 19 local new_scroll_pane = require("luan:swing/Scroll_pane.luan").new or error() |
| 20 local new_text_area_line_numbers = require("luan:swing/Text_area_line_numbers.luan").new or error() | 20 local new_text_area_line_numbers = require("luan:swing/Text_area_line_numbers.luan").new or error() |
| 21 local new_menu_bar = require("luan:swing/Menu_bar.luan").new or error() | 21 local new_menu_bar = require("luan:swing/Menu_bar.luan").new or error() |
| 22 local new_menu = require("luan:swing/Menu.luan").new or error() | 22 local Menu = require "luan:swing/Menu.luan" |
| 23 local new_menu = Menu.new or error() | |
| 24 local separator = Menu.separator or error() | |
| 23 local new_menu_item = require("luan:swing/Menu_item.luan").new or error() | 25 local new_menu_item = require("luan:swing/Menu_item.luan").new or error() |
| 24 local new_check_box_menu_item = require("luan:swing/Check_box_menu_item.luan").new or error() | 26 local new_check_box_menu_item = require("luan:swing/Check_box_menu_item.luan").new or error() |
| 25 local int_to_color = require("luan:swing/Color.luan").int_to_color or error() | 27 local int_to_color = require("luan:swing/Color.luan").int_to_color or error() |
| 26 local Border = require "luan:swing/Border.luan" | 28 local Border = require "luan:swing/Border.luan" |
| 27 local create_empty_border = Border.create_empty_border or error() | 29 local create_empty_border = Border.create_empty_border or error() |
| 46 fn() | 48 fn() |
| 47 end | 49 end |
| 48 end | 50 end |
| 49 | 51 |
| 50 local function make_menu_bar(window) | 52 local function make_menu_bar(window) |
| 51 local menu_bar = new_menu_bar() | 53 local document = window.text_area.document |
| 52 do | 54 local revert = new_menu_item{ |
| 53 local file_menu = new_menu() | 55 text = "Revert" |
| 54 file_menu.text = "File" | 56 enabled = window.has_file |
| 55 do | 57 action_listener = action_listener(window.revert) |
| 56 local new_file = new_menu_item{ | 58 } |
| 57 text = "New File" | 59 local undo = new_menu_item{ |
| 58 accelerator = "meta N" | 60 text = "Undo" |
| 59 action_listener = function(_) | 61 accelerator = "meta Z" |
| 60 new_window() | 62 action_listener = action_listener(document.undo) |
| 61 end | 63 } |
| 64 local redo = new_menu_item{ | |
| 65 text = "Redo" | |
| 66 accelerator = "meta shift Z" | |
| 67 action_listener = action_listener(document.redo) | |
| 68 } | |
| 69 local function update_undo_redo() | |
| 70 undo.set_enabled(document.can_undo()) | |
| 71 redo.set_enabled(document.can_redo()) | |
| 72 end | |
| 73 window.update_undo_redo = update_undo_redo -- dont gc | |
| 74 update_undo_redo() | |
| 75 document.add_undo_listener(update_undo_redo) | |
| 76 | |
| 77 return new_menu_bar{ | |
| 78 menus = { | |
| 79 new_menu{ | |
| 80 text = "File" | |
| 81 menu_items = { | |
| 82 new_menu_item{ | |
| 83 text = "New File" | |
| 84 accelerator = "meta N" | |
| 85 action_listener = function(_) | |
| 86 new_window() | |
| 87 end | |
| 88 } | |
| 89 new_menu_item{ | |
| 90 text = "Open..." | |
| 91 accelerator = "meta O" | |
| 92 action_listener = action_listener(window.open) | |
| 93 } | |
| 94 new_menu_item{ | |
| 95 text = "Save" | |
| 96 accelerator = "meta S" | |
| 97 action_listener = function(_) | |
| 98 if window.save() then | |
| 99 revert.set_enabled(true) | |
| 100 end | |
| 101 end | |
| 102 } | |
| 103 revert | |
| 104 } | |
| 62 } | 105 } |
| 63 file_menu.add(new_file) | 106 new_menu{ |
| 64 end | 107 text = "Edit" |
| 65 do | 108 menu_items = { |
| 66 local open = new_menu_item{ | 109 undo |
| 67 text = "Open..." | 110 redo |
| 68 accelerator = "meta O" | 111 separator |
| 69 action_listener = action_listener(window.open) | 112 new_menu_item{ |
| 113 text = "Cut" | |
| 114 accelerator = "meta X" | |
| 115 action_listener = action_listener(window.text_area.cut) | |
| 116 } | |
| 117 new_menu_item{ | |
| 118 text = "Copy" | |
| 119 accelerator = "meta C" | |
| 120 action_listener = action_listener(window.text_area.copy) | |
| 121 } | |
| 122 new_menu_item{ | |
| 123 text = "Paste" | |
| 124 accelerator = "meta V" | |
| 125 action_listener = action_listener(window.text_area.paste) | |
| 126 } | |
| 127 separator | |
| 128 new_menu_item{ | |
| 129 text = "Indent" | |
| 130 accelerator = "meta CLOSE_BRACKET" | |
| 131 action_listener = action_listener(window.indent) | |
| 132 } | |
| 133 new_menu_item{ | |
| 134 text = "Unindent" | |
| 135 accelerator = "meta OPEN_BRACKET" | |
| 136 action_listener = action_listener(window.unindent) | |
| 137 } | |
| 138 separator | |
| 139 new_menu_item{ | |
| 140 text = "Select All" | |
| 141 accelerator = "meta A" | |
| 142 action_listener = action_listener(window.text_area.select_all) | |
| 143 } | |
| 144 separator | |
| 145 new_menu_item{ | |
| 146 text = "Find and Replace" | |
| 147 accelerator = "meta F" | |
| 148 action_listener = action_listener(window.show_find_dialog) | |
| 149 } | |
| 150 } | |
| 70 } | 151 } |
| 71 file_menu.add(open) | 152 new_menu{ |
| 72 end | 153 text = "View" |
| 73 local revert | 154 menu_items = { |
| 74 do | 155 new_check_box_menu_item{ |
| 75 local save = new_menu_item{ | 156 text = "Word Wrap" |
| 76 text = "Save" | 157 state = window.text_area.line_wrap |
| 77 accelerator = "meta S" | 158 action_listener = function(event) |
| 78 action_listener = function(_) | 159 window.text_area.line_wrap = event.source.state |
| 79 if window.save() then | 160 end |
| 80 revert.set_enabled(true) | 161 } |
| 81 end | 162 new_check_box_menu_item{ |
| 82 end | 163 text = "Show Whitespace" |
| 164 action_listener = function(event) | |
| 165 window.text_area.show_whitespace(event.source.state) | |
| 166 end | |
| 167 } | |
| 168 new_menu_item{ | |
| 169 text = "Show Cursor Column" | |
| 170 action_listener = function(_) | |
| 171 show_message_dialog( window.frame, "Cursor Column: "..window.cursor_column() ) | |
| 172 end | |
| 173 } | |
| 174 new_menu_item{ | |
| 175 text = "Goto Line" | |
| 176 accelerator = "meta G" | |
| 177 action_listener = function(_) | |
| 178 local input = show_input_dialog( window.frame, "Goto line" ) | |
| 179 --logger.info("input "..input) | |
| 180 local line = input and to_number(input) | |
| 181 if line ~= nil then | |
| 182 window.goto(line) | |
| 183 end | |
| 184 end | |
| 185 } | |
| 186 } | |
| 83 } | 187 } |
| 84 file_menu.add(save) | 188 } |
| 85 end | 189 } |
| 86 do | |
| 87 revert = new_menu_item{ | |
| 88 text = "Revert" | |
| 89 enabled = window.has_file | |
| 90 action_listener = action_listener(window.revert) | |
| 91 } | |
| 92 file_menu.add(revert) | |
| 93 end | |
| 94 menu_bar.add(file_menu) | |
| 95 end | |
| 96 do | |
| 97 local edit_menu = new_menu() | |
| 98 edit_menu.text = "Edit" | |
| 99 local document = window.text_area.document | |
| 100 local undo, redo | |
| 101 do | |
| 102 undo = new_menu_item{ | |
| 103 text = "Undo" | |
| 104 accelerator = "meta Z" | |
| 105 action_listener = action_listener(document.undo) | |
| 106 } | |
| 107 edit_menu.add(undo) | |
| 108 end | |
| 109 do | |
| 110 redo = new_menu_item{ | |
| 111 text = "Redo" | |
| 112 accelerator = "meta shift Z" | |
| 113 action_listener = action_listener(document.redo) | |
| 114 } | |
| 115 edit_menu.add(redo) | |
| 116 end | |
| 117 local function update_undo_redo() | |
| 118 undo.set_enabled(document.can_undo()) | |
| 119 redo.set_enabled(document.can_redo()) | |
| 120 end | |
| 121 edit_menu.dont_gc(update_undo_redo) | |
| 122 update_undo_redo() | |
| 123 document.add_undo_listener(update_undo_redo) | |
| 124 edit_menu.add_separator() | |
| 125 do | |
| 126 local cut = new_menu_item{ | |
| 127 text = "Cut" | |
| 128 accelerator = "meta X" | |
| 129 action_listener = action_listener(window.text_area.cut) | |
| 130 } | |
| 131 edit_menu.add(cut) | |
| 132 end | |
| 133 do | |
| 134 local copy = new_menu_item{ | |
| 135 text = "Copy" | |
| 136 accelerator = "meta C" | |
| 137 action_listener = action_listener(window.text_area.copy) | |
| 138 } | |
| 139 edit_menu.add(copy) | |
| 140 end | |
| 141 do | |
| 142 local paste = new_menu_item{ | |
| 143 text = "Paste" | |
| 144 accelerator = "meta V" | |
| 145 action_listener = action_listener(window.text_area.paste) | |
| 146 } | |
| 147 edit_menu.add(paste) | |
| 148 end | |
| 149 edit_menu.add_separator() | |
| 150 do | |
| 151 local indent = new_menu_item{ | |
| 152 text = "Indent" | |
| 153 accelerator = "meta CLOSE_BRACKET" | |
| 154 action_listener = action_listener(window.indent) | |
| 155 } | |
| 156 edit_menu.add(indent) | |
| 157 end | |
| 158 do | |
| 159 local unindent = new_menu_item{ | |
| 160 text = "Unindent" | |
| 161 accelerator = "meta OPEN_BRACKET" | |
| 162 action_listener = action_listener(window.unindent) | |
| 163 } | |
| 164 edit_menu.add(unindent) | |
| 165 end | |
| 166 edit_menu.add_separator() | |
| 167 do | |
| 168 local select_all = new_menu_item{ | |
| 169 text = "Select All" | |
| 170 accelerator = "meta A" | |
| 171 action_listener = action_listener(window.text_area.select_all) | |
| 172 } | |
| 173 edit_menu.add(select_all) | |
| 174 end | |
| 175 edit_menu.add_separator() | |
| 176 do | |
| 177 local find = new_menu_item{ | |
| 178 text = "Find and Replace" | |
| 179 accelerator = "meta F" | |
| 180 action_listener = action_listener(window.show_find_dialog) | |
| 181 } | |
| 182 edit_menu.add(find) | |
| 183 end | |
| 184 menu_bar.add(edit_menu) | |
| 185 end | |
| 186 do | |
| 187 local view_menu = new_menu() | |
| 188 view_menu.text = "View" | |
| 189 do | |
| 190 local word_wrap = new_check_box_menu_item{ | |
| 191 text = "Word Wrap" | |
| 192 state = window.text_area.line_wrap | |
| 193 action_listener = function(event) | |
| 194 window.text_area.line_wrap = event.source.state | |
| 195 end | |
| 196 } | |
| 197 view_menu.add(word_wrap) | |
| 198 end | |
| 199 do | |
| 200 local show_whitespace = new_check_box_menu_item() | |
| 201 show_whitespace.text = "Show Whitespace" | |
| 202 show_whitespace.add_action_listener(function(_) | |
| 203 window.text_area.show_whitespace(show_whitespace.state) | |
| 204 end) | |
| 205 view_menu.add(show_whitespace) | |
| 206 end | |
| 207 do | |
| 208 local show_column = new_menu_item() | |
| 209 show_column.text = "Show Cursor Column" | |
| 210 show_column.add_action_listener(function(_) | |
| 211 show_message_dialog( window.frame, "Cursor Column: "..window.cursor_column() ) | |
| 212 end) | |
| 213 view_menu.add(show_column) | |
| 214 end | |
| 215 do | |
| 216 local goto = new_menu_item() | |
| 217 goto.text = "Goto Line" | |
| 218 goto.accelerator = "meta G" | |
| 219 goto.add_action_listener(function(_) | |
| 220 local input = show_input_dialog( window.frame, "Goto line" ) | |
| 221 --logger.info("input "..input) | |
| 222 local line = input and to_number(input) | |
| 223 if line ~= nil then | |
| 224 window.goto(line) | |
| 225 end | |
| 226 end) | |
| 227 view_menu.add(goto) | |
| 228 end | |
| 229 menu_bar.add(view_menu) | |
| 230 end | |
| 231 return menu_bar | |
| 232 end | 190 end |
| 233 | 191 |
| 234 local function make_find_dialog(window) | 192 local function make_find_dialog(window) |
| 235 local dialog = new_dialog(window.frame) | 193 local dialog = new_dialog(window.frame) |
| 236 local root = dialog.component | 194 local root = dialog.component |
