style.h

00001 // style.h   -*-c++-*-
00002 //
00003 //   Copyright (C) 2005 Daniel Burrows
00004 //
00005 //   This program is free software; you can redistribute it and/or
00006 //   modify it under the terms of the GNU General Public License as
00007 //   published by the Free Software Foundation; either version 2 of
00008 //   the License, or (at your option) any later version.
00009 //
00010 //   This program is distributed in the hope that it will be useful,
00011 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 //   General Public License for more details.
00014 //
00015 //   You should have received a copy of the GNU General Public License
00016 //   along with this program; see the file COPYING.  If not, write to
00017 //   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018 //   Boston, MA 02111-1307, USA.
00019 
00020 #ifndef STYLE_H
00021 #define STYLE_H
00022 
00023 #define _XOPEN_SOURCE_EXTENDED
00024 #include <ncursesw/curses.h>
00025 #undef _XOPEN_SOURCE_EXTENDED
00026 
00027 #include <cwidget/curses++.h>
00028 
00029 #include <string>
00030 
00031 #include <cwidget/config/colors.h>
00032 
00033 #include <cwidget/generic/util/eassert.h>
00034 
00035 namespace cwidget
00036 {
00053   class style
00054   {
00056     short fg;
00060     short bg;
00061 
00063     attr_t set_attrs;
00065     attr_t clear_attrs;
00069     attr_t flip_attrs;
00070 
00071     // Note: it is assumed that set_attrs and clear_attrs are pairwise
00072     // disjoint.
00073 
00074   public:
00076     style():fg(-1), bg(-2), set_attrs(0), clear_attrs(0), flip_attrs(0)
00077     {
00078     }
00079 
00083     void set_fg(short _fg) {if(_fg >= 0) fg=_fg;}
00084 
00088     void set_bg(short _bg) {if(_bg >= -1) bg = _bg;}
00089 
00091     void attrs_on(attr_t attrs)
00092     {
00093       set_attrs|=attrs;
00094       clear_attrs&=~attrs;
00095       flip_attrs&=~attrs;
00096     }
00097 
00099     void attrs_off(attr_t attrs)
00100     {
00101       clear_attrs|=attrs;
00102       set_attrs&=~attrs;
00103       flip_attrs&=~attrs;
00104     }
00105 
00107     void attrs_flip(attr_t attrs)
00108     {
00109       flip_attrs^=attrs;
00110     }
00111 
00115     void apply_style(const style &other)
00116     {
00117       set_fg(other.fg);
00118       set_bg(other.bg);
00119       attrs_on(other.set_attrs);
00120       attrs_off(other.clear_attrs);
00121       attrs_flip(other.flip_attrs);
00122     }
00123 
00127     style operator+(const style &other) const
00128     {
00129       style rval(*this);
00130       rval+=other;
00131       return rval;
00132     }
00133 
00135     style &operator+=(const style &other)
00136     {
00137       apply_style(other);
00138       return *this;
00139     }
00140 
00141     bool operator==(const style &other) const
00142     {
00143       return fg == other.fg && bg == other.bg &&
00144         set_attrs == other.set_attrs && clear_attrs == other.clear_attrs &&
00145         flip_attrs == other.flip_attrs;
00146     }
00147 
00148     bool operator!=(const style &other) const
00149     {
00150       return fg != other.fg || bg != other.bg ||
00151         set_attrs != other.set_attrs || clear_attrs != other.clear_attrs ||
00152         flip_attrs != other.flip_attrs;
00153     }
00154 
00156     short get_fg() const {return fg<0?0:fg;}
00158     short get_bg() const {return bg<0?0:bg;}
00160     attr_t get_attrs() const
00161     {
00162       attr_t rval=0;
00163       rval |=  set_attrs;
00164       rval &= ~clear_attrs;
00165       rval ^=  flip_attrs;
00166       rval |=  config::mix_color(0, fg, bg);
00167       if(fg == bg)
00168         rval |= A_INVIS;
00169       return rval;
00170     }
00171 
00173     chtype apply_to(chtype ch) const
00174     {
00175       // Relies somewhat on the bitwise representation of attributes;
00176       // the multicharacter-capable stuff needed for utf8 will make this
00177       // go away (for better or for worse..)
00178       return (ch & A_CHARTEXT) |
00179         config::mix_color(ch, fg, bg) |
00180         ((((ch & ~ (A_CHARTEXT | A_COLOR)) | set_attrs) & ~clear_attrs) ^ flip_attrs);
00181     }
00182 
00184     wchtype apply_to(wchtype ch) const
00185     {
00186       // Relies somewhat on the bitwise representation of attributes;
00187       // the multicharacter-capable stuff needed for utf8 will make this
00188       // go away (for better or for worse..)
00189       return wchtype(ch.ch,
00190                      config::mix_color(ch.attrs, fg, bg) |
00191                      ((((ch.attrs & ~ A_COLOR) | set_attrs) & ~clear_attrs) ^ flip_attrs));
00192     }
00193   };
00194 
00195   // To allow styles to be built functionally, the following
00196   // 'constructors' are provided.  The main idea here is to make
00197   // default-setting more compact and less obscure.
00198 
00202   inline style style_fg(short fg)
00203   {
00204     style rval;
00205     rval.set_fg(fg);
00206     return rval;
00207   }
00208 
00212   inline style style_bg(short bg)
00213   {
00214     style rval;
00215     rval.set_bg(bg);
00216     return rval;
00217   }
00218 
00221   inline style style_attrs_on(attr_t attrs)
00222   {
00223     style rval;
00224     rval.attrs_on(attrs);
00225     return rval;
00226   }
00227 
00229   inline style style_attrs_off(attr_t attrs)
00230   {
00231     style rval;
00232     rval.attrs_off(attrs);
00233     return rval;
00234   }
00235 
00237   inline style style_attrs_flip(attr_t attrs)
00238   {
00239     style rval;
00240     rval.attrs_flip(attrs);
00241     return rval;
00242   }
00243 
00248   const style &get_style(const std::string &name);
00249 
00251   void set_style(const std::string &name, const style &style);
00252 }
00253 
00254 #endif // STYLE_H

Generated on Mon Feb 16 01:16:31 2009 for cwidget by  doxygen 1.4.6