Mercurial Hosting > luan
changeset 1914:d5776185f9d7
config
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 17 Apr 2025 18:36:27 -0600 |
parents | 4f0c14fad13b |
children | 15dda75a887f |
files | src/luan/modules/editor/find.luan src/luan/modules/editor/menu.luan src/luan/modules/editor/window.luan src/luan/modules/swing/Awt_container.luan src/luan/modules/swing/Component.luan src/luan/modules/swing/Frame.luan src/luan/modules/swing/SwingLuan.java src/luan/modules/swing/TextAreaLuan.java src/luan/modules/swing/TextFieldLuan.java src/luan/modules/swing/Text_area.luan src/luan/modules/swing/Text_field.luan src/luan/modules/swing/Utils.luan |
diffstat | 12 files changed, 272 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/modules/editor/find.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/editor/find.luan Thu Apr 17 18:36:27 2025 -0600 @@ -135,13 +135,13 @@ end find_field = new_text_field{ constraints = "growx" - show_whitespace = true + whitespace_visible = true action = "next" action_listener = find_match } replace_field = new_text_field{ constraints = "growx" - show_whitespace = true + whitespace_visible = true action = "replace" action_listener = replace_match }
--- a/src/luan/modules/editor/menu.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/editor/menu.luan Thu Apr 17 18:36:27 2025 -0600 @@ -84,6 +84,16 @@ 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{ @@ -151,13 +161,14 @@ text = "Word Wrap" state = text_area.line_wrap action_listener = function(event) - text_area.line_wrap = event.source.state + window.set_line_wrap(event.source.state) end } new_check_box_menu_item{ text = "Show Whitespace" + state = text_area.whitespace_visible action_listener = function(event) - text_area.show_whitespace(event.source.state) + window.set_whitespace_visible(event.source.state) end } new_menu_item{ @@ -193,7 +204,7 @@ end local size = to_number(input) try - text_area.tab_size = size + window.set_tab_size(size) status_bar.text = "Set tab size to "..size catch e status_bar.text = "Invalid tab size: "..input
--- a/src/luan/modules/editor/window.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/editor/window.luan Thu Apr 17 18:36:27 2025 -0600 @@ -1,5 +1,6 @@ local Luan = require "luan:Luan.luan" local error = Luan.error +local stringify = Luan.stringify or error() local Math = require "luan:Math.luan" local min = Math.min or error() local String = require "luan:String.luan" @@ -19,18 +20,28 @@ local new_label = require("luan:swing/Label.luan").new or error() local make_find_panel = require "luan:editor/find.luan" local add_menu_bar = require "luan:editor/menu.luan" +local Logging = require "luan:logging/Logging.luan" +local logger = Logging.logger "editor/window" local n_windows = 0 local documents = {} +local config = { + size = { width=700, height=700 } + line_wrap = true + whitespace_visible = false + tab_size = 4 +} + local function new_window(file) local window = {} window.has_file = file~=nil and file.is_file() local text_area = new_text_area{ wrap_style_word = true - line_wrap = true - tab_size = 4 + line_wrap = config.line_wrap + whitespace_visible = config.whitespace_visible + tab_size = config.tab_size font = { family="Monospaced", size=13 } } window.text_area = text_area @@ -56,7 +67,7 @@ window.status_bar = status_bar local find_panel = make_find_panel(window) local frame = new_frame{ - preferred_size = { width=700, height=700 } + preferred_size = config.size content_pane = new_panel{ layout = new_mig_layout("insets 0,wrap,fill,hidemode 3","","[][grow 0]") children = { @@ -81,6 +92,14 @@ Luan.exit() end end) + frame.add_resize_stopped_listener( 200, function() + --logger.info(stringify(frame.size)) + config.size = frame.size + end) + frame.add_move_stopped_listener( 200, function() + --logger.info(stringify(frame.location)) + config.location = frame.location + end) local function set_title() local s = title if not text_area.document.is_unedited() then @@ -180,8 +199,23 @@ local pos = text_area.get_line_start_position(line) text_area.set_selection(pos) end + function window.set_line_wrap(line_wrap) + text_area.line_wrap = line_wrap + config.line_wrap = line_wrap + end + function window.set_whitespace_visible(whitespace_visible) + text_area.whitespace_visible = whitespace_visible + config.whitespace_visible = whitespace_visible + end + function window.set_tab_size(tab_size) + text_area.tab_size = tab_size + config.tab_size = tab_size + end add_menu_bar(window) frame.pack() + if config.location ~= nil then + frame.location = config.location + end frame.visible = true text_area.request_focus_in_window() n_windows = n_windows + 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/swing/Awt_container.luan Thu Apr 17 18:36:27 2025 -0600 @@ -0,0 +1,82 @@ +local Luan = require "luan:Luan.luan" +local error = Luan.error +local ipairs = Luan.ipairs or error() +local Utils = require "luan:swing/Utils.luan" +local fail = Utils.fail or error() +local delete = Utils.delete or error() +local check_not_nil = Utils.check_not_nil or error() +local to_dimension = Utils.to_dimension or error() +local from_dimension = Utils.from_dimension or error() +local to_point = Utils.to_point or error() +local from_point = Utils.from_point or error() +require "java" +local SwingLuan = require "java:luan.modules.swing.SwingLuan" +local newResizeListener = SwingLuan.newResizeListener +local notifyAfterResizeStops = SwingLuan.notifyAfterResizeStops +local newMoveListener = SwingLuan.newMoveListener +local notifyAfterMoveStops = SwingLuan.notifyAfterMoveStops + + +local Awt_container = {} + +function Awt_container.__index(component,key) + local jcomponent = component.java + if key == "foreground_color" then + return jcomponent.getForeground() + end + if key == "visible" then + return jcomponent.isVisible() + end + if key == "size" then + return from_dimension(jcomponent.getSize()) + end + if key == "location" then + return from_point(jcomponent.getLocation()) + end + return fail +end + +function Awt_container.__new_index(component,key,value) + local jcomponent = component.java + if key == "location" then + jcomponent.setLocation(to_point(value)) + return + end + return fail +end + +--Awt_container.mt = make_metatable(Awt_container) + +function Awt_container.construct(component,props) + check_not_nil(props) + local jcomponent = component.java + local size = delete(props,"size") + if size~=nil then jcomponent.setSize(size.width,size.height) end + local location = delete(props,"location") + if location~=nil then jcomponent.setLocation(location.x,location.y) end + local preferred_size = delete(props,"preferred_size") + if preferred_size~=nil then jcomponent.setPreferredSize(to_dimension(preferred_size)) end + function component.add(el) + jcomponent.add(el.java) + end + function component.remove(el) + jcomponent.remove(el.java) + end + function component.add_all(list) + for _, child in ipairs(list) do + jcomponent.add(child.java) + end + end + function component.add_resize_listener(fn) + jcomponent.addComponentListener(newResizeListener(fn)) + end + function component.add_resize_stopped_listener( time_after_stopped, fn ) + notifyAfterResizeStops( jcomponent, newResizeListener(fn), time_after_stopped ) + end + function component.add_move_stopped_listener( time_after_stopped, fn ) + notifyAfterMoveStops( jcomponent, newMoveListener(fn), time_after_stopped ) + end + return component +end + +return Awt_container
--- a/src/luan/modules/swing/Component.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/Component.luan Thu Apr 17 18:36:27 2025 -0600 @@ -8,8 +8,11 @@ local make_metatable = Utils.make_metatable or error() local delete = Utils.delete or error() local check_empty = Utils.check_empty or error() -local check_not_nil = Utils.check_not_nil or error() local get_font = require("luan:swing/Font.luan").get or error() +local Awt_container = require "luan:swing/Awt_container.luan" +local super__index = Awt_container.__index or error() +local super__new_index = Awt_container.__new_index or error() +local super_construct = Awt_container.construct or error() require "java" local JComponent = require "java:javax.swing.JComponent" local JPanel = require "java:javax.swing.JPanel" @@ -24,22 +27,20 @@ } function Component.__index(component,key) - if key == "foreground_color" then - return component.java.getForeground() - end + local rtn = super__index(component,key) + if rtn ~= fail then return rtn end if key == "border" then return component.java.getBorder() end if key == "constraints" then return nil end - if key == "visible" then - return component.java.isVisible() - end return fail end function Component.__new_index(component,key,value) + local rtn = super__new_index(component,key,value) + if rtn ~= fail then return end if key == "foreground_color" then component.java.setForeground(value) return @@ -59,7 +60,7 @@ Component.mt = mt local function construct(component,props) - check_not_nil(props) + super_construct(component,props) local jcomponent = component.java jcomponent.putClientProperty("luan",component) local layout = delete(props,"layout") @@ -106,17 +107,6 @@ component._dont_gc[obj] = true end component.set_layout = jcomponent.setLayout - function component.add(el) - jcomponent.add(el.java) - end - function component.remove(el) - jcomponent.remove(el.java) - end - function component.add_all(list) - for _, child in ipairs(list) do - jcomponent.add(child.java) - end - end return component end Component.construct = construct
--- a/src/luan/modules/swing/Frame.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/Frame.luan Thu Apr 17 18:36:27 2025 -0600 @@ -8,8 +8,10 @@ local make_metatable = Utils.make_metatable or error() local delete = Utils.delete or error() local check_empty = Utils.check_empty or error() -local check_not_nil = Utils.check_not_nil or error() -local to_dimension = Utils.to_dimension or error() +local Awt_container = require "luan:swing/Awt_container.luan" +local super__index = Awt_container.__index or error() +local super__new_index = Awt_container.__new_index or error() +local super_construct = Awt_container.construct or error() require "java" local JFrame = require "java:javax.swing.JFrame" local FileDialog = require "java:java.awt.FileDialog" @@ -23,9 +25,8 @@ local Frame = {} function Frame.__index(frame,key) - if key == "visible" then - return frame.java.isVisible() - end + local rtn = super__index(frame,key) + if rtn ~= fail then return rtn end if key == "title" then return frame.java.getTitle() end @@ -33,6 +34,8 @@ end function Frame.__new_index(frame,key,value) + local rtn = super__new_index(frame,key,value) + if rtn ~= fail then return end if key == "visible" then frame.java.setVisible(value) return @@ -94,21 +97,16 @@ end function Frame.new(props) - check_not_nil(props) local jframe = JFrame.new() jframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); local frame = { java = jframe } + super_construct(frame,props) local content_pane = delete(props,"content_pane") if content_pane~=nil then jframe.setContentPane(content_pane.java) end - local preferred_size = delete(props,"preferred_size") - if preferred_size~=nil then jframe.setPreferredSize(to_dimension(preferred_size)) end check_empty(props) function frame.add_close_listener(close_listener) jframe.addWindowListener(newCloseListener(close_listener)) end - function frame.add(component) - jframe.add(component.java) - end function frame.set_menu_bar(menu_bar) jframe.setJMenuBar(menu_bar.java) end
--- a/src/luan/modules/swing/SwingLuan.java Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/SwingLuan.java Thu Apr 17 18:36:27 2025 -0600 @@ -6,14 +6,19 @@ import javax.swing.Action; import javax.swing.AbstractAction; import javax.swing.JComponent; +import javax.swing.Timer; import javax.swing.text.JTextComponent; import javax.swing.text.Document; import javax.swing.undo.UndoManager; +import java.awt.Component; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.WindowListener; import java.awt.event.WindowEvent; import java.awt.event.WindowAdapter; +import java.awt.event.ComponentListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; import goodjava.logging.Logger; import goodjava.logging.LoggerFactory; import luan.Luan; @@ -81,19 +86,80 @@ public static WindowListener newCloseListener(final Luan luan,LuanFunction fn) { return new WindowAdapter() { - private void call() { + @Override public void windowClosed(WindowEvent event) { + try { + fn.call(luan); + } catch(LuanException e) { + exception(e); + } + } + }; + } + + public static ComponentListener newResizeListener(final Luan luan,LuanFunction fn) { + return new ComponentAdapter() { + @Override public void componentResized(ComponentEvent event) { try { fn.call(luan); } catch(LuanException e) { - throw new LuanRuntimeException(e); + exception(e); } } - @Override public void windowClosed(WindowEvent e) { - call(); + }; + } + + public static void notifyAfterResizeStops(Component comp,final ComponentListener cl,int timeAfterStopped) { + comp.addComponentListener( new ComponentAdapter() { + ComponentEvent event; + final Timer timer = new Timer( timeAfterStopped, new ActionListener() { + @Override public void actionPerformed(ActionEvent _e) { + cl.componentResized(event); + } + } ); + + { + timer.setRepeats(false); + } + + @Override public void componentResized(ComponentEvent event) { + this.event = event; + timer.restart(); + } + } ); + } + + public static ComponentListener newMoveListener(final Luan luan,LuanFunction fn) { + return new ComponentAdapter() { + @Override public void componentMoved(ComponentEvent event) { + try { + fn.call(luan); + } catch(LuanException e) { + exception(e); + } } }; } + public static void notifyAfterMoveStops(Component comp,final ComponentListener cl,int timeAfterStopped) { + comp.addComponentListener( new ComponentAdapter() { + ComponentEvent event; + final Timer timer = new Timer( timeAfterStopped, new ActionListener() { + @Override public void actionPerformed(ActionEvent _e) { + cl.componentMoved(event); + } + } ); + + { + timer.setRepeats(false); + } + + @Override public void componentMoved(ComponentEvent event) { + this.event = event; + timer.restart(); + } + } ); + } + public static void fixTextComponent(final JTextComponent tc) { tc.getInputMap().put(KeyStroke.getKeyStroke("meta Z"),"undo"); Action undoAction = new AbstractAction() {
--- a/src/luan/modules/swing/TextAreaLuan.java Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/TextAreaLuan.java Thu Apr 17 18:36:27 2025 -0600 @@ -79,7 +79,11 @@ return getLineHeight(line) / getRowHeight(); } - public void showWhitespace(boolean showWhitespace) { + public boolean isWhitespaceVisible() { + return showWhitespace; + } + + public void setWhitespaceVisible(boolean showWhitespace) { this.showWhitespace = showWhitespace; repaint(); }
--- a/src/luan/modules/swing/TextFieldLuan.java Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/TextFieldLuan.java Thu Apr 17 18:36:27 2025 -0600 @@ -14,7 +14,11 @@ private boolean showWhitespace = false; - public void showWhitespace(boolean showWhitespace) { + public boolean isWhitespaceVisible() { + return showWhitespace; + } + + public void setWhitespaceVisible(boolean showWhitespace) { this.showWhitespace = showWhitespace; repaint(); }
--- a/src/luan/modules/swing/Text_area.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/Text_area.luan Thu Apr 17 18:36:27 2025 -0600 @@ -22,23 +22,27 @@ function Text_area.__index(text_area,key) local rtn = super__index(text_area,key) if rtn ~= fail then return rtn end + local jtext_area = text_area.java if key == "line_wrap" then - return text_area.java.getLineWrap() + return jtext_area.getLineWrap() end if key == "wrap_style_word" then - return text_area.java.getWrapStyleWord() + return jtext_area.getWrapStyleWord() end if key == "tab_size" then - return text_area.java.getTabSize() + return jtext_area.getTabSize() end if key == "rows" then - return text_area.java.getRows() + return jtext_area.getRows() end if key == "columns" then - return text_area.java.getColumns() + return jtext_area.getColumns() end if key == "line_count" then - return text_area.java.getLineCount() + return jtext_area.getLineCount() + end + if key == "whitespace_visible" then + return jtext_area.isWhitespaceVisible() end return fail end @@ -46,24 +50,29 @@ function Text_area.__new_index(text_area,key,value) local rtn = super__new_index(text_area,key,value) if rtn ~= fail then return end + local jtext_area = text_area.java if key == "line_wrap" then - text_area.java.setLineWrap(value) + jtext_area.setLineWrap(value) return end if key == "wrap_style_word" then - text_area.java.setWrapStyleWord(value) + jtext_area.setWrapStyleWord(value) return end if key == "tab_size" then - text_area.java.setTabSize(value) + jtext_area.setTabSize(value) return end if key == "rows" then - text_area.java.setRows(value) + jtext_area.setRows(value) return end if key == "columns" then - text_area.java.setColumns(value) + jtext_area.setColumns(value) + return + end + if key == "whitespace_visible" then + jtext_area.setWhitespaceVisible(value) return end return fail @@ -85,8 +94,9 @@ if line_wrap~=nil then jtext_area.setLineWrap(line_wrap) end local tab_size = delete(props,"tab_size") if tab_size~=nil then jtext_area.setTabSize(tab_size) end + local whitespace_visible = delete(props,"whitespace_visible") + if whitespace_visible~=nil then jtext_area.setWhitespaceVisible(whitespace_visible) end check_empty(props) - text_area.show_whitespace = jtext_area.showWhitespace function text_area.get_line_from_position(pos) return jtext_area.getLineOfOffset(pos-1) + 1 end
--- a/src/luan/modules/swing/Text_field.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/Text_field.luan Thu Apr 17 18:36:27 2025 -0600 @@ -27,8 +27,8 @@ if action~=nil then jtext_field.setActionCommand(action) end local action_listener = delete(props,"action_listener") if action_listener~=nil then jtext_field.addActionListener(newActionListener(action_listener)) end - local show_whitespace = delete(props,"show_whitespace") - if show_whitespace~=nil then jtext_field.showWhitespace(show_whitespace) end + local whitespace_visible = delete(props,"whitespace_visible") + if whitespace_visible~=nil then jtext_field.setWhitespaceVisible(whitespace_visible) end check_empty(props) set_metatable(text_field,super_mt) return text_field
--- a/src/luan/modules/swing/Utils.luan Wed Apr 16 22:16:42 2025 -0600 +++ b/src/luan/modules/swing/Utils.luan Thu Apr 17 18:36:27 2025 -0600 @@ -7,6 +7,7 @@ local is_empty = Table.is_empty or error() require "java" local Dimension = require "java:java.awt.Dimension" +local Point = require "java:java.awt.Point" local Utils = {} @@ -58,4 +59,18 @@ return Dimension.new(width,height) end +function Utils.from_dimension(dim) + return { width=dim.width, height=dim.height } +end + +function Utils.to_point(tbl) + local x = tbl.x or error "missing x" + local y = tbl.y or error "missing y" + return Point.new(x,y) +end + +function Utils.from_point(point) + return { x=point.x, y=point.y } +end + return Utils