Back to index

texmacs  1.0.7.15
wk_widget.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : wk_widget.cpp
00004 * DESCRIPTION: Definition of abstract native widgets
00005 * COPYRIGHT  : (C) 1999  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "window.hpp"
00013 #include "Widkit/wk_widget.hpp"
00014 #include "Widkit/Event/basic_event.hpp"
00015 #include "analyze.hpp"
00016 #include "font.hpp"
00017 
00018 /******************************************************************************
00019 * Widget construction and destruction
00020 ******************************************************************************/
00021 
00022 extern int widget_count;
00023 wk_widget_rep::wk_widget_rep (
00024   array<wk_widget> a2, array<string> n2, gravity grav2):
00025     win (NULL), ox (0), oy (0), w (0), h (0),
00026     grav (grav2), a (a2), name (n2) { TM_DEBUG(widget_count++); }
00027 
00028 wk_widget_rep::~wk_widget_rep () { TM_DEBUG(widget_count--); }
00029 
00030 /******************************************************************************
00031 * Computing lower left and upper right widget coordinates
00032 ******************************************************************************/
00033 
00034 SI
00035 get_dx (gravity grav, SI w) {
00036   switch (grav) {
00037   case north_west: case west: case south_west:
00038     return 0;
00039   case north: case center: case south:
00040     return (w/(2*PIXEL))*PIXEL;
00041   case north_east: case east: case south_east:
00042     return w;
00043   }
00044   FAILED ("unknown gravity");
00045   return 0;
00046 }
00047 
00048 SI
00049 get_dy (gravity grav, SI h) {
00050   switch (grav) {
00051   case north_west: case north: case  north_east:
00052     return 0;
00053   case west: case center: case east:
00054     return ((-h)/(2*PIXEL))*PIXEL;
00055   case south_west: case south: case south_east:
00056     return -h;
00057   }
00058   FAILED ("unknown gravity");
00059   return 0;
00060 }
00061 
00062 SI
00063 wk_widget_rep::x1 () {
00064   return ox- get_dx (grav, w);
00065 }
00066 
00067 SI
00068 wk_widget_rep::y1 () {
00069   return oy- get_dy (grav, h)- h;
00070 }
00071 
00072 SI
00073 wk_widget_rep::x2 () {
00074   return ox- get_dx (grav, w)+ w;
00075 }
00076 
00077 SI
00078 wk_widget_rep::y2 () {
00079   return oy- get_dy (grav, h);
00080 }
00081 
00082 /******************************************************************************
00083 * Finding and assigning children by name
00084 ******************************************************************************/
00085 
00086 static string
00087 get_first (string s) {
00088   int i;
00089   for (i=0; i<N(s); i++)
00090     if (s[i] == '|') return s (0, i);
00091   return s;
00092 }
00093 
00094 wk_widget
00095 wk_widget::operator [] (string s) {
00096   string l= get_first (s);
00097   wk_widget w;
00098   (*this) << get_widget (l, w);
00099   if (l==s) return w;
00100   else return w [s (N(l)+1, N(s))];
00101 }
00102 
00103 /******************************************************************************
00104 * Other routines
00105 ******************************************************************************/
00106 
00107 bool
00108 wk_widget_rep::attached () {
00109   return win != NULL;
00110 }
00111 
00112 bool
00113 wk_widget_rep::is_window_widget () {
00114   return false;
00115 }
00116 
00117 void
00118 wk_widget_rep::wk_error (string message) {
00119   cerr << "\n------------------------------------------------------------------------------\n";
00120   cerr << wk_widget (this);
00121   cerr << "------------------------------------------------------------------------------\n";
00122   cerr << "Error: " << message << "\n";
00123 }
00124 
00125 wk_widget
00126 operator << (wk_widget w, event ev) {
00127   if (!w->handle (ev))
00128     cerr << "Warning: " << ((tree) ev)
00129         << " cannot be handled by\n" << w << "\n";
00130   return w;
00131 }
00132 
00133 static void
00134 print_tree (tm_ostream& out, tree t, int tab) {
00135   int i;
00136   for (i=0; i<tab; i++) out << "| ";
00137   if (is_atomic (t)) out << as_string (t) << "\n";
00138   else {
00139     out << as_string (t[0]) << "\n";
00140     for (i=1; i<N(t); i++) print_tree (out, t[i], tab+1);
00141   }
00142 }
00143 
00144 tm_ostream&
00145 wk_widget_rep::print (tm_ostream& out) {
00146   print_tree (out, operator tree (), 0);
00147   return out;  
00148 }
00149 
00150 tm_ostream&
00151 operator << (tm_ostream& out, wk_widget w) {
00152   print_tree (out, (tree) w, 0);
00153   return out;
00154 }
00155 
00156 /******************************************************************************
00157 * Pointer grabbing
00158 ******************************************************************************/
00159 
00160 void
00161 wk_grab_pointer (wk_widget w) {
00162   ASSERT (!is_nil (w) && w->win != NULL, "widget should be attached");
00163   w->win->set_mouse_grab (abstract (w), true);
00164 }
00165 
00166 void
00167 wk_ungrab_pointer (wk_widget w) {
00168   ASSERT (!is_nil (w) && w->win != NULL, "widget should be attached");
00169   w->win->set_mouse_grab (abstract (w), false);
00170 }
00171 
00172 bool
00173 wk_has_pointer_grab (wk_widget w) {
00174   return !is_nil (w) && w->win != NULL &&
00175     w->win->get_mouse_grab (abstract (w));
00176 }
00177 
00178 /******************************************************************************
00179 * Length conversions
00180 ******************************************************************************/
00181 
00182 #define SHRINK 3
00183 
00184 SI
00185 decode_length (string width, wk_widget wid, int style) {
00186   SI ex, ey;
00187   if (wid->win == NULL) gui_maximal_extents (ex, ey);
00188   else wid->win->get_size (ex, ey);
00189   if (ends (width, "w") && is_double (width (0, N(width) - 1))) {
00190     double x= as_double (width (0, N(width) - 1));
00191     return (SI) (x * ex);
00192   }
00193   else if (ends (width, "h") && is_double (width (0, N(width) - 1))) {
00194     double y= as_double (width (0, N(width) - 1));
00195     return (SI) (y * ey);
00196   }
00197   else if (ends (width, "em") && is_double (width (0, N(width) - 2))) {
00198     font fn= get_default_styled_font (style);
00199     double x= as_double (width (0, N(width) - 2));
00200     return (SI) ((x * fn->wquad) / SHRINK);
00201   }
00202   else if (ends (width, "px") && is_double (width (0, N(width) - 2))) {
00203     double x= as_double (width (0, N(width) - 2));
00204     return (SI) (x * PIXEL);
00205   }
00206   else return ex;
00207 }