From 8c423c7a05215ef10cd209113b3473bccb058c4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thorsten=20Wi=C3=9Fmann?= <uni@thorsten-wissmann.de>
Date: Sun, 27 Jul 2014 19:43:19 +0200
Subject: [PATCH] Add curses painting basics

---
 _oasis                           |  2 +-
 src/ncurses/Curses.ml            |  1 +
 src/ncurses/Curses.mli           |  1 +
 src/ncurses/Curses_stub.c        | 12 ++++++
 src/ncurses/NCUI.ml              | 70 ++++++++++++++++++++++++++++++++
 src/ncurses/NCUI.mli             | 28 +++++++++++++
 src/repl-example/repl-example.ml |  8 +++-
 7 files changed, 120 insertions(+), 2 deletions(-)
 create mode 100644 src/ncurses/NCUI.ml
 create mode 100644 src/ncurses/NCUI.mli

diff --git a/_oasis b/_oasis
index 9c0c415..8fb6893 100644
--- a/_oasis
+++ b/_oasis
@@ -88,7 +88,7 @@ Library interfacencurses
   CCOpt: -std=c++98 -x c++
   CSources:         Curses_stub.c, Readline_stub.c
   #InternalModules:
-  Modules:          Curses, Readline
+  Modules:          Curses, Readline, NCUI
 
 Executable coalg
   CompiledObject:   native
diff --git a/src/ncurses/Curses.ml b/src/ncurses/Curses.ml
index 066502b..e29f596 100644
--- a/src/ncurses/Curses.ml
+++ b/src/ncurses/Curses.ml
@@ -13,4 +13,5 @@ external addch: char -> unit = "curses_addch"
 external mvwaddch: window -> int -> int -> char -> unit = "curses_mvwaddch"
 external addstr: string -> unit = "curses_addstr"
 external mvwaddstr: window -> int -> int -> string -> unit = "curses_mvwaddstr"
+external getmaxyx: window -> int * int = "curses_getmaxyx"
 
diff --git a/src/ncurses/Curses.mli b/src/ncurses/Curses.mli
index ba96dc5..ac9b369 100644
--- a/src/ncurses/Curses.mli
+++ b/src/ncurses/Curses.mli
@@ -12,3 +12,4 @@ val addch: char -> unit
 val mvwaddch: window -> int -> int -> char -> unit
 val addstr: string -> unit
 val mvwaddstr: window -> int -> int -> string -> unit
+val getmaxyx: window -> int * int
diff --git a/src/ncurses/Curses_stub.c b/src/ncurses/Curses_stub.c
index af4a03f..39ee0c0 100644
--- a/src/ncurses/Curses_stub.c
+++ b/src/ncurses/Curses_stub.c
@@ -100,4 +100,16 @@ value curses_mvwaddstr(value win, value x, value y, value s)
   CAMLreturn (Val_unit);
 }
 
+value curses_getmaxyx(value win)
+{
+  CAMLparam1 (win);
+  int h, w;
+  CAMLlocal1( hw );
+  hw = caml_alloc(2, 0);
+  getmaxyx(Window_val(win), h, w);
+  Store_field( hw, 0, Val_int(h) );
+  Store_field( hw, 1, Val_int(w) );
+  CAMLreturn ( hw );
+}
+
 }
diff --git a/src/ncurses/NCUI.ml b/src/ncurses/NCUI.ml
new file mode 100644
index 0000000..eb64745
--- /dev/null
+++ b/src/ncurses/NCUI.ml
@@ -0,0 +1,70 @@
+(* a simple NCurses UI Library *)
+open Curses
+
+type point = int * int (* x and y *)
+
+type buffer = string list
+
+exception ScreenNotOpen
+exception NoRootWidget
+
+type 'a member = {
+    set : 'a -> unit;
+    get : unit -> 'a
+}
+
+type widget = {
+    minSize: point member;
+    paint: point -> buffer;
+}
+
+let member_init (v: 'a): 'a member =
+    let pointer = ref (v) in
+    {
+        set = (fun n -> pointer := v);
+        get = (fun () -> !pointer);
+    }
+
+let label str = {
+        minSize = member_init (0,0);
+        paint = (fun (w,h) -> [ str ]);
+    }
+
+let root_widget : widget option ref = ref (None)
+
+let get_root_widget () : widget =
+    match (!root_widget) with
+    | None -> raise NoRootWidget
+    | Some x -> x
+
+let stdscr : window option ref = ref (None)
+
+let screen_open  () =
+    stdscr := Some (initscr ())
+
+let get_stdscr () =
+    match (!stdscr) with
+    | None -> raise ScreenNotOpen
+    | Some x -> x
+
+let screen_close () =
+    stdscr := None;
+    endwin ()
+
+let paint_widget (wid:widget) ((x,y):point) (size: point) =
+    let stdscr = get_stdscr () in
+    let lines = wid.paint size in
+    let paint i str =
+        mvwaddstr stdscr (y+i) x str
+    in
+    List.iteri paint lines
+
+let update () =
+    let h, w = getmaxyx (get_stdscr ()) in
+    paint_widget (get_root_widget()) (0,0) (w,h);
+    refresh()
+
+let set_root_widget widget =
+    root_widget := Some widget;
+    update()
+
diff --git a/src/ncurses/NCUI.mli b/src/ncurses/NCUI.mli
new file mode 100644
index 0000000..a67d16c
--- /dev/null
+++ b/src/ncurses/NCUI.mli
@@ -0,0 +1,28 @@
+(* a simple NCurses UI Library *)
+
+type point = int * int (* x and y *)
+
+type buffer = string list
+
+exception ScreenNotOpen
+exception NoRootWidget
+
+
+type 'a member = {
+    set : 'a -> unit;
+    get : unit -> 'a
+}
+
+type widget = {
+    minSize: point member;
+    paint: point -> buffer;
+}
+
+val member_init : 'a -> 'a member
+val label: string -> widget
+
+val update : unit -> unit
+val set_root_widget : widget -> unit
+val screen_open  : unit -> unit
+val screen_close : unit -> unit
+
diff --git a/src/repl-example/repl-example.ml b/src/repl-example/repl-example.ml
index 5f93561..e87f607 100644
--- a/src/repl-example/repl-example.ml
+++ b/src/repl-example/repl-example.ml
@@ -22,4 +22,10 @@ let main2 () =
   register_redraw redraw ;
   Readline.readline()
 
-let _ = main2 ()
+let main3 () =
+    NCUI.screen_open();
+    NCUI.set_root_widget (NCUI.label "HALLOOOO");
+    Unix.sleep 3;
+    NCUI.screen_close()
+
+let _ = main3 ()
-- 
GitLab