[Aptitude-devel] r3164 - in branches/aptitude-0.3/aptitude: . doc/en src/vscreen

Daniel Burrows dburrows@costa.debian.org
Thu, 28 Apr 2005 02:15:11 +0000


Author: dburrows
Date: Thu Apr 28 02:15:08 2005
New Revision: 3164

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/doc/en/aptitude.xml
   branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc
   branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h
   branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc
Log:
Add untested support for 'tabbed' multiplexes.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Thu Apr 28 02:15:08 2005
@@ -1,5 +1,12 @@
 2005-04-27  Daniel Burrows  <dburrows@debian.org>
 
+	* doc/en/aptitude.xml, src/vscreen/vs_multiplex.cc, src/vscreen/vs_multiplex.h, src/vscreen/vscreen.cc:
+
+	  Add theoretical support for 'tabbed' multiplexes (untested as
+	  yet).  In order to do this properly, I had to extend the
+	  vs_multiplex API and rewrite its internals to represent each
+	  child using an actual structure.
+
 	* src/main.cc:
 
 	  Hook the layer of indirection up to "dump errors to cerr" before

Modified: branches/aptitude-0.3/aptitude/doc/en/aptitude.xml
==============================================================================
--- branches/aptitude-0.3/aptitude/doc/en/aptitude.xml	(original)
+++ branches/aptitude-0.3/aptitude/doc/en/aptitude.xml	Thu Apr 28 02:15:08 2005
@@ -5687,6 +5687,24 @@
 		</row>
 
 		<row>
+		  <entry><literal>MultiplexTab</literal></entry>
+		  <entry><literal>boldwhite,green</literal></entry>
+		  <entry>
+		    The color used to display <quote>tabs</quote>
+		    other than the currently selected one.
+		  </entry>
+		</row>
+
+		<row>
+		  <entry><literal>MultiplexTabHighlighted</literal></entry>
+		  <entry><literal>green,boldwhite</literal></entry>
+		  <entry>
+		    The color used to display the currently selected
+		    <quote>tab</quote>.
+		  </entry>
+		</row>
+
+		<row>
 		  <entry><literal>PkgBroken</literal></entry>
 		  <entry><literal>black,red</literal></entry>
 		  <entry>

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.cc	Thu Apr 28 02:15:08 2005
@@ -1,6 +1,6 @@
 // vs_multiplex.cc
 //
-//  Copyright 1999,2000 Daniel Burrows
+//  Copyright 1999-2005 Daniel Burrows
 //
 //  This program is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -20,6 +20,8 @@
 #include "vscreen.h"
 #include "vs_multiplex.h"
 
+#include "config/colors.h"
+
 #include <sigc++/adaptors/bind.h>
 #include <sigc++/functors/mem_fun.h>
 
@@ -38,20 +40,41 @@
 
 vs_multiplex::~vs_multiplex()
 {
-  for(list<vscreen_widget *>::iterator i=children.begin();
+  for(list<child_info>::iterator i=children.begin();
+      i!=children.end();
+      i++)
+    i->w->set_owner(NULL);
+}
+
+bool vs_multiplex::tabs_visible() const
+{
+  if(!show_tabs)
+    return false;
+
+  bool one_visible=false;
+
+  for(list<child_info>::const_iterator i=children.begin();
       i!=children.end();
       i++)
-    (*i)->set_owner(NULL);
+    if(i->w->get_visible())
+      {
+	if(!one_visible)
+	  one_visible=true;
+	else
+	  return true;
+      }
+
+  return false;
 }
 
 int vs_multiplex::width_request()
 {
   int rval=0;
 
-  for(list<vscreen_widget *>::iterator i=children.begin();
+  for(list<child_info>::iterator i=children.begin();
       i!=children.end(); ++i)
-    if((*i)->get_visible())
-      rval=max(rval, (*i)->width_request());
+    if(i->w->get_visible())
+      rval=max(rval, i->w->width_request());
 
   return rval;
 }
@@ -60,47 +83,116 @@
 {
   int rval=0;
 
-  for(list<vscreen_widget *>::iterator i=children.begin();
+  for(list<child_info>::iterator i=children.begin();
       i!=children.end(); ++i)
-    if((*i)->get_visible())
-      rval=max(rval, (*i)->height_request(width));
+    if(i->w->get_visible())
+      rval=max(rval, i->w->height_request(width));
 
-  return rval;
+  if(tabs_visible())
+    return rval+1;
+  else
+    return rval;
 }
 
 
 void vs_multiplex::layout_me()
 {
   if(visible_child!=children.end())
-    (*visible_child)->alloc_size(0, 0, getmaxx(), getmaxy());
+    {
+      if(tabs_visible())
+	visible_child->w->alloc_size(0, 1, getmaxx(), getmaxy()-1);
+      else
+	visible_child->w->alloc_size(0, 0, getmaxx(), getmaxy());
+    }
 }
 
 void vs_multiplex::paint()
 {
+  if(tabs_visible())
+    {
+      int visible_children=0;
+
+      for(list<child_info>::iterator i=children.begin();
+	  i!=children.end(); ++i)
+	if(i->w->get_visible())
+	  ++visible_children;
+
+      assert(visible_children>0);
+
+      int remaining_w=getmaxx();
+      int startx=0;
+      move(0, 0);
+
+      for(list<child_info>::iterator i=children.begin();
+	  i!=children.end(); ++i)
+	if(i->w->get_visible()) // draw one
+	  {
+	    int attr;
+	    if(i == visible_child)
+	      attr=get_color("MultiplexTabHighlighted");
+	    else
+	      attr=get_color("MultiplexTab");
+
+	    attrset(attr);
+
+	    unsigned int thisw=remaining_w/visible_children;
+	    --visible_children;
+	    remaining_w-=thisw;
+
+	    if(i->title.size()>thisw)
+	      {
+		addnstr(i->title, thisw);
+
+		startx+=thisw;
+	      }
+	    else
+	      {
+		unsigned int j=0;
+		unsigned int firstchar=(thisw-i->title.size())/2;
+
+		while(j<firstchar)
+		  {
+		    addch(' ');
+		    ++j;
+		  }
+
+		addnstr(i->title, i->title.size());
+		j+=i->title.size();
+
+		while(j<thisw)
+		  {
+		    addch(' ');
+		    ++j;
+		  }
+	      }
+	  }
+      assert(visible_children == 0);
+    }
+
   if(visible_child!=children.end())
-    (*visible_child)->display();
+    visible_child->w->display();
 }
 
 void vs_multiplex::dispatch_mouse(short id, int x, int y, int z,
 				  mmask_t bstate)
 {
   if(visible_child!=children.end())
-    (*visible_child)->dispatch_mouse(id,
-				     x-(*visible_child)->get_startx(),
-				     y-(*visible_child)->get_starty(),
+    visible_child->w->dispatch_mouse(id,
+				     x-visible_child->w->get_startx(),
+				     y-visible_child->w->get_starty(),
 				     z, bstate);
 }
 
 void vs_multiplex::got_focus()
 {
   if(visible_child!=children.end())
-    (*visible_child)->focussed();
+    visible_child->w->focussed();
 }
 
 void vs_multiplex::lost_focus()
 {
   if(visible_child!=children.end())
-    (*visible_child)->unfocussed();
+    visible_child->w->unfocussed();
 }
 
 void vs_multiplex::show_all()
@@ -108,14 +200,14 @@
   show();
 
   if(visible_child!=children.end())
-    (*visible_child)->show_all();
+    visible_child->w->show_all();
 }
 
 void vs_multiplex::show_widget(vscreen_widget *w)
 {
   assert(!children.empty());
 
-  list<vscreen_widget *>::iterator new_visible=visible_child;
+  list<child_info>::iterator new_visible=visible_child;
 
   if(new_visible!=children.end())
     ++new_visible;
@@ -126,19 +218,19 @@
     {
       if(new_visible==children.end())
 	new_visible=children.begin();
-      else if(*new_visible==w)
+      else if(new_visible->w==w)
 	break;
       else
 	++new_visible;
     }
 
   if(visible_child!=children.end() && get_isfocussed())
-    (*visible_child)->unfocussed();
+    visible_child->w->unfocussed();
 
   visible_child=new_visible;
 
   if(visible_child!=children.end() && get_isfocussed())
-    (*visible_child)->focussed();
+    visible_child->w->focussed();
 
   vscreen_queuelayout();
   vscreen_update();
@@ -148,9 +240,9 @@
 {
   assert(!children.empty());
 
-  if(visible_child!=children.end() && *visible_child==w)
+  if(visible_child!=children.end() && visible_child->w==w)
     {
-      list<vscreen_widget *>::iterator new_visible=visible_child;
+      list<child_info>::iterator new_visible=visible_child;
 
       if(new_visible!=children.begin())
 	--new_visible;
@@ -162,7 +254,7 @@
 
       while(new_visible!=visible_child)
 	{
-	  if((*new_visible)->get_visible())
+	  if(new_visible->w->get_visible())
 	    break;
 	  else if(new_visible==children.begin())
 	    {
@@ -174,7 +266,7 @@
 	}
 
       if(visible_child!=children.end() && get_isfocussed())
-	(*visible_child)->unfocussed();
+	visible_child->w->unfocussed();
 
       if(new_visible==visible_child)
 	visible_child=children.end();
@@ -182,7 +274,7 @@
 	visible_child=new_visible;
 
       if(visible_child!=children.end() && get_isfocussed())
-	(*visible_child)->focussed();
+	visible_child->w->focussed();
     }
 
   vscreen_queuelayout();
@@ -191,16 +283,16 @@
 
 vscreen_widget *vs_multiplex::get_focus()
 {
-  return visible_child==children.end()?NULL:*visible_child;
+  return visible_child==children.end()?NULL:visible_child->w;
 }
 
 void vs_multiplex::rem_widget(vscreen_widget *w)
 {
   hide_widget(w);
 
-  for(list<vscreen_widget *>::iterator i=children.begin(); i!=children.end(); i++)
+  for(list<child_info>::iterator i=children.begin(); i!=children.end(); i++)
     {
-      if(*i==w)
+      if(i->w==w)
 	{
 	  assert(w->get_owner()==this);
 
@@ -210,38 +302,54 @@
 	}
     }
 
-  children.remove(w);
+  list<child_info>::iterator i=children.begin(),j;
+  while(i!=children.end())
+    {
+      j=i;
+      ++j;
+
+      if(i->w==w)
+	children.erase(i);
+
+      i=j;
+    }
 
   vscreen_queuelayout();
   vscreen_update();
 }
 
-void vs_multiplex::add_widget(vscreen_widget *w)
+void vs_multiplex::add_widget(vscreen_widget *w,
+			      const string &title)
 {
   w->shown_sig.connect(sigc::bind(sigc::mem_fun(*this, &vs_multiplex::show_widget), w));
   w->hidden_sig.connect(sigc::bind(sigc::mem_fun(*this, &vs_multiplex::hide_widget), w));
 
-  children.push_back(w);
+  children.push_back(child_info(w, title));
   w->set_owner(this);
 
   if(w->get_visible())
     show_widget(w);
 }
 
-void vs_multiplex::add_widget_after(vscreen_widget *w, vscreen_widget *after)
+void vs_multiplex::add_widget(vscreen_widget *w)
+{
+  add_widget(w, "Untitled");
+}
+
+void vs_multiplex::add_widget_after(vscreen_widget *w, vscreen_widget *after, const string &title)
 {
-  for(list<vscreen_widget *>::iterator i=children.begin();
+  for(list<child_info>::iterator i=children.begin();
       i!=children.end();
       i++)
     {
-      if(*i==after)
+      if(i->w==after)
 	{
 	  ++i;
 
 	  w->shown_sig.connect(bind(sigc::mem_fun(*this, &vs_multiplex::show_widget), w));
 	  w->hidden_sig.connect(bind(sigc::mem_fun(*this, &vs_multiplex::hide_widget), w));
 
-	  children.insert(i, w);
+	  children.insert(i, child_info(w, title));
 	  w->set_owner(this);
 
 	  if(w->get_visible())
@@ -255,11 +363,16 @@
   add_widget(w);
 }
 
+void vs_multiplex::add_widget_after(vscreen_widget *w, vscreen_widget *after)
+{
+  add_widget_after(w, after, "Untitled");
+}
+
 void vs_multiplex::cycle_forward()
 {
   if(!children.empty())
     {
-      list<vscreen_widget *>::iterator new_visible=visible_child;
+      list<child_info>::iterator new_visible=visible_child;
 
       if(new_visible!=children.end())
 	++new_visible;
@@ -270,7 +383,7 @@
 	{
 	  if(new_visible==children.end())
 	    new_visible=children.begin();
-	  else if((*new_visible)->get_visible())
+	  else if(new_visible->w->get_visible())
 	    break;
 	  else
 	    ++new_visible;
@@ -283,12 +396,12 @@
 	}
 
       if(visible_child!=children.end() && get_isfocussed())
-	(*visible_child)->unfocussed();
+	visible_child->w->unfocussed();
 
       visible_child=new_visible;
 
       if(visible_child!=children.end() && get_isfocussed())
-	(*visible_child)->focussed();
+	visible_child->w->focussed();
     }
 }
 
@@ -296,7 +409,7 @@
 {
   if(!children.empty())
     {
-      list<vscreen_widget *>::iterator new_visible=visible_child;
+      list<child_info>::iterator new_visible=visible_child;
 
       if(new_visible!=children.begin())
 	--new_visible;
@@ -308,7 +421,7 @@
 
       while(new_visible!=visible_child)
 	{
-	  if((*new_visible)->get_visible())
+	  if(new_visible->w->get_visible())
 	    break;
 	  else if(new_visible==children.begin())
 	    {
@@ -326,19 +439,19 @@
 	}
 
       if(visible_child!=children.end() && get_isfocussed())
-	(*visible_child)->unfocussed();
+	visible_child->w->unfocussed();
 
       visible_child=new_visible;
 
       if(visible_child!=children.end() && get_isfocussed())
-	(*visible_child)->focussed();
+	visible_child->w->focussed();
     }
 }
 
 vscreen_widget *vs_multiplex::visible_widget()
 {
   if(visible_child!=children.end())
-    return *visible_child;
+    return visible_child->w;
   else
     return NULL;
 }
@@ -352,9 +465,9 @@
 {
   unsigned int n=0;
 
-  for(list<vscreen_widget *>::iterator i=children.begin();
+  for(list<child_info>::iterator i=children.begin();
       i!=children.end(); ++i)
-    if((*i)->get_visible())
+    if(i->w->get_visible())
       ++n;
 
   return n;

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vs_multiplex.h	Thu Apr 28 02:15:08 2005
@@ -1,5 +1,5 @@
 // vs_multiplex.h                       (This is -*-c++-*-)
-// Copyright 1999,2000 Daniel Burrows
+// Copyright 1999-2005 Daniel Burrows
 //
 //  This program is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -33,12 +33,39 @@
 #include <assert.h>
 
 #include <list>
+#include <string>
 
+/** This widget displays exactly one of its children at once.  It is
+ *  the same size as its currently active child (plus an optional "tab
+ *  bar" displaying all its children).
+ */
 class vs_multiplex:public vs_passthrough
 {
-  std::list<vscreen_widget *> children;
-
-  std::list<vscreen_widget *>::iterator visible_child;
+  struct child_info
+  {
+    vscreen_widget *w;
+    std::string title;
+
+    child_info(vscreen_widget *_w, const std::string &_title)
+      :w(_w), title(_title)
+    {
+    }
+  };
+
+  std::list<child_info> children;
+
+  std::list<child_info>::iterator visible_child;
+
+  /** If \b true and more than one child is visible, "tabs" are
+   *  displayed at the top of the widget, corresponding to the visible
+   *  children.
+   */
+  bool show_tabs;
+
+  /** \return \b true if show_tabs is \b true and more than one
+   *  child is visible.
+   */
+  bool tabs_visible() const;
 
   void show_widget(vscreen_widget *widget);
   // Used to bring a widget to the front
@@ -72,8 +99,14 @@
 
   void show_all();
 
+  /** Add a title-less widget.  Provided to implement a required
+   *  function and for backwards compatibility; use of this routine is
+   *  deprecated.
+   */
   void add_widget(vscreen_widget *widget);
+  void add_widget(vscreen_widget *widget, const std::string &title);
   void add_widget_after(vscreen_widget *widget, vscreen_widget *after);
+  void add_widget_after(vscreen_widget *widget, vscreen_widget *after, const std::string &title);
   void rem_widget(vscreen_widget *widget);
 
   // These cycle forward and backwards through the list of visible items.

Modified: branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/vscreen.cc	Thu Apr 28 02:15:08 2005
@@ -1,6 +1,6 @@
 // vscreen.cc
 //
-//  Copyright 1999,2000,2001 Daniel Burrows
+//  Copyright 1999-2005 Daniel Burrows
 //
 //  This program is free software; you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -309,6 +309,9 @@
   set_color("MenuBar", COLOR_WHITE, COLOR_BLUE, A_BOLD);
   set_color("HighlightedMenuBar", COLOR_BLUE, COLOR_WHITE, A_BOLD);
 
+  set_color("MultiplexTab", COLOR_WHITE, COLOR_GREEN, A_BOLD);
+  set_color("MultiplexTabHighlighted", COLOR_GREEN, COLOR_WHITE, A_BOLD);
+
   set_color("EditLine", COLOR_WHITE, COLOR_BLACK, 0);
 
   set_color("WidgetFrame", COLOR_WHITE, COLOR_BLACK, 0);