From 0c412c10e4d9c4e033c5a14760482825f0b48035 Mon Sep 17 00:00:00 2001 From: "Glenn Y. Rolland" Date: Sat, 2 Jan 2021 16:24:18 +0100 Subject: [PATCH] Implement a simple demo with Ncurses --- src/lib/cli.cr | 33 +++++++++-- src/lib/gui.cr | 40 -------------- src/lib/tui.cr | 88 +++++++++++++++++++++++++++++ src/main.cr | 147 ++++++++++++++++++++++++------------------------- 4 files changed, 187 insertions(+), 121 deletions(-) delete mode 100644 src/lib/gui.cr create mode 100644 src/lib/tui.cr diff --git a/src/lib/cli.cr b/src/lib/cli.cr index 7f8985c..fbc3af4 100644 --- a/src/lib/cli.cr +++ b/src/lib/cli.cr @@ -1,13 +1,34 @@ +require "clim" + +require "./tui" + module Noozoid - class Cli < Thor + class Cli < Clim + main do + desc "Happy Send - Mass send short text messages via your smartphone + kdeconnect" - desc 'gui', 'Start ncurses GUI' - def gui - Gui.start + usage "happy-send [options] [arguments] ..." + + option "-v", "--verbose", + type: Bool, + default: false, + desc: "Enable debug messages" + + option "-c FILE", "--csv=FILE", + type: String, + required: false, + desc: "Use given CSV (mandatory fields: number,message)" + + run do |opts, args| + Log.setup(:warn) + Log.setup(:debug) if opts.verbose + + app = Noozoid::Tui.new + app.run + # app = HappyApp.new(csv: opts.csv, send: opts.send, wait: opts.wait) + end end - - default_task :gui end end diff --git a/src/lib/gui.cr b/src/lib/gui.cr deleted file mode 100644 index 294d798..0000000 --- a/src/lib/gui.cr +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -module Noozoid - # Gui - module Gui - # app - class App - def initialize - @tree = Noozoid::Models::Node.new('untitled') - end - - def run - Curses.noecho - Curses.nonl - Curses.stdscr.keypad(true) - # Curses.raw - # Curses.stdscr.nodelay = 1 - Curses.curs_set(0) - # Curses.start_color - Curses.init_screen - Curses.refresh - - # attach models to views - @main_window = MainView.new(self) - @main_window.draw - @main_window.wait - - rescue StandardError => e - Curses.close_screen - warn e.message unless e.nil? - warn e.backtrace unless e.nil? - end - end - - def self.start - app = App.new - app.run - end - end -end diff --git a/src/lib/tui.cr b/src/lib/tui.cr new file mode 100644 index 0000000..0646423 --- /dev/null +++ b/src/lib/tui.cr @@ -0,0 +1,88 @@ + +require "ncurses" + +module Noozoid + class Tui + def initialize + #@tree = Noozoid::Models::Node.new('untitled') + end + + def run + # initialize + NCurses.init + NCurses.cbreak + NCurses.noecho + NCurses.keypad(true) + NCurses.start_color + + # define background color + pair = NCurses::ColorPair.new(1).init(NCurses::Color::RED, NCurses::Color::BLACK) + NCurses.bkgd(pair) + NCurses.curs_set(0) + + NCurses.erase + + # move the cursor & write + NCurses.move(x:0, y: 1) + NCurses.addstr(NCurses.longname) + + + NCurses.move(x:0, y: 2) + NCurses.addstr(NCurses.curses_version) + + + # attach models to views + #@main_window = MainView.new(self) + #@main_window.draw + #@main_window.wait + + NCurses.notimeout(true) + + x = NCurses.maxx / 2 + y = NCurses.maxy / 2 + + loop do + NCurses.erase + NCurses.move(x: x, y: y) + NCurses.addstr("o") + NCurses.refresh + + key = NCurses.getch + + case key + when 'q', NCurses::KeyCode::ESC + break + + when NCurses::KeyCode::LEFT + x -= 1 + x = 0 if x < 0 + + when NCurses::KeyCode::RIGHT + x += 1 + x = NCurses.maxx - 1 if x >= NCurses.maxx + + when NCurses::KeyCode::UP + y -= 1 + y = 0 if y < 0 + + when NCurses::KeyCode::DOWN + y += 1 + y = NCurses.maxy - 2 if y >= NCurses.maxy - 1 + + end + end + + NCurses.endwin + + #rescue StandardError => e + #Curses.close_screen + #warn e.message unless e.nil? + #warn e.backtrace unless e.nil? + end + end + + def self.start + app = App.new + app.run + end +end diff --git a/src/main.cr b/src/main.cr index a657c0b..f47cdc7 100755 --- a/src/main.cr +++ b/src/main.cr @@ -1,81 +1,78 @@ -#!/usr/bin/env ruby -# Usage: -# - Start new mindmap: -# `ruby ttymindmap.rb` -# - Open Freemind format MM mindmap: -# `ruby ttymindmap.rb ` -# -# Press `h` key when running for help. -require 'noozoid' +require "log" +require "./lib/cli" + +LOG = ::Log.for("noozoid") +#LOG = Logger.new(STDOUT, level: Logger::WARN) Noozoid::Cli.start(ARGV) exit 0 -def print_help - puts '= Commands =' - puts '' - puts '- Navigation -' - puts "#{KEYS[:nav_parent]}: go to parent node" - puts "#{KEYS[:nav_child]}: go to children node" - puts "#{KEYS[:nav_previous]}: previous sibling" - puts "#{KEYS[:nav_next]}: next sibling" - puts '' - puts "- Action -" - puts "#{KEYS[:node_create]}: create child node" - puts "#{KEYS[:node_delete]}: remove node" - puts "#{KEYS[:node_toggle]}: toggle" - puts '' - puts "- Misc -" - puts "#{KEYS[:main_help]}: show this help" - puts "#{KEYS[:main_quit]}: exit program" - puts '[press a key to continue]' - read_command -end - -def read_command - system("stty raw -echo") #=> Raw mode, no echo - char = STDIN.getc - system("stty -raw echo") #=> Reset terminal mode - char -end - -if ARGV.empty? - print 'Mindmap name: ' - current = root = Node.new(STDIN.gets.chomp) -end - -loop do - print `clear` - PrettyPrint.tree(root, current) - - cmd = read_command - - if cmd == KEYS[:node_create] - print 'Title: ' - current[] = Node.new(STDIN.gets.chomp) - elsif cmd == KEYS[:node_delete] - current.remove - current = current.parent unless current.parent.nil? - elsif cmd == KEYS[:node_toggle] - current.toggle! - elsif cmd == KEYS[:nav_child] - current = current[0] if current.children? - elsif cmd == KEYS[:nav_parent] - current = current.parent unless current.parent.nil? - elsif cmd == KEYS[:nav_previous] - sibling = current >> -1 - current = sibling unless sibling.nil? - elsif cmd == KEYS[:nav_next] - sibling = current >> 1 - current = sibling unless sibling.nil? - elsif cmd == KEYS[:nav_root] - current = root - elsif cmd == KEYS[:main_help] - print_help - elsif cmd == KEYS[:main_quit] - puts 'Good Bye!' - break - end -end +# def print_help +# puts '= Commands =' +# puts '' +# puts '- Navigation -' +# puts "#{KEYS[:nav_parent]}: go to parent node" +# puts "#{KEYS[:nav_child]}: go to children node" +# puts "#{KEYS[:nav_previous]}: previous sibling" +# puts "#{KEYS[:nav_next]}: next sibling" +# puts '' +# puts "- Action -" +# puts "#{KEYS[:node_create]}: create child node" +# puts "#{KEYS[:node_delete]}: remove node" +# puts "#{KEYS[:node_toggle]}: toggle" +# puts '' +# puts "- Misc -" +# puts "#{KEYS[:main_help]}: show this help" +# puts "#{KEYS[:main_quit]}: exit program" +# puts '[press a key to continue]' +# read_command +# end +# +# def read_command +# system("stty raw -echo") #=> Raw mode, no echo +# char = STDIN.getc +# system("stty -raw echo") #=> Reset terminal mode +# char +# end +# +# if ARGV.empty? +# print 'Mindmap name: ' +# current = root = Node.new(STDIN.gets.chomp) +# end +# +# loop do +# print `clear` +# PrettyPrint.tree(root, current) +# +# cmd = read_command +# +# if cmd == KEYS[:node_create] +# print 'Title: ' +# current[] = Node.new(STDIN.gets.chomp) +# elsif cmd == KEYS[:node_delete] +# current.remove +# current = current.parent unless current.parent.nil? +# elsif cmd == KEYS[:node_toggle] +# current.toggle! +# elsif cmd == KEYS[:nav_child] +# current = current[0] if current.children? +# elsif cmd == KEYS[:nav_parent] +# current = current.parent unless current.parent.nil? +# elsif cmd == KEYS[:nav_previous] +# sibling = current >> -1 +# current = sibling unless sibling.nil? +# elsif cmd == KEYS[:nav_next] +# sibling = current >> 1 +# current = sibling unless sibling.nil? +# elsif cmd == KEYS[:nav_root] +# current = root +# elsif cmd == KEYS[:main_help] +# print_help +# elsif cmd == KEYS[:main_quit] +# puts 'Good Bye!' +# break +# end +# end +#