billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=5db4ef8519ded9d2ba30b3494d6d1db42d66f637

commit 5db4ef8519ded9d2ba30b3494d6d1db42d66f637
Author: Godfath3r <galatsan...@gmail.com>
Date:   Tue Jul 15 12:20:19 2014 +0200

    Terminology: Miniview: add position indicator
    
    Summary: Merge branch 'miniview_indicator'
    
    Reviewers: raster, billiob
    
    Maniphest Tasks: T1417
    
    Differential Revision: https://phab.enlightenment.org/D1150
---
 data/themes/default.edc |  26 +++++++
 src/bin/miniview.c      | 183 +++++++++++++++++++++++++++++++++++++++++++++++-
 src/bin/miniview.h      |   1 +
 src/bin/termio.c        |   4 ++
 4 files changed, 211 insertions(+), 3 deletions(-)

diff --git a/data/themes/default.edc b/data/themes/default.edc
index 5b97f4c..fdf2455 100644
--- a/data/themes/default.edc
+++ b/data/themes/default.edc
@@ -46,6 +46,22 @@ collections {
                }
             }
          }
+         part { name: "miniview_screen"; type: RECT;
+             mouse_events: 1;
+                dragable {
+                    confine: "miniview.img";
+                    x: 0 0 0;
+                    y: 1 1 0;
+                }
+             description { state: "default" 0.0;
+                color: 255 255 255 40;
+                fixed:1 1;
+             }
+             description { state: "outbounds" 0.0;
+                color: 255 25 35 40;
+                fixed:1 1;
+             }
+         }
          part { name: "miniview.close_shadow"; type: IMAGE;
             description { state: "default" 0.0;
                image {
@@ -78,6 +94,16 @@ collections {
             signal: "mouse,clicked,1"; source: "miniview.close";
             action: SIGNAL_EMIT "miniview,close" "terminology";
          }
+         program {
+            signal: "miniview_screen,inbounds"; source: "miniview";
+            action: STATE_SET "default" 0.0;
+            target: "miniview_screen";
+         }
+         program {
+            signal: "miniview_screen,outbounds"; source: "miniview";
+            action: STATE_SET "outbounds" 0.0;
+            target: "miniview_screen";
+         }
       };
    };
 
diff --git a/src/bin/miniview.c b/src/bin/miniview.c
index a9797d4..fca7201 100644
--- a/src/bin/miniview.c
+++ b/src/bin/miniview.c
@@ -1,6 +1,7 @@
 #include <Elementary.h>
 #include <stdio.h>
 #include <assert.h>
+#include <math.h>
 
 #include "miniview.h"
 #include "col.h"
@@ -63,6 +64,13 @@ struct _Miniview
 
    unsigned int is_shown : 1;
    unsigned int to_render : 1;
+
+   Eina_Bool fits_to_img;
+
+   struct _screen {
+      double size;
+      double pos_val;
+   }screen;
 };
 
 static Evas_Smart *_smart = NULL;
@@ -127,6 +135,42 @@ _draw_line(const Termpty *ty, unsigned int *pixels,
      }
 }
 
+Eina_Bool
+_is_top_bottom_reached(Miniview *mv)
+{
+   Termpty *ty;
+   int history_len;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(mv, EINA_FALSE);
+   ty = termio_pty_get(mv->termio);
+   history_len = ty->backscroll_num;
+
+   if (( (- mv->img_hist) > (int)(mv->img_h - mv->rows - (mv->rows / 2))) &&
+       ( (- mv->img_hist) < (int)(history_len + (mv->rows / 2))))
+          return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static void
+_screen_visual_bounds(Miniview *mv)
+{
+   if ((mv->screen.pos_val > 1) || (mv->screen.pos_val < 0))
+     {
+        edje_object_part_drag_value_set(mv->base, "miniview_screen",
+                                        0.0, mv->screen.pos_val);
+        edje_object_signal_emit(mv->base, "miniview_screen,outbounds",
+                                "miniview");
+     }
+   else
+     {
+        edje_object_part_drag_value_set(mv->base, "miniview_screen",
+                                        0.0, mv->screen.pos_val);
+        edje_object_signal_emit(mv->base, "miniview_screen,inbounds",
+                                "miniview");
+     }
+}
+
 static void
 _queue_render(Miniview *mv)
 {
@@ -147,9 +191,58 @@ _smart_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED,
    /* do not handle horizontal scrolling */
    if (ev->direction) return;
    mv->img_hist += ev->z * 25;
+
+   if (!mv->fits_to_img && !_is_top_bottom_reached(mv))
+     {
+        mv->screen.pos_val = mv->screen.pos_val -
+                             (double) (ev->z * 25) / (mv->img_h - mv->rows);
+        _screen_visual_bounds(mv);
+     }
    _queue_render(mv);
 }
 
+void
+miniview_position_offset(Evas_Object *obj, int by, Eina_Bool sanitize)
+{
+   Miniview *mv = evas_object_smart_data_get(obj);
+   int remain = 0;
+
+   termio_scroll_get(mv->termio);
+   EINA_SAFETY_ON_NULL_RETURN(mv);
+   if ((mv->screen.pos_val <= 1.0) && (mv->screen.pos_val >= 0.0))
+     edje_object_signal_emit(mv->base, "miniview_screen,inbounds", "miniview");
+
+   if (!mv->fits_to_img)
+     {
+        mv->screen.pos_val += (double) by / (mv->img_h - mv->rows);
+        edje_object_part_drag_value_set(mv->base, "miniview_screen",
+                                        0.0, mv->screen.pos_val);
+        if ((mv->screen.pos_val <= 0) && (sanitize))
+          {
+             /* This is what remains when screen pos has to
+                go negative by some portion "by" */
+             remain = (int) round(mv->screen.pos_val * (mv->img_h - mv->rows));
+             mv->img_hist += remain;
+             mv->screen.pos_val = 0;
+          }
+        if ((mv->screen.pos_val > 1) && (sanitize))
+          {
+             remain = (int) round((1 - mv->screen.pos_val) *
+                      (mv->img_h - mv->rows));
+             mv->img_hist -= remain;
+             mv->screen.pos_val = 1;
+          }
+     }
+   else
+     {
+        mv->screen.pos_val += (double) by / (mv->img_h - mv->rows);
+        edje_object_part_drag_value_set(mv->base, "miniview_screen",
+                                        0.0, mv->screen.pos_val);
+        if (mv->screen.pos_val < 0 && sanitize) mv->screen.pos_val = 0;
+        if (mv->screen.pos_val > 1 && sanitize) mv->screen.pos_val = 1;
+     }
+}
+
 Eina_Bool
 miniview_handle_key(Evas_Object *obj, Evas_Event_Key_Down *ev)
 {
@@ -175,13 +268,31 @@ miniview_handle_key(Evas_Object *obj, Evas_Event_Key_Down 
*ev)
 
    if (!strcmp(ev->key, "Prior"))
      {
-        mv->img_hist -= z;
+        if (!mv->fits_to_img)
+          {
+             mv->img_hist -= z;
+             if (_is_top_bottom_reached(mv))
+               {
+                  miniview_position_offset(obj, -z, EINA_FALSE);
+               }
+             miniview_position_offset(obj, z, EINA_FALSE);
+             _screen_visual_bounds(mv);
+          }
         _queue_render(mv);
         return EINA_TRUE;
      }
    else if (!strcmp(ev->key, "Next"))
      {
-        mv->img_hist += z;
+        if (!mv->fits_to_img)
+          {
+             mv->img_hist += z;
+             if (_is_top_bottom_reached(mv))
+               {
+                  miniview_position_offset(obj, z, EINA_FALSE);
+               }
+             miniview_position_offset(obj, -z, EINA_FALSE);
+             _screen_visual_bounds(mv);
+          }
         _queue_render(mv);
         return EINA_TRUE;
      }
@@ -194,7 +305,7 @@ _smart_cb_mouse_down(void *data, Evas *e EINA_UNUSED,
 {
    Evas_Event_Mouse_Down *ev = event;
    Miniview *mv= evas_object_smart_data_get(data);
-   int pos;
+   int pos, pos2;
    Evas_Coord oy;
 
    EINA_SAFETY_ON_NULL_RETURN(mv);
@@ -205,6 +316,56 @@ _smart_cb_mouse_down(void *data, Evas *e EINA_UNUSED,
    if (pos < 0) pos = 0;
    else pos += mv->rows / 2;
    termio_scroll_set(mv->termio, pos);
+
+   pos2 = ev->canvas.y - oy - (mv->rows / 2);
+   if (pos2 < 0) pos2 = 0;
+   if (pos2 > -mv->img_hist) pos2 = -mv->img_hist;
+   mv->screen.pos_val = (double) pos2 / (mv->img_h - mv->rows);
+   edje_object_part_drag_value_set(mv->base, "miniview_screen", 0.0, 
mv->screen.pos_val);
+   edje_object_signal_emit(mv->base, "miniview_screen,inbounds", "miniview");
+
+}
+
+static void
+_on_screen_stoped(void *data, Evas_Object *o EINA_UNUSED,
+                  const char *emission EINA_UNUSED,
+                  const char *source EINA_UNUSED)
+{
+   Miniview *mv= evas_object_smart_data_get(data);
+
+   EINA_SAFETY_ON_NULL_RETURN(mv);
+
+   edje_object_part_drag_value_set(mv->base, "miniview_screen", 0.0,
+                                   mv->screen.pos_val);
+}
+
+static void
+_on_screen_moved(void *data, Evas_Object *o, const char *emission EINA_UNUSED,
+                 const char *source EINA_UNUSED)
+{
+   Miniview *mv = evas_object_smart_data_get(data);
+   double val = 0.0, pos = 0.0, bottom_bound = 0.0;
+
+   edje_object_part_drag_value_get(o, "miniview_screen", NULL, &val);
+   bottom_bound = ((double) (-mv->img_hist )) / (mv->img_h - mv->rows);
+   if (!mv->fits_to_img)
+     {
+        pos = (bottom_bound - val) * (mv->img_h - mv->rows);
+        mv->screen.pos_val = val;
+     }
+   else
+     {
+        bottom_bound = ((double) (-mv->img_hist )) / (mv->img_h - mv->rows);
+        pos = (bottom_bound - val) * (mv->img_h - mv->rows);
+        if (val < bottom_bound)
+          mv->screen.pos_val = val;
+        if (val > bottom_bound)
+          {
+             mv->screen.pos_val = bottom_bound;
+             pos = 0;
+          }
+     }
+   termio_scroll_set(mv->termio, (int) pos);
 }
 
 static void
@@ -285,6 +446,9 @@ _smart_show(Evas_Object *obj)
         mv->rows = oh / font_h;
         mv->cols = ow / font_w;
 
+        mv->screen.size = (double) mv->rows / (double) mv->img_h;
+        edje_object_part_drag_size_set(mv->base, "miniview_screen", 1.0, 
mv->screen.size);
+
         if ((mv->rows == 0) || (mv->cols == 0)) return;
 
         _queue_render(mv);
@@ -388,6 +552,15 @@ _deferred_renderer(void *data)
    evas_object_image_pixels_dirty_set(mv->img, EINA_FALSE);
    evas_object_image_data_update_add(mv->img, 0, 0, ow, oh);
 
+   if (history_len > (int)(mv->img_h - mv->rows)) mv->fits_to_img = EINA_FALSE;
+   else mv->fits_to_img = EINA_TRUE;
+
+   if ((termio_scroll_get(mv->termio) == 0))
+     {
+        mv->screen.pos_val = (double) -mv->img_hist / (mv->img_h - mv->rows);
+        edje_object_part_drag_value_set(mv->base, "miniview_screen", 0.0, 
mv->screen.pos_val);
+     }
+
    mv->to_render = 0;
    mv->deferred_renderer = NULL;
    return EINA_FALSE;
@@ -483,6 +656,10 @@ miniview_add(Evas_Object *parent, Evas_Object *termio)
                                   _smart_cb_mouse_down, obj);
    edje_object_signal_callback_add(mv->base, "miniview,close", "terminology",
                                    _cb_miniview_close, mv);
+   edje_object_signal_callback_add(mv->base, "drag", "miniview_screen",
+                                   _on_screen_moved, obj);
+   edje_object_signal_callback_add(mv->base, "drag,stop", "miniview_screen",
+                                   _on_screen_stoped, obj);
    return obj;
 }
 
diff --git a/src/bin/miniview.h b/src/bin/miniview.h
index e36a077..8ca308a 100644
--- a/src/bin/miniview.h
+++ b/src/bin/miniview.h
@@ -6,6 +6,7 @@
 Evas_Object * miniview_add(Evas_Object *parent, Evas_Object *termio);
 
 void miniview_redraw(Evas_Object *obj);
+void miniview_position_offset(Evas_Object *obj, int by, Eina_Bool sanitize);
 Eina_Bool miniview_handle_key(Evas_Object *obj, Evas_Event_Key_Down *ev);
 
 void miniview_init(void);
diff --git a/src/bin/termio.c b/src/bin/termio.c
index 27d625b..cf44037 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -2032,6 +2032,7 @@ _handle_shift(Evas_Event_Key_Down *ev, int by, 
Evas_Object *term, Termio *sd)
              if (sd->scroll > sd->pty->backscroll_num)
                sd->scroll = sd->pty->backscroll_num;
              _smart_update_queue(term, sd);
+             miniview_position_offset(term_miniview_get(sd->term), -by, 
EINA_TRUE);
           }
      }
    else if (!strcmp(ev->key, "Next"))
@@ -2039,6 +2040,7 @@ _handle_shift(Evas_Event_Key_Down *ev, int by, 
Evas_Object *term, Termio *sd)
         sd->scroll -= by;
         if (sd->scroll < 0) sd->scroll = 0;
         _smart_update_queue(term, sd);
+        miniview_position_offset(term_miniview_get(sd->term), by, EINA_TRUE);
      }
    else if (!strcmp(ev->key, "Insert"))
      {
@@ -3466,6 +3468,8 @@ _smart_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, 
Evas_Object *obj EINA_UNU
                sd->scroll = sd->pty->backscroll_num;
              else if (sd->scroll < 0) sd->scroll = 0;
              _smart_update_queue(data, sd);
+             miniview_position_offset(term_miniview_get(sd->term),
+                                      ev->z * 4, EINA_TRUE);
           }
      }
    else

-- 


Reply via email to