[Aptitude-svn-commit] r4213 - in branches/aptitude-0.3/aptitude: . src/vscreen

Daniel Burrows dburrows at costa.debian.org
Sat Sep 24 03:22:29 UTC 2005


Author: dburrows
Date: Sat Sep 24 03:22:26 2005
New Revision: 4213

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h
Log:
Let the menu be scrolled up and down on small terminals.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Sat Sep 24 03:22:26 2005
@@ -1,5 +1,10 @@
 2005-09-23  Daniel Burrows  <dburrows at debian.org>
 
+	* src/vscreen/vs_menu.cc, src/vscreen/vs_menu.h:
+
+	  Allow the user to scroll the menu up and down on small
+	  terminals.
+
 	* src/view_changelog.cc:
 
 	  Write a long menu description for the changelog pager.

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.cc	Sat Sep 24 03:22:26 2005
@@ -76,6 +76,8 @@
   :vscreen_widget(), cursorloc(0), min_width(2)
 {
   shown_sig.connect(sigc::mem_fun(*this, &vs_menu::appear));
+  hidden_sig.connect(sigc::mem_fun(*this, &vs_menu::disappear));
+  do_layout.connect(sigc::mem_fun(*this, &vs_menu::update_startloc));
 }
 
 vs_menu::~vs_menu()
@@ -85,7 +87,7 @@
 }
 
 vs_menu::vs_menu(int x, int y, int w, vs_menu_info *inf)
-  :vscreen_widget(), cursorloc(0), min_width(w)
+  :vscreen_widget(), cursorloc(0), startloc(0), min_width(w)
 {
   while(inf->item_type!=vs_menu_info::VS_MENU_END)
     {
@@ -123,6 +125,7 @@
 
   shown_sig.connect(sigc::mem_fun(*this, &vs_menu::appear));
   hidden_sig.connect(sigc::mem_fun(*this, &vs_menu::disappear));
+  do_layout.connect(sigc::mem_fun(*this, &vs_menu::update_startloc));
 }
 
 void vs_menu::append_item(vs_menu_item *newitem)
@@ -159,6 +162,9 @@
   else if(idx==cursorloc)
     set_cursor(prev_selectable(next_selectable(items.size()-1)));
 
+  while(startloc >= items.size())
+    --startloc;
+
   if(get_visible())
     vscreen_queuelayout();
 }
@@ -210,13 +216,38 @@
     item_highlighted(NULL);
 }
 
+void vs_menu::update_startloc()
+{
+  unsigned int h = get_height();
+
+  if(h <= 2)
+    return;
+  else if(h - 2 >= items.size())
+    {
+      startloc = 0;
+      return;
+    }
+  else if(cursorloc >= items.size() || cursorloc < items.size())
+    ; // Do nothing, but also do the final sanitization below.
+  else if(cursorloc < startloc)
+    startloc = cursorloc;
+  else if(startloc + h - 2 <= cursorloc)
+    startloc = cursorloc - (h - 2 - 1);
+
+  if(startloc + (h - 2) > items.size())
+    startloc = items.size() - (h - 2);
+}
+
 void vs_menu::set_cursor(itemlist::size_type pos)
 {
   vs_widget_ref tmpref(this);
 
   if(cursorloc!=pos)
     {
-      cursorloc=pos;
+      cursorloc = pos;
+
+      update_startloc();
+
       highlight_current();
 
       if(get_visible())
@@ -228,7 +259,10 @@
 {
   vs_widget_ref tmpref(this);
 
-  cursorloc=next_selectable(0);
+  cursorloc = next_selectable(0);
+  startloc = 0;
+
+  update_startloc();
 
   highlight_current();
 }
@@ -294,45 +328,97 @@
   else
     cursorloc=prev_selectable(prev_selectable(cursorloc));
 
+  update_startloc();
+
   highlight_current();
 }
 
-bool vs_menu::handle_key(const key &k)
+void vs_menu::move_selection_up()
 {
-  vs_widget_ref tmpref(this);
-
-  // This will ensure that the cursor is in bounds if possible, and that
-  // if it is in bounds, a "real" item is selected.
-  sanitize_cursor(true);
-
-  if(bindings->key_matches(k, "Up"))
+  if(cursorloc > 0)
     {
-      if(cursorloc>0)
+      itemlist::size_type newloc = prev_selectable(cursorloc-1);
+
+      if(newloc >= 0 && newloc < items.size())
 	{
-	  itemlist::size_type newloc=prev_selectable(cursorloc-1);
+	  if(newloc < startloc)
+	    --startloc;
 
-	  if(newloc>=0 && newloc<items.size())
+	  if(newloc >= startloc)
 	    set_cursor(newloc);
-
-	  vscreen_update();
 	}
+      else if(startloc > 0)
+	--startloc;
+
+      update_startloc();
+
+      vscreen_update();
     }
-  else if(bindings->key_matches(k, "Down"))
+  else if(startloc > 0)
+    {
+      --startloc;
+      vscreen_update();
+    }
+}
+
+void vs_menu::move_selection_down()
+{
+  int h = get_height();
+
+  if(cursorloc < items.size() - 1)
     {
-      if(cursorloc<items.size()-1)
+      itemlist::size_type newloc = next_selectable(cursorloc+1);
+
+      if(newloc >= 0 && newloc < items.size())
 	{
-	  itemlist::size_type newloc=next_selectable(cursorloc+1);
+	  if(newloc >= startloc + h - 2)
+	    ++startloc;
 
-	  if(newloc>=0 && newloc<items.size())
+	  if(newloc < startloc + h - 2)
 	    set_cursor(newloc);
-
-	  vscreen_update();
 	}
+      else if(startloc + h < items.size())
+	++startloc;
+
+      vscreen_update();
     }
+  else if(startloc + h - 2 < items.size())
+    {
+      ++startloc;
+      vscreen_update();
+    }
+}
+
+void vs_menu::move_selection_top()
+{
+  startloc = 0;
+  set_cursor(next_selectable(startloc));
+  vscreen_update();
+}
+
+void vs_menu::move_selection_bottom()
+{
+  startloc = items.size() - 1;
+  set_cursor(prev_selectable(startloc));
+  vscreen_update();
+}
+
+bool vs_menu::handle_key(const key &k)
+{
+  vs_widget_ref tmpref(this);
+
+  // This will ensure that the cursor is in bounds if possible, and that
+  // if it is in bounds, a "real" item is selected.
+  sanitize_cursor(true);
+
+  if(bindings->key_matches(k, "Up"))
+    move_selection_up();
+  else if(bindings->key_matches(k, "Down"))
+    move_selection_down();
   else if(bindings->key_matches(k, "Begin"))
-    set_cursor(next_selectable(0));
+    move_selection_top();
   else if(bindings->key_matches(k, "End"))
-    set_cursor(prev_selectable(items.size()-1));
+    move_selection_bottom();
   else if(bindings->key_matches(k, "Confirm"))
     {
       itemlist::size_type selected=cursorloc;
@@ -407,21 +493,26 @@
 
   apply_style(border_style);
   mvadd_wch(0, 0, WACS_ULCORNER);
-  for(int i=1; i<width-1; i++)
-    add_wch(WACS_HLINE);
+
+  const bool up_arrows_visible = (startloc != 0);
+  for(int i = 1; i < width-1; i++)
+    {
+      add_wch((up_arrows_visible && i % 3 == 0) ? WACS_UARROW : WACS_HLINE);
+    }
   add_wch(WACS_URCORNER);
 
   // Make sure that whatever is selected is really selectable.
   sanitize_cursor(true);
 
-  for(itemlist::size_type i=0; i<items.size(); i++)
+  for(itemlist::size_type i = startloc; i < items.size(); ++i)
     if(items[i])
       {
+	int y = i - startloc + 1;
 	bool boldthis=false;
 
 	apply_style(border_style);
-	mvadd_wch(1+i, 0, WACS_VLINE);
-	mvadd_wch(1+i, width-1, WACS_VLINE);
+	mvadd_wch(y, 0, WACS_VLINE);
+	mvadd_wch(y, width-1, WACS_VLINE);
 
 	wstring title=items[i]->get_title();
 	wstring righttext=items[i]->get_binding().empty()?L"":global_bindings.readable_keyname(items[i]->get_binding());
@@ -438,7 +529,7 @@
 
 	apply_style(textst);
 
-	move(1+i, 1);
+	move(y, 1);
 
 	wstring::size_type titleloc=0, rightloc=0;
 	int rightwidth=wcswidth(righttext.c_str(), righttext.size());
@@ -498,8 +589,10 @@
       }
     else
       {
+	int y = i - startloc + 1;
+
 	apply_style(border_style);
-	mvadd_wch(1+i, 0, WACS_LTEE);
+	mvadd_wch(y, 0, WACS_LTEE);
 	for(int j=1; j<width-1; j++)
 	  add_wch(WACS_HLINE);
 	add_wch(WACS_RTEE);
@@ -521,8 +614,12 @@
     }
 
   mvadd_wch(height-1, 0, WACS_LLCORNER);
-  for(int i=1; i<width-1; i++)
-    add_wch(WACS_HLINE);
+
+  const bool down_arrows_visible = startloc + height - 2 < items.size();
+
+  for(int i = 1; i < width-1; ++i)
+    add_wch((down_arrows_visible && i % 3 == 0) ? WACS_DARROW : WACS_HLINE);
+
   add_wch(WACS_LRCORNER);
 }
 
@@ -541,7 +638,7 @@
 
   sanitize_cursor(true);
 
-  return point(0, 1+cursorloc);
+  return point(0, 1 + cursorloc - startloc);
 }
 
 void vs_menu::init_bindings()

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_menu.h	Sat Sep 24 03:22:26 2005
@@ -106,6 +106,9 @@
   /** The location of the cursor, or items.size() if no item is selected. */
   itemlist::size_type cursorloc;
 
+  /** The first visible item in the menu. */
+  itemlist::size_type startloc;
+
   /** The minimum width of this menu. */
   int min_width;
 
@@ -115,6 +118,11 @@
   // connected to "hidden"
   void disappear();
 
+  /** Update the starting location from the current height and cursor
+   *  location.
+   */
+  void update_startloc();
+
   /** Returns \b true iff the given item is selectable. */
   bool selectable(itemlist::size_type pos);
 
@@ -187,6 +195,18 @@
   void append_item(vs_menu_item *newitem);
   void remove_item(vs_menu_item *item);
 
+  /** Move the selection up, as if Up had been pressed. */
+  void move_selection_up();
+
+  /** Move the selection down, as if Down had been pressed. */
+  void move_selection_down();
+
+  /** Move the selection to the top of the menu, as if Home had been pressed. */
+  void move_selection_top();
+
+  /** Move the selection to the bottom of the menu, as if End had been pressed. */
+  void move_selection_bottom();
+
   virtual bool focus_me();
   virtual void paint(const style &st);
   virtual void dispatch_mouse(short id, int x, int y, int z, mmask_t bstate);



More information about the Aptitude-svn-commit mailing list