From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001
From: Jari Vetoniemi <jari.vetoniemi@indooratlas.com>
Date: Mon, 16 Mar 2020 18:49:26 +0900
Subject: Fresh start

---
 jni/ruby/ext/tk/sample/demos-jp/rmt | 268 ++++++++++++++++++++++++++++++++++++
 1 file changed, 268 insertions(+)
 create mode 100644 jni/ruby/ext/tk/sample/demos-jp/rmt

(limited to 'jni/ruby/ext/tk/sample/demos-jp/rmt')

diff --git a/jni/ruby/ext/tk/sample/demos-jp/rmt b/jni/ruby/ext/tk/sample/demos-jp/rmt
new file mode 100644
index 0000000..dcfb328
--- /dev/null
+++ b/jni/ruby/ext/tk/sample/demos-jp/rmt
@@ -0,0 +1,268 @@
+#!/usr/bin/env ruby
+
+# rmt --
+# This script implements a simple remote-control mechanism for
+# Tk applications.  It allows you to select an application and
+# then type commands to that application.
+
+require 'tk'
+
+class Rmt
+  def initialize(parent=nil)
+    win = self
+
+    unless parent
+      parent = TkRoot.new
+    end
+    root = TkWinfo.toplevel(parent)
+    root.minsize(1,1)
+
+    # The instance variable below keeps track of the remote application
+    # that we're sending to.  If it's an empty string then we execute
+    # the commands locally.
+    @app = 'local'
+    @mode = 'Ruby'
+
+    # The instance variable below keeps track of whether we're in the
+    # middle of executing a command entered via the text.
+    @executing = 0
+
+    # The instance variable below keeps track of the last command executed,
+    # so it can be re-executed in response to !! commands.
+    @lastCommand = ""
+
+    # Create menu bar.  Arrange to recreate all the information in the
+    # applications sub-menu whenever it is cascaded to.
+
+    TkFrame.new(root, 'relief'=>'raised', 'bd'=>2) {|f|
+      pack('side'=>'top', 'fill'=>'x')
+      TkMenubutton.new(f, 'text'=>'File', 'underline'=>0) {|mb|
+	TkMenu.new(mb) {|mf|
+	  mb.menu(mf)
+	  TkMenu.new(mf) {|ma|
+	    postcommand proc{win.fillAppsMenu ma}
+	    mf.add('cascade', 'label'=>'Select Application',
+		   'menu'=>ma, 'underline'=>0)
+	  }
+	  add('command', 'label'=>'Quit',
+	      'command'=>proc{root.destroy}, 'underline'=>0)
+	}
+	pack('side'=>'left')
+      }
+    }
+
+    # Create text window and scrollbar.
+
+    @txt = TkText.new(root, 'relief'=>'sunken', 'bd'=>2, 'setgrid'=>true) {
+      yscrollbar(TkScrollbar.new(root){pack('side'=>'right', 'fill'=>'y')})
+      pack('side'=>'left')
+    }
+
+    @promptEnd = TkTextMark.new(@txt, 'insert')
+
+    # Create a binding to forward commands to the target application,
+    # plus modify many of the built-in bindings so that only information
+    # in the current command can be deleted (can still set the cursor
+    # earlier in the text and select and insert;  just can't delete).
+
+    @txt.bindtags([@txt, TkText, root, 'all'])
+    @txt.bind('Return', proc{
+		@txt.set_insert('end - 1c')
+		@txt.insert('insert', "\n")
+		win.invoke
+		Tk.callback_break
+	      })
+    @txt.bind('Delete', proc{
+		begin
+		  @txt.tag_remove('sel', 'sel.first', @promptEnd)
+		rescue
+		end
+		if @txt.tag_nextrange('sel', '1.0', 'end') == []
+		  if @txt.compare('insert', '<', @promptEnd)
+		    Tk.callback_break
+		  end
+		end
+	      })
+    @txt.bind('BackSpace', proc{
+		begin
+		  @txt.tag_remove('sel', 'sel.first', @promptEnd)
+		rescue
+		end
+		if @txt.tag_nextrange('sel', '1.0', 'end') == []
+		  if @txt.compare('insert', '<', @promptEnd)
+		    Tk.callback_break
+		  end
+		end
+	      })
+    @txt.bind('Control-d', proc{
+		if @txt.compare('insert', '<', @promptEnd)
+		  Tk.callback_break
+		end
+	      })
+    @txt.bind('Control-k', proc{
+		if @txt.compare('insert', '<', @promptEnd)
+		  @txt.set_insert(@promptEnd)
+		end
+	      })
+    @txt.bind('Control-t', proc{
+		if @txt.compare('insert', '<', @promptEnd)
+		  Tk.callback_break
+		end
+	      })
+    @txt.bind('Meta-d', proc{
+		if @txt.compare('insert', '<', @promptEnd)
+		  Tk.callback_break
+		end
+	      })
+    @txt.bind('Meta-BackSpace', proc{
+		if @txt.compare('insert', '<=', @promptEnd)
+		  Tk.callback_break
+		end
+	      })
+    @txt.bind('Control-h', proc{
+		if @txt.compare('insert', '<=', @promptEnd)
+		  Tk.callback_break
+		end
+	      })
+
+    @txt.tag_configure('bold', 'font'=>['Courier', 12, 'bold'])
+
+    @app = Tk.appname('rmt')
+    if (@app =~ /^rmt(.*)$/)
+      root.title("Tk Remote Controller#{$1}")
+      root.iconname("Tk Remote#{$1}")
+    end
+    prompt
+    @txt.focus
+    #@app = TkWinfo.appname(TkRoot.new)
+  end
+
+  def tkTextInsert(w,s)
+    return if s == ""
+    begin
+      if w.compare('sel.first','<=','insert') \
+	&& w.compare('sel.last','>=','insert')
+	w.tag_remove('sel', 'sel.first', @promptEnd)
+	w.delete('sel.first', 'sel.last')
+      end
+    rescue
+    end
+    w.insert('insert', s)
+    w.see('insert')
+  end
+
+  # The method below is used to print out a prompt at the
+  # insertion point (which should be at the beginning of a line
+  # right now).
+
+  def prompt
+    @txt.insert('insert', "#{@app}: ")
+    @promptEnd.set('insert')
+    @promptEnd.gravity = 'left'
+    @txt.tag_add('bold', "#{@promptEnd.path} linestart", @promptEnd)
+  end
+
+  # The method below executes a command (it takes everything on the
+  # current line after the prompt and either sends it to the remote
+  # application or executes it locally, depending on "app".
+
+  def invoke
+    cmd = @txt.get(@promptEnd, 'insert')
+    @executing += 1
+    case (@mode)
+    when 'Tcl'
+      if Tk.info('complete', cmd)
+	if (cmd == "!!\n")
+	  cmd = @lastCommand
+	else
+	  @lastCommand = cmd
+	end
+	begin
+	  msg = Tk.appsend(@app, false, cmd)
+	rescue
+	  msg = "Error: #{$!}"
+	end
+	@txt.insert('insert', msg + "\n") if msg != ""
+	prompt
+	@promptEnd.set('insert')
+      end
+
+    when 'Ruby'
+      if (cmd == "!!\n")
+	cmd = @lastCommand
+      end
+      complete = true
+      begin
+	eval("proc{#{cmd}}")
+      rescue
+	complete = false
+      end
+      if complete
+	@lastCommand = cmd
+	begin
+#	  msg = Tk.appsend(@app, false,
+#			   'ruby',
+#			   '"(' + cmd.gsub(/[][$"]/, '\\\\\&') + ').to_s"')
+	  msg = Tk.rb_appsend(@app, false, cmd)
+	rescue
+	  msg = "Error: #{$!}"
+	end
+	@txt.insert('insert', msg + "\n") if msg != ""
+	prompt
+	@promptEnd.set('insert')
+      end
+    end
+
+    @executing -= 1
+    @txt.yview_pickplace('insert')
+  end
+
+  # The following method is invoked to change the application that
+  # we're talking to.  It also updates the prompt for the current
+  # command, unless we're in the middle of executing a command from
+  # the text item (in which case a new prompt is about to be output
+  # so there's no need to change the old one).
+
+  def newApp(appName, mode)
+    @app = appName
+    @mode = mode
+    if @executing == 0
+      @promptEnd.gravity = 'right'
+      @txt.delete("#{@promptEnd.path} linestart", @promptEnd)
+      @txt.insert(@promptEnd, "#{appName}: ")
+      @txt.tag_add('bold', "#{@promptEnd.path} linestart", @promptEnd)
+      @promptEnd.gravity = 'left'
+    end
+  end
+
+  # The method below will fill in the applications sub-menu with a list
+  # of all the applications that currently exist.
+
+  def fillAppsMenu(menu)
+    win = self
+    begin
+      menu.delete(0,'last')
+    rescue
+    end
+    TkWinfo.interps.sort.each{|ip|
+      begin
+	if Tk.appsend(ip, false, 'info commands ruby') == ""
+	  mode = 'Tcl'
+	else
+	  mode = 'Ruby'
+	end
+	menu.add('command', 'label'=>format("%s    (#{mode}/Tk)", ip),
+		 'command'=>proc{win.newApp ip, mode})
+      rescue
+	menu.add('command', 'label'=>format("%s (unknown Tk)", ip),
+		 'command'=>proc{win.newApp ip, mode}, 'state'=>'disabled')
+      end
+    }
+    menu.add('command', 'label'=>format("local    (Ruby/Tk)"),
+	     'command'=>proc{win.newApp 'local', 'Ruby'})
+  end
+end
+
+Rmt.new
+
+Tk.mainloop
-- 
cgit v1.2.3-70-g09d2