From f0d44091519e26b160ce12bc7366d02f196ac852 Mon Sep 17 00:00:00 2001
From: Frederic Culot <calcurse@culot.org>
Date: Fri, 18 Apr 2008 17:53:31 +0000
Subject: Generic functions to handle scrolling windows created

---
 src/help.c | 76 ++++++++++++++++++++++++++------------------------------------
 src/wins.c | 50 ++++++++++++++++++++++++++++++++++++++++-
 src/wins.h | 46 +++++++++++++++++++++++--------------
 3 files changed, 110 insertions(+), 62 deletions(-)

(limited to 'src')

diff --git a/src/help.c b/src/help.c
index f023d48..6a81750 100755
--- a/src/help.c
+++ b/src/help.c
@@ -1,4 +1,4 @@
-/*	$calcurse: help.c,v 1.22 2008/04/12 21:14:03 culot Exp $	*/
+/*	$calcurse: help.c,v 1.23 2008/04/18 17:53:31 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -256,15 +256,12 @@ wanted_page (int ch)
 void
 help_screen (void)
 {
-  window_t hwin;
-  window_t hpad;
+  scrollwin_t hwin;
   const int PADOFFSET = 4;
   const int TITLELINES = 3;
+  int need_resize;
   int ch = '?';
-  int text_lines;
-  int first_line = 0, nl = 0;
   int page, oldpage;
-  int need_resize;
   help_page_t hscr[HELPSCREENS];
 
   hscr[HELP_MAIN].title =
@@ -560,71 +557,62 @@ help_screen (void)
       "Send your feedback or comments to : calcurse@culot.org\n"
       "Calcurse home page : http://culot.org/calcurse");
 
-  need_resize = 0;
-  page = oldpage = HELP_MAIN;
-  help_wins_init (&hwin, &hpad, PADOFFSET);
+  hwin.win.x = 0;
+  hwin.win.y = 0;
+  hwin.win.h = (notify_bar ()) ? row - 3 : row - 2;
+  hwin.win.w = col;
 
+  hwin.pad.x = PADOFFSET;
+  hwin.pad.y = TITLELINES;
+  hwin.pad.h = BUFSIZ;
+  hwin.pad.w = col - 2 * PADOFFSET + 1;
+
+  snprintf (hwin.label, BUFSIZ, _("Calcurse %s | help"), VERSION);
+  wins_scrollwin_init (&hwin);
+  wins_show (hwin.win.p, hwin.label);
+  page = oldpage = HELP_MAIN;
+  need_resize = 0;
+  
   /* Display the help screen related to user input. */
   while (ch != 'q')
     {
-      erase_window_part (hwin.p, 1, TITLELINES, col - 2, hwin.h - 2);
-
+      erase_window_part (hwin.win.p, 1, TITLELINES, col - 2,
+                         hwin.win.h - 2);
       switch (ch)
 	{
 	case KEY_RESIZE:
-	  help_wins_reset (&hwin, &hpad, PADOFFSET);
-	  first_line = 0;
-	  nl = write_help_pad (&hpad, &hscr[oldpage]);
+	  help_wins_reset (&hwin.win, &hwin.pad, PADOFFSET);
+	  hwin.first_visible_line = 0;
+	  hwin.total_lines = write_help_pad (&hwin.pad, &hscr[oldpage]);
 	  need_resize = 1;
 	  break;
 
 	case CTRL ('n'):
-	  if (nl > (first_line + hwin.h - (PADOFFSET + 1)))
-	    first_line++;
+	  if (hwin.total_lines
+              > (hwin.first_visible_line + hwin.win.h - hwin.pad.x))
+	    hwin.first_visible_line++;
 	  break;
 
 	case CTRL ('p'):
-	  if (first_line > 0)
-	    first_line--;
+	  if (hwin.first_visible_line > 0)
+	    hwin.first_visible_line--;
 	  break;
 
 	default:
 	  page = wanted_page (ch);
 	  if (page != NOPAGE)
 	    {
-	      first_line = 0;
-	      nl = write_help_pad (&hpad, &hscr[page]);
+	      hwin.first_visible_line = 0;
+	      hwin.total_lines = write_help_pad (&hwin.pad, &hscr[page]);
 	      oldpage = page;
 	    }
 	  break;
 	}
-
-      /* Draw the scrollbar if necessary. */
-      text_lines = hwin.h - (PADOFFSET + 1);
-      if (nl > text_lines)
-	{
-	  float ratio = ((float) text_lines + 1) / ((float) nl);
-	  int sbar_length = (int) (ratio * text_lines);
-	  int highend = (int) (ratio * first_line);
-	  int sbar_top = highend + TITLELINES + 1;
-
-	  if ((sbar_top + sbar_length) > hwin.h - 1)
-	    sbar_length = hwin.h - 1 - sbar_top;
-	  draw_scrollbar (hwin.p, sbar_top, col - 2,
-			  sbar_length, TITLELINES + 1, hwin.h - 1, true);
-	}
-
-      wmove (win[STA].p, 0, 0);
-      wnoutrefresh (hwin.p);
-      pnoutrefresh (hpad.p, first_line, 0, PADOFFSET, PADOFFSET,
-		    hwin.h - 2, col - PADOFFSET);
-      doupdate ();
+      wins_scrollwin_display (&hwin);
       ch = wgetch (win[STA].p);
       ch = tolower (ch);
     }
-
-  delwin (hpad.p);
-  delwin (hwin.p);
+  wins_scrollwin_delete (&hwin);
   if (need_resize)
     wins_reset ();
 }
diff --git a/src/wins.c b/src/wins.c
index 489c3da..189e149 100755
--- a/src/wins.c
+++ b/src/wins.c
@@ -1,4 +1,4 @@
-/*	$calcurse: wins.c,v 1.13 2008/04/12 21:14:03 culot Exp $	*/
+/*	$calcurse: wins.c,v 1.14 2008/04/18 17:53:31 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -118,6 +118,54 @@ wins_init (void)
   keypad (win[STA].p, TRUE);
 }
 
+/* 
+ * Create a new window and its associated pad, which is used to make the
+ * scrolling faster.
+ */
+void
+wins_scrollwin_init (scrollwin_t *sw)
+{
+  ASSERT (sw != NULL);
+  sw->win.p = newwin (sw->win.h, sw->win.w, sw->win.y, sw->win.x);
+  sw->pad.p = newpad (sw->pad.h, sw->pad.w);
+  sw->first_visible_line = 0;
+  sw->total_lines = 0;
+}
+
+/* Free an already created scrollwin. */
+void
+wins_scrollwin_delete (scrollwin_t *sw)
+{
+  ASSERT (sw != NULL);
+  delwin(sw->win.p);
+  delwin(sw->pad.p);
+}
+
+/* Display a scrolling window. */
+void
+wins_scrollwin_display (scrollwin_t *sw)
+{
+  const int visible_lines = sw->win.h - sw->pad.x;
+  
+  if (sw->total_lines > visible_lines)
+    {
+      float ratio = ((float) visible_lines) / ((float) sw->total_lines);
+      int sbar_length = (int) (ratio * visible_lines);
+      int highend = (int) (ratio * sw->first_visible_line);
+      int sbar_top = highend + sw->pad.y + 1;
+
+      if ((sbar_top + sbar_length) > sw->win.h - 1)
+        sbar_length = sw->win.h - sbar_top;
+      draw_scrollbar (sw->win.p, sbar_top, sw->win.w + sw->win.x - 2,
+                      sbar_length, sw->pad.y + 1, sw->win.h - 1, true);
+    }
+  wmove (win[STA].p, 0, 0);
+  wnoutrefresh (sw->win.p);
+  pnoutrefresh (sw->pad.p, sw->first_visible_line, 0, sw->pad.y, sw->pad.x,
+                sw->win.h - sw->pad.y + 1, sw->win.w - sw->win.x);
+  doupdate ();
+}
+
 /* 
  * Delete the existing windows and recreate them with their new
  * size and placement.
diff --git a/src/wins.h b/src/wins.h
index eef9119..67f9025 100755
--- a/src/wins.h
+++ b/src/wins.h
@@ -1,4 +1,4 @@
-/*	$calcurse: wins.h,v 1.7 2008/04/12 21:14:03 culot Exp $	*/
+/*	$calcurse: wins.h,v 1.8 2008/04/18 17:53:31 culot Exp $	*/
 
 /*
  * Calcurse - text-based organizer
@@ -40,7 +40,7 @@ typedef enum
 }
 window_e;
 
-/* Window properties */
+/* Generic window structure. */
 typedef struct
 {
   WINDOW   *p;			/* pointer to window */
@@ -48,23 +48,35 @@ typedef struct
   unsigned  h;			/* height */
   int       x;			/* x position */
   int       y;			/* y position */
-}
-window_t;
+} window_t;
+
+/* Generic scrolling window structure. */
+typedef struct
+{
+  window_t  win;
+  window_t  pad;
+  unsigned  first_visible_line;
+  unsigned  total_lines;
+  char      label[BUFSIZ];
+} scrollwin_t;
 
 extern window_t win[NBWINS];
 
-int      wins_layout (void);
-void     wins_set_layout (int);
-void     wins_slctd_init (void);
-window_e wins_slctd (void);
-void     wins_slctd_set (window_e);
-void     wins_slctd_next (void);
-void     wins_init (void);
-void     wins_reinit (void);
-void     wins_show (WINDOW *, char *);
-void     wins_get_config (void);
-void     wins_update (void);
-void     wins_reset (void);
-void     wins_launch_external (const char *, const char *);
+int          wins_layout (void);
+void         wins_set_layout (int);
+void         wins_slctd_init (void);
+window_e     wins_slctd (void);
+void         wins_slctd_set (window_e);
+void         wins_slctd_next (void);
+void         wins_init (void);
+void         wins_scrollwin_init (scrollwin_t *);
+void         wins_scrollwin_delete (scrollwin_t *);
+void         wins_scrollwin_display (scrollwin_t *);
+void         wins_reinit (void);
+void         wins_show (WINDOW *, char *);
+void         wins_get_config (void);
+void         wins_update (void);
+void         wins_reset (void);
+void         wins_launch_external (const char *, const char *);
 
 #endif /* CALCURSE_WINS_H */
-- 
cgit v1.2.3-70-g09d2