]> git.mdlowis.com Git - archive/tide-ocaml.git/commitdiff
updated drawing code to draw scrollbar thumb based on visible part of the file
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 10 Nov 2017 02:47:10 +0000 (21:47 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 10 Nov 2017 02:47:10 +0000 (21:47 -0500)
13 files changed:
docs/Buf.html
docs/Draw.Cursor.html
docs/Draw.html
docs/Rope.html
docs/index_values.html
docs/type_Draw.Cursor.html
edit.ml
lib/buf.ml
lib/buf.mli
lib/draw.ml
lib/draw.mli
lib/rope.ml
lib/x11_prims.c

index e7943e79d63836d161e9d2c7f0d1b0788c40b1a7..f2246c7e002086f3c734791e0836c23aabc69833 100644 (file)
@@ -99,6 +99,7 @@
 
 <pre><span id="VALempty"><span class="keyword">val</span> empty</span> : <code class="type"><a href="Buf.html#TYPEbuf">buf</a></code></pre>
 <pre><span id="VALload"><span class="keyword">val</span> load</span> : <code class="type">string -> <a href="Buf.html#TYPEbuf">buf</a></code></pre>
+<pre><span id="VALlength"><span class="keyword">val</span> length</span> : <code class="type"><a href="Buf.html#TYPEbuf">buf</a> -> int</code></pre>
 <pre><span id="VALiteri"><span class="keyword">val</span> iteri</span> : <code class="type">(int -> <a href="Rope.html#TYPErune">Rope.rune</a> -> bool) -> <a href="Buf.html#TYPEbuf">buf</a> -> int -> unit</code></pre>
 <pre><span id="VALiter"><span class="keyword">val</span> iter</span> : <code class="type">(<a href="Rope.html#TYPErune">Rope.rune</a> -> bool) -> <a href="Buf.html#TYPEbuf">buf</a> -> int -> unit</code></pre>
 <pre><span class="keyword">module</span> <a href="Buf.Cursor.html">Cursor</a>: <code class="code">sig</code> <a href="Buf.Cursor.html">..</a> <code class="code">end</code></pre>
index d2fe5f0a947e7e1e50433c3a362d528eca454692..20875f9cf2e04142ab4c451fc47d69ef7406bbf6 100644 (file)
@@ -73,6 +73,8 @@
 
 
 <pre><span id="VALmake"><span class="keyword">val</span> make</span> : <code class="type">int * int -> int -> int -> <a href="Draw.Cursor.html#TYPEt">t</a></code></pre>
+<pre><span id="VALclone"><span class="keyword">val</span> clone</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">t</a> -> <a href="Draw.Cursor.html#TYPEt">t</a></code></pre>
+<pre><span id="VALmove_x"><span class="keyword">val</span> move_x</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">t</a> -> int -> unit</code></pre>
 <pre><span id="VALmax_width"><span class="keyword">val</span> max_width</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">t</a> -> int</code></pre>
 <pre><span id="VALrestart"><span class="keyword">val</span> restart</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">t</a> -> int -> int -> <a href="Draw.Cursor.html#TYPEt">t</a></code></pre>
 <pre><span id="VALnext_line"><span class="keyword">val</span> next_line</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">t</a> -> unit</code></pre>
index 0bfe7fa5d54a1744043387954ffc8e2a1d205a9b..867004a7f0d576a42e86b05799d4297e7e759403 100644 (file)
@@ -42,8 +42,8 @@
 <pre><span id="VALstring"><span class="keyword">val</span> string</span> : <code class="type">string -> <a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> unit</code></pre>
 <pre><span id="VALhrule"><span class="keyword">val</span> hrule</span> : <code class="type">int -> <a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> unit</code></pre>
 <pre><span id="VALvrule"><span class="keyword">val</span> vrule</span> : <code class="type">int -> <a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> unit</code></pre>
-<pre><span id="VALbuffer"><span class="keyword">val</span> buffer</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> <a href="Buf.html#TYPEt">Buf.t</a> -> int -> unit</code></pre>
+<pre><span id="VALbuffer"><span class="keyword">val</span> buffer</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> <a href="Buf.html#TYPEt">Buf.t</a> -> int -> int</code></pre>
 <pre><span id="VALstatus"><span class="keyword">val</span> status</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> string -> unit</code></pre>
 <pre><span id="VALtags"><span class="keyword">val</span> tags</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> 'a -> unit</code></pre>
-<pre><span id="VALscroll"><span class="keyword">val</span> scroll</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> unit</code></pre>
-<pre><span id="VALedit"><span class="keyword">val</span> edit</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> <a href="Buf.html#TYPEt">Buf.t</a> -> int -> unit</code></pre></body></html>
\ No newline at end of file
+<pre><span id="VALscroll"><span class="keyword">val</span> scroll</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> float -> unit</code></pre>
+<pre><span id="VALedit"><span class="keyword">val</span> edit</span> : <code class="type"><a href="Draw.Cursor.html#TYPEt">Cursor.t</a> -> <a href="Buf.html#TYPEt">Buf.t</a> -> int -> int</code></pre></body></html>
\ No newline at end of file
index 56ebad42bdcdfd7d8fc1146e39d9261cf1520213..cd7d93a9db56414e263a9f80b1ac213331d6e8f8 100644 (file)
@@ -62,7 +62,6 @@
 <pre><span id="VALlength"><span class="keyword">val</span> length</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> int</code></pre>
 <pre><span id="VALheight"><span class="keyword">val</span> height</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> int</code></pre>
 <pre><span id="VALis_leaf"><span class="keyword">val</span> is_leaf</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> bool</code></pre>
-<pre><span id="VALis_leaf"><span class="keyword">val</span> is_leaf</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> bool</code></pre>
 <pre><span id="VALlimit_index"><span class="keyword">val</span> limit_index</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> int -> int</code></pre>
 <pre><span id="VALlast"><span class="keyword">val</span> last</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> int</code></pre>
 <pre><span id="VALcheck_index"><span class="keyword">val</span> check_index</span> : <code class="type"><a href="Rope.html#TYPEt">t</a> -> int -> unit</code></pre>
index 05bcc0c0919416966c691b05b0994ceffe8e817c..8e3364121706f7eff4331c1a490d9859538e5368 100644 (file)
@@ -41,6 +41,8 @@
 <td></td></tr>
 <tr><td><a href="Rope.html#VALcheck_index">check_index</a> [<a href="Rope.html">Rope</a>]</td>
 <td></td></tr>
+<tr><td><a href="Draw.Cursor.html#VALclone">clone</a> [<a href="Draw.Cursor.html">Draw.Cursor</a>]</td>
+<td></td></tr>
 <tr><td><a href="Buf.Cursor.html#VALclone">clone</a> [<a href="Buf.Cursor.html">Buf.Cursor</a>]</td>
 <td></td></tr>
 <tr><td><a href="Cfg.html#VALclrvar">clrvar</a> [<a href="Cfg.html">Cfg</a>]</td>
 <tr><td align="left"><br>L</td></tr>
 <tr><td><a href="Rope.html#VALlast">last</a> [<a href="Rope.html">Rope</a>]</td>
 <td></td></tr>
+<tr><td><a href="Buf.html#VALlength">length</a> [<a href="Buf.html">Buf</a>]</td>
+<td></td></tr>
 <tr><td><a href="Rope.html#VALlength">length</a> [<a href="Rope.html">Rope</a>]</td>
 <td></td></tr>
 <tr><td><a href="Draw.html#VALlight_bkg">light_bkg</a> [<a href="Draw.html">Draw</a>]</td>
 <td></td></tr>
 <tr><td><a href="Buf.html#VALmove_to">move_to</a> [<a href="Buf.html">Buf</a>]</td>
 <td></td></tr>
+<tr><td><a href="Draw.Cursor.html#VALmove_x">move_x</a> [<a href="Draw.Cursor.html">Draw.Cursor</a>]</td>
+<td></td></tr>
 <tr><td align="left"><br>N</td></tr>
 <tr><td><a href="Draw.Cursor.html#VALnext_glyph">next_glyph</a> [<a href="Draw.Cursor.html">Draw.Cursor</a>]</td>
 <td></td></tr>
index 060e5144db453e2df7cb7c37db2c58621e0bdee7..c98866dd0f6a8706181c6a46ca13eb9a3e746d91 100644 (file)
@@ -26,6 +26,8 @@
 &nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">mutable</span>&nbsp;y&nbsp;:&nbsp;int;<br>
 &nbsp;&nbsp;}<br>
 &nbsp;&nbsp;<span class="keyword">val</span>&nbsp;make&nbsp;:&nbsp;int&nbsp;*&nbsp;int&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;int&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;int&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t<br>
+&nbsp;&nbsp;<span class="keyword">val</span>&nbsp;clone&nbsp;:&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t<br>
+&nbsp;&nbsp;<span class="keyword">val</span>&nbsp;move_x&nbsp;:&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;int&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;unit<br>
 &nbsp;&nbsp;<span class="keyword">val</span>&nbsp;max_width&nbsp;:&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;int<br>
 &nbsp;&nbsp;<span class="keyword">val</span>&nbsp;restart&nbsp;:&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;int&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;int&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t<br>
 &nbsp;&nbsp;<span class="keyword">val</span>&nbsp;next_line&nbsp;:&nbsp;<span class="constructor">Draw</span>.<span class="constructor">Cursor</span>.t&nbsp;<span class="keywordsign">-&gt;</span>&nbsp;unit<br>
diff --git a/edit.ml b/edit.ml
index 1b3b4cc87d6a591f7ec0e4ca27d9fa9c1ae49cb8..b53ba942506c3058164c66d3e65cdb88177ab2cc 100644 (file)
--- a/edit.ml
+++ b/edit.ml
@@ -1,10 +1,14 @@
 open X11
 
 module View = struct
-  type t = { buf : Buf.t; map : Scrollmap.t }
+  type t = {
+    num : int;
+    buf : Buf.t;
+    map : Scrollmap.t
+  }
 
   let from_buffer buf width height =
-    { buf = buf; map = Scrollmap.make buf width 0 }
+    { num = 0; buf = buf; map = Scrollmap.make buf width 0 }
 
   let empty width height =
     from_buffer (Buf.empty) width height
@@ -17,14 +21,18 @@ module View = struct
 
   let draw view csr =
     let view = (resize view (Draw.Cursor.max_width csr)) in
-    Draw.buffer csr view.buf (Scrollmap.first view.map);
-    view
+    let num = Draw.buffer csr view.buf (Scrollmap.first view.map) in
+    { view with num = num }
 
   let scroll_up view =
     { view with map = Scrollmap.scroll_up view.map view.buf }
 
   let scroll_dn view =
     { view with map = Scrollmap.scroll_dn view.map view.buf }
+
+  let visible view =
+    (float_of_int view.num) /. (float_of_int (Buf.length view.buf))
+
 end
 
 let tags_buf = ref Buf.empty
@@ -52,8 +60,10 @@ let onupdate width height =
   let csr = Draw.Cursor.make (width, height) 0 0 in
   Draw.status csr "UNSI> *scratch*";
   Draw.tags csr !tags_buf;
-  Draw.scroll csr;
-  edit_view := View.draw !edit_view csr
+  let scrollcsr = (Draw.Cursor.clone csr) in
+  Draw.Cursor.move_x csr 15;
+  edit_view := View.draw !edit_view csr;
+  Draw.scroll scrollcsr (View.visible !edit_view)
 
 let onshutdown () = ()
 
index 94a6fbb63b2620ddae6d7d2a67d56d529bfbdc16..ef6f37af66f95c4f062611a59b202afec38dc0ae 100644 (file)
@@ -16,6 +16,9 @@ let empty =
 let load path =
   { path = path; rope = Rope.from_string (Misc.load_file path) }
 
+let length buf =
+  Rope.length buf.rope
+
 let iteri fn buf i =
   Rope.iteri fn buf.rope i
 
index 496882d854ec1e8e675a563e2fb22cc319d71a17..57f6304ff6f1ad82ae041210b625f9c9a1d83b51 100644 (file)
@@ -36,6 +36,7 @@ end
 
 val empty : t
 val load : string -> t
+val length : t -> int
 val iter : (int -> bool) -> t -> int -> unit
 val iteri : (int -> int -> bool) -> t -> int -> unit
 
index 8cafd265ba80dc5fa17d4d8ef57edf93f5205cf8..9cbf0c3bd58a8f356ae9f70690d9cd108e916878 100644 (file)
@@ -22,6 +22,14 @@ module Cursor = struct
     { height = height; width = width;
       startx = x; starty = y; x = x; y = y }
 
+  let clone csr =
+    { height = csr.height; width = csr.width;
+      startx = csr.startx; starty = csr.starty;
+      x = csr.x; y = csr.y }
+
+  let move_x csr n =
+    csr.x <- csr.x + n
+
   let max_width csr =
     (csr.width - csr.x)
 
@@ -92,12 +100,14 @@ let vrule height csr =
 
 let buffer csr buf off =
   dark_bkg (csr.width - csr.x) (csr.height - csr.y) csr;
-  let csr = (restart csr 2 0) in
+  let num = ref 0 and csr = (restart csr 2 0) in
   let draw_rune c =
     draw_glyph csr c;
+    num := !num + 1;
     has_next_line csr
   in
-  Buf.iter draw_rune buf off
+  Buf.iter draw_rune buf off;
+  !num
 
 let status csr str =
   dark_bkg csr.width (4 + font_height) csr;
@@ -111,9 +121,10 @@ let tags csr buf =
   string "Quit Save Undo Redo Cut Copy Paste | Find " csr;
   hrule csr.width csr
 
-let scroll csr =
+let scroll csr pct =
+  let thumbsz = int_of_float ((float_of_int csr.height) *. pct) in
   rule_bkg 14 csr.height csr;
-  dark_bkg 14 (csr.height / 2) csr;
+  dark_bkg 14 thumbsz csr;
   csr.x <- csr.x + 14;
   vrule csr.height csr
 
index 592a2c3628770ef6df3f3786cf8f141f00cc4799..c71bf5f180a828127f0b17364ba1d4328ab3f1ce 100644 (file)
@@ -1,6 +1,8 @@
 module Cursor : sig
   type t
   val make : (int * int) -> int -> int -> t
+  val clone : t -> t
+  val move_x : t -> int -> unit
   val max_width : t -> int
   val restart : t -> int -> int -> t
   val next_line : t -> unit
@@ -16,7 +18,7 @@ val dark_bkg : int -> int -> Cursor.t -> unit
 val light_bkg : int -> int -> Cursor.t -> unit
 val rule_bkg : int -> int -> Cursor.t -> unit
 
-val buffer : Cursor.t -> Buf.t -> int -> unit
+val buffer : Cursor.t -> Buf.t -> int -> int
 
 val string : string -> Cursor.t -> unit
 val hrule : int -> Cursor.t -> unit
@@ -24,5 +26,5 @@ val vrule : int -> Cursor.t -> unit
 
 val status : Cursor.t -> string -> unit
 val tags : Cursor.t -> Buf.t -> unit
-val scroll : Cursor.t -> unit
-val edit : Cursor.t -> Buf.t -> int -> unit
+val scroll : Cursor.t -> float -> unit
+val edit : Cursor.t -> Buf.t -> int -> int
index d8211a2c73739849c5dfb4c7a76758a628fadeec..d9759407497b46339495143374fe290066eca392 100644 (file)
@@ -26,10 +26,6 @@ let is_leaf = function
   | Leaf _ -> true
   | _ -> false
 
-let is_leaf = function
-  | Leaf _ -> true
-  | _ -> false
-
 let limit_index rope i =
   if i < 0 then 0
   else if i > 0 && i >= (length rope) then
@@ -79,7 +75,7 @@ let rec getc rope i =
 
 (* inefficient form of iteri *)
 let rec iteri fn rope pos =
-  if pos < (length rope) && (fn pos (getc rope pos)) then
+  if pos < (length rope) && (fn pos (Char.code (getb rope pos))) then
     iteri fn rope (pos + 1)
 
 (* More efficient form of iteri?
@@ -113,6 +109,53 @@ let gets rope i j =
 
 (******************************************************************************)
 
+(* Rebalancing:
+
+* Height of leaf is 0
+* Height of a node is (1 + max(left,right))
+* Rope balanced if (length >= Fib(n) + 2)
+
+
+The rebalancing operation maintains an ordered sequence of (empty or) balanced
+ropes, one for each length interval [Fn, Fn+1), for n $2.
+
+We traverse the rope from left to right, inserting each leaf into the
+appropriate sequence position, depending on its length.
+
+The concatenation of the sequence of ropes in order of decreasing length is
+equivalent to the prefix of the rope we have traversed so far.
+
+Each new leaf x is inserted into the appropriate entry of the sequence.
+
+Assume that x's length is in the interval [Fib(n), Fib(n+1)], and thus it should be put
+in slot n (which also corresponds to maximum depth n - 2).
+
+If all lower and equal numbered levels are empty, then this can be done directly.
+
+If not, then we concatenate ropes in slots 2,. . .,(n - 1) (concatenating onto
+the left), and concatenate x to the right of the result.
+
+We then continue to concatenate ropes from the sequence in increasing order to
+the left of this result, until the result fits into an empty slot in the sequence.
+
+The concatenation we form in this manner is guaranteed to be balanced.
+
+The concatenations formed before the addition of x each have depth at most one more
+than is warranted by their length.
+
+If slot n - 1 is empty then the concatenation of shorter ropes has depth at most
+n - 3, so the concatenation with x has depth n - 2, and is thus balanced.
+
+If slot n - 1 is full, then the final depth after adding x may be n - 1, but the
+resulting length is guaranteed to be at least Fn+1, again guaranteeing
+balance.
+
+Subsequent concatenations (if any) involve concatenating two balanced ropes with
+lengths at least Fm and Fm-1 and producing a rope of depth m - 1, which must
+again be balanced.
+
+*)
+
 let flatten rope =
   let s = (gets rope 0 (length rope)) in
   Leaf (s,0,(String.length s))
index c43193eeffef813206be19ccce31d7af7fd4f72a..2e03ef0952e7aa8bc3264ef0226e2eb3920d0b21 100644 (file)
@@ -126,14 +126,12 @@ CAMLprim value x11_event_loop(value ms, value cbfn) {
         uint64_t t = getmillis();
         while (XPending(X.display)) {
             XNextEvent(X.display, &e);
-            printf("%d ", e.type);
             if (!XFilterEvent(&e, None) && EventHandlers[e.type]) {
                 event = EventHandlers[e.type](&e);
                 if (event != Val_int(TNone))
                     caml_callback(cbfn, event);
             }
         }
-        puts("");
         printf("time 1 %lu ", getmillis()-t);
         t = getmillis();
         if (X.running) {