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

Daniel Burrows dburrows@costa.debian.org
Sun, 08 May 2005 15:41:25 +0000


Author: dburrows
Date: Sun May  8 15:41:22 2005
New Revision: 3274

Modified:
   branches/aptitude-0.3/aptitude/ChangeLog
   branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
   branches/aptitude-0.3/aptitude/src/vscreen/fragment.h
Log:
Rewrite fragments to handle styles.

Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog	(original)
+++ branches/aptitude-0.3/aptitude/ChangeLog	Sun May  8 15:41:22 2005
@@ -1,5 +1,9 @@
 2005-05-08  Daniel Burrows  <dburrows@debian.org>
 
+	* src/vscreen/fragment.cc, src/vscreen/fragment.h:
+
+	Rewrite the fragment code to handle styles.
+
 	* src/vscreen/vscreen.cc, src/vscreen/vs_minibuf_win.h, src/vscreen/vs_treeitem.h:
 
 	Make vscreen.cc compile, and change some 'get the color' routines

Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment.cc	Sun May  8 15:41:22 2005
@@ -24,18 +24,14 @@
 public:
   _text_fragment(const chstring &_s):s(_s) {}
 
-  fragment_contents layout(size_t firstw, size_t restw)
+  fragment_contents layout(size_t firstw, size_t restw,
+			   const style &st)
   {
     fragment_contents rval;
-    rval.push_back(s);
+    rval.push_back(chstring(s, st));
     return rval;
   }
 
-  void set_attr(int attr)
-  {
-    s.set_attr(attr);
-  }
-
   size_t max_width(size_t first_indent,
 		   size_t rest_indent) const
   {
@@ -58,9 +54,9 @@
 
 fragment *text_fragment(const chstring &s) { return new _text_fragment(s); }
 fragment *text_fragment(const string &s,
-			int attr)
+			const style &style)
 {
-  return new _text_fragment(chstring(s, attr));
+  return new _text_fragment(chstring(s, style));
 }
 
 /** This fragment just expands to a newline. */
@@ -76,10 +72,6 @@
     return rval;
   }
 
-  void set_attr(int attr)
-  {
-  }
-
   size_t max_width(size_t first_indent, size_t rest_indent) const
   {
     return first_indent;
@@ -101,11 +93,44 @@
   return new _newline_fragment;
 }
 
-fragment *attr_fragment(fragment *f,
-			int attr)
+class _style_fragment:public fragment
+{
+public:
+  _style_fragment(const style &_s, const fragment *_contents)
+    :st(_st), contents(_contents)
+  {
+  }
+  ~_style_fragment() {delete contents;}
+
+  fragment_contents layout(size_t firstw, size_t restw,
+			   const style &s2)
+  {
+    return contents->layout(firstw, restw, s+s2);
+  }
+
+  size_t max_width(size_t first_indent, size_t rest_indent) const
+  {
+    return contents->max_width(first_indent, rest_indent);
+  }
+
+  size_t trailing_width(size_t first_indent, size_t rest_indent) const
+  {
+    return contents->trailing_width(first_indent, rest_indent);
+  }
+
+  bool final_nl() const
+  {
+    return contents->final_nl();
+  }
+private:
+  fragment *contents;
+  style st;
+}
+
+fragment *style_fragment(fragment *f,
+			 const style &st)
 {
-  f->set_attr(attr);
-  return f;
+  return new _style_fragment(f, st);
 }
 
 /** A base class for fragment containers that supports caching
@@ -186,7 +211,8 @@
   {
   }
 
-  fragment_contents layout(size_t firstw, const size_t restw)
+  fragment_contents layout(size_t firstw, const size_t restw,
+			   const style &st)
   {
     fragment_contents rval;
 
@@ -195,7 +221,7 @@
     for(vector<fragment*>::const_iterator i=contents.begin();
 	i!=contents.end(); ++i)
       {
-	fragment_contents lines=(*i)->layout(firstw, restw);
+	fragment_contents lines=(*i)->layout(firstw, restw, st);
 
 	// Update firstw appropriately.
 	if(lines.get_final_nl())
@@ -242,13 +268,6 @@
     return rval;
   }
 
-  void set_attr(int attr)
-  {
-    for(vector<fragment*>::const_iterator i=contents.begin();
-	i!=contents.end(); ++i)
-      (*i)->set_attr(attr);
-  }
-
   ~_sequence_fragment()
   {
     for(vector<fragment*>::const_iterator i=contents.begin();
@@ -329,7 +348,7 @@
 
 // Fall back on sequence_fragment [for now?]
 fragment *join_fragments(const vector<fragment *> &fragments,
-			 const string &between, int attr)
+			 const string &between)
 {
   vector<fragment*> rval;
 
@@ -338,7 +357,7 @@
       ++i)
     {
       if(i!=fragments.begin())
-	rval.push_back(text_fragment(between, attr));
+	rval.push_back(text_fragment(between));
 
       rval.push_back(*i);
     }
@@ -351,12 +370,14 @@
 public:
   _flowbox(fragment *_contents):contents(_contents) {}
 
-  fragment_contents layout(size_t firstw, const size_t restw)
+  fragment_contents layout(size_t firstw, const size_t restw,
+			   const style &st)
   {
     if(restw==0)
       return fragment_contents();
 
-    fragment_contents rval,lines=contents->layout(firstw, restw);
+    fragment_contents rval,lines=contents->layout(firstw, restw,
+						  st);
 
     for(fragment_contents::const_iterator i=lines.begin();
 	i!=lines.end(); ++i)
@@ -435,8 +456,6 @@
     return rval;
   }
 
-  void set_attr(int attr) { contents->set_attr(attr); }
-
   size_t calc_max_width(size_t first_indent,
 			size_t rest_indent) const
   {
@@ -467,12 +486,14 @@
 public:
   _fillbox(fragment *_contents):contents(_contents) {}
 
-  fragment_contents layout(size_t firstw, size_t restw)
+  fragment_contents layout(size_t firstw, size_t restw,
+			   const style &st)
   {
     if(restw==0)
       return fragment_contents();
 
-    fragment_contents rval,lines=contents->layout(firstw, restw);
+    fragment_contents rval,lines=contents->layout(firstw, restw,
+						  st);
 
     for(fragment_contents::const_iterator i=lines.begin();
 	i!=lines.end(); ++i)
@@ -588,8 +609,6 @@
     return rval;
   }
 
-  void set_attr(int attr) { contents->set_attr(attr); }
-
   size_t calc_max_width(size_t first_indent,
 			size_t rest_indent) const
   {
@@ -622,12 +641,14 @@
 
   ~_hardwrapbox() {delete contents;}
 
-  fragment_contents layout(size_t firstw, const size_t restw)
+  fragment_contents layout(size_t firstw, const size_t restw,
+			   const style &st)
   {
     if(restw==0)
       return fragment_contents();
 
-    fragment_contents rval, lines=contents->layout(firstw, restw);
+    fragment_contents rval, lines=contents->layout(firstw, restw,
+						   st);
 
     for(fragment_contents::const_iterator i=lines.begin();
 	i!=lines.end(); ++i)
@@ -662,8 +683,6 @@
     return rval;
   }
 
-  void set_attr(int attr) { contents->set_attr(attr); }
-
   size_t calc_max_width(size_t first_indent, size_t rest_indent) const
   {
     return contents->max_width(first_indent, rest_indent);
@@ -693,9 +712,11 @@
 public:
   _clipbox(fragment *_contents):contents(_contents) {}
 
-  fragment_contents layout(size_t firstw, const size_t restw)
+  fragment_contents layout(size_t firstw, const size_t restw,
+			   const style &st)
   {
-    fragment_contents rval, lines=contents->layout(firstw, restw);
+    fragment_contents rval, lines=contents->layout(firstw, restw,
+						   st);
 
     for(fragment_contents::const_iterator i=lines.begin(); i!=lines.end(); ++i)
       {
@@ -713,8 +734,6 @@
     return rval;
   }
 
-  void set_attr(int attr) { contents->set_attr(attr); }
-
   size_t calc_max_width(size_t first_indent,
 			size_t rest_indent) const
   {
@@ -744,22 +763,24 @@
 {
 public:
   _indentbox(size_t _firstindent, size_t _restindent, fragment *_contents)
-    :contents(_contents), indentattr(0),
-     firstindent(_firstindent), restindent(_restindent) {}
+    :contents(_contents), firstindent(_firstindent),
+     restindent(_restindent) {}
 
-  fragment_contents layout(size_t firstw, size_t restw)
+  fragment_contents layout(size_t firstw, size_t restw,
+			   const style &st)
   {
     if(restw<=restindent)
       return fragment_contents();
 
-    fragment_line firstprepend(firstindent, ' '|indentattr);
-    fragment_line restprepend(restindent, ' '|indentattr);
+    fragment_line firstprepend(firstindent, ' ');
+    fragment_line restprepend(restindent, ' ');
 
     size_t child_firstw=firstw>=firstindent?firstw-firstindent:0;
     size_t child_restw=restw>=restindent?restw-restindent:0;
 
     fragment_contents rval, lines=contents->layout(child_firstw,
-						   child_restw);
+						   child_restw,
+						   st);
 
     for(fragment_contents::const_iterator i=lines.begin(); i!=lines.end(); ++i)
       {
@@ -792,14 +813,10 @@
     return true;
   }
 
-  void set_attr(int attr) { contents->set_attr(attr); indentattr=attr; }
-
   ~_indentbox() { delete contents; }
 private:
   fragment *contents;
 
-  int indentattr;
-
   size_t firstindent, restindent;
 };
 
@@ -978,8 +995,7 @@
       nextpercent=strchr(start, '%');
     }
 
-
-  int attr=A_NORMAL;
+  style st;
 
   va_list arglst;
   va_start(arglst, format);
@@ -996,11 +1012,8 @@
 	case 's':
 	  arguments[i].s=va_arg(arglst, const char *);
 	  break;
-	case 'C':
-	  arguments[i].attr=get_color(va_arg(arglst, const char *));
-	  break;
-	case 'A':
-	  arguments[i].attr=va_arg(arglst, int);
+	case 'S':
+	  arguments[i].s=va_arg(arglst, const char *);
 	  break;
 	default:
 	  return text_fragment("Internal error: bad argument format '"+char_to_str(arguments[i].format)+"'",
@@ -1028,7 +1041,7 @@
   while(nextpercent!=NULL)
     {
       // First, make a fragment for everything until the percent:
-      curstr+=chstring(string(start, nextpercent-start), attr);
+      curstr+=chstring(string(start, nextpercent-start), st);
 
       // This is almost always what we want; in the cases when it's not,
       // I override it explicitly.
@@ -1038,25 +1051,25 @@
       switch(*(nextpercent+1))
 	{
 	case '%':
-	  curstr+=chstring(string("%"), attr);
+	  curstr+=chstring(string("%"), st);
 	  break;
 	case 'B':
-	  attr|=A_BOLD;
+	  st.attr_flip(A_BOLD);
 	  break;
 	case 'b':
-	  attr&=~A_BOLD;
+	  st.attr_flip(A_BOLD);
 	  break;
 	case 'R':
-	  attr|=A_REVERSE;
+	  st.attr_flip(A_REVERSE);
 	  break;
 	case 'r':
-	  attr&=~A_REVERSE;
+	  st.attr_flip(A_REVERSE);
 	  break;
 	case 'D':
-	  attr|=A_DIM;
+	  st.attr_flip(A_DIM);
 	  break;
 	case 'd':
-	  attr&=~A_DIM;
+	  st.attr_flip(A_DIM);
 	  break;
 	case 'n':
 	  if(!curstr.empty())
@@ -1086,16 +1099,10 @@
 	  curstr+=chstring(arguments[argcount].s, attr);
 	  ++argcount;
 	  break;
-	case 'A':
-	  assert(arguments[argcount].format=='A');
+	case 'S':
+	  assert(arguments[argcount].format=='S');
 
-	  attr=arguments[argcount].attr;
-	  ++argcount;
-	  break;
-	case 'C':
-	  assert(arguments[argcount].format=='C');
-	  // it was parsed earlier.
-	  attr=arguments[argcount].attr;
+	  st+=get_style(arguments[argcount].s);
 	  ++argcount;
 	  break;
 	case '0':
@@ -1129,9 +1136,8 @@
 	      case 's':
 		curstr+=chstring(arguments[pos].s, attr);
 		break;
-	      case 'A':
-	      case 'C':
-		attr=arguments[pos].attr;
+	      case 'S':
+		st+=get_style(arguments[pos].s);
 		break;
 	      }
 
@@ -1145,7 +1151,7 @@
 
   // Get any trailing bit o' string:
   if(*start!=0)
-    curstr+=chstring(start, attr);
+    curstr+=chstring(start, st);
 
   if(!curstr.empty())
     rval.push_back(text_fragment(curstr));

Modified: branches/aptitude-0.3/aptitude/src/vscreen/fragment.h
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/fragment.h	(original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/fragment.h	Sun May  8 15:41:22 2005
@@ -10,6 +10,8 @@
 
 #include "fragment_contents.h"
 
+#include "config/style.h"
+
 #include <string>
 #include <vector>
 
@@ -30,17 +32,14 @@
    *  \param w the width to which subsequent lines of the fragment
    *  should be formatted.
    *
+   *  \param s the enclosing style of this fragment
+   *
    *  \return the lines of this fragment; the caller is responsible
    *  for deleting it.
    */
   virtual fragment_contents layout(size_t firstw,
-				   size_t w)=0;
-
-  /** Set the attributes of this fragment.
-   *
-   *  \param attr attributes assigned to this fragment
-   */
-  virtual void set_attr(int attr)=0;
+				   size_t w,
+				   const style &st)=0;
 
   /** \param first_indent the indentation of the first line, relative
    *  to a baseline (which may be outside this fragment).
@@ -87,12 +86,12 @@
  *  formatted as a single line without clipping.
  *
  *  \param s the text to use
- *  \param attr attributes to assign to it
+ *  \param style the new fragment's style
  *
  *  \return the new fragment
  */
 fragment *text_fragment(const std::string &s,
-			int attr=A_NORMAL);
+			const style &st=style());
 
 /** Create a fragment from a string of text.  The text will simply be
  *  formatted as a single line without clipping.
@@ -103,29 +102,23 @@
  *  \return the new fragment
  */
 inline fragment *text_fragment(const char *s,
-			       int attr=A_NORMAL)
+			       const style &st=style())
 {
-  return text_fragment(std::string(s), attr);
+  return text_fragment(std::string(s), st);
 }
 
 /** Create a fragment which simply produces a newline wherever it occurs. */
 fragment *newline_fragment();
 
-/** Create a fragment which simply assigns a particular attribute to
- *  the text of its child fragment.  It's not clear that this is
- *  really necessary, but it might make it easier to support some
- *  layout models.
- *
- *  (presently this actually just sets the attributes of f and returns
- *  it, but this could also return a separate node)
+/** Create a fragment which alters the style of its contents.
  *
  *  \param f the child of this fragment
  *  \param attr the text attribute which should be assigned to f
  *
  *  \return the new fragment
  */
-fragment *attr_fragment(fragment *f,
-			int attr);
+fragment *style_fragment(fragment *f,
+			 const style &st);
 
 /** Create a fragment from a sequence of other fragments.
  *
@@ -161,10 +154,9 @@
  *
  *  \param fragments the list of fragments to join
  *  \param between a string to place between adjacent items in the input list
- *  \param attr the attribute with which to display between
  */
 fragment *join_fragments(const std::vector<fragment *> &fragments,
-			 const std::string &between, int attr=A_NORMAL);
+			 const std::string &between);
 
 /** Create a flowbox.
  *
@@ -245,22 +237,21 @@
  *  - %s: substitutes a const char * into the sequence being built
  *  - %n: substitutes a newline fragment into the sequence being built
  *  - %%: inserts a literal %
- *  - %B/%b: enable/disable the bold character attribute
- *  - %R/%r: enable/disable the reverse video character attribute
- *  - %D/%d: enable/disable the dim character attribute
- *  - %A: set the text attributes to the corresponding vararg parameter
- *  - %C: set the text attributes to the color corresponding to a
- *        string (looked up via get_color).
+ *  - %B/%b: toggle the bold character attribute
+ *  - %R/%r: toggle the reverse video character attribute
+ *  - %D/%d: toggle the dim character attribute
+ *  - %S: Apply the style corresponding to a
+ *        string (looked up via get_style) to the attributes.
  *
  *  For instance,
  *
- *   fragf("%C%BWARNING%b: something bad happened in routine %s,"
+ *   fragf("%S%BWARNING%b: something bad happened in routine %s,"
  *         "expect a segfault.", "Error", some_routine);
  *
  *  Note: if you use a parameter index multiple times, you are virtually
  *  GUARANTEED to segfault!
  *
- *  Note 2: format should not contain literal newlines.
+ *  Note 2: as usual, format should not contain literal newlines.
  *
  *  \param format the format string
  *  \return the formatted fragment, or NULL if there is an error in the format.