/*******************************************************************************
+
+  LEDA 7.2.3  
+
+
+  window.h
+
+
+  Copyright (c) 1995-2026
+  by Algorithmic Solutions Software GmbH
+  All rights reserved.
+ 
*******************************************************************************/


#ifndef LEDA_WINDOW_H
#define LEDA_WINDOW_H

#if !defined(LEDA_ROOT_INCL_ID)
#define LEDA_ROOT_INCL_ID 723215
#include <LEDA/internal/PREAMBLE.h>
#endif

#include <LEDA/graphics/base_window.h>
#include <LEDA/geo/plane.h>

LEDA_BEGIN_NAMESPACE

/*{\Moptions usesubscripts=yes}*/


typedef void (*show_coord_handler_func)(window*,double,double);


/*{\Manpage {window} {} {Windows}}*/

class __exportC GraphWin;
class __exportGeoW  GeoWinTypeName;

class __exportC window : public BASE_WINDOW {

friend class __exportC GraphWin;
friend class __exportGeoW  GeoWinTypeName;

/*{\Mdefinition
The data type $window$ provides an interface for graphical input and output 
of basic two-dimensional geometric objects.
Application programs using this data type have to be linked with {\em libW.a} 
and (on UNIX systems) with the X11 base library {\em libX11.a}
(cf.~section~1.6):

CC $prog.c$ -lW -lP -lG -lL -lX11 -lm

An instance $W$ of type $window$ is an iso-oriented rectangular window in the 
two-dimensional plane. The default representation of $W$ on the screen is a 
square of maximal possible edge length positioned in the upper right corner 
of the display. 

In general, a window consists of two rectangular sections,
a {\em panel section} in the upper part and 
a {\em drawing section} in the rest of the window. 
The panel section  contains {\em panel items} such as sliders, choice
fields, string items and buttons. They have to be created before
the window is opened by special panel operations described in section
\ref{panel-operations}.

The drawing section can be used for the output of geometric objects such
as points, lines, segments, arrows, circles, polygons, graph, \dots and 
for the input of all these objects using the mouse input device.  
All drawing and input operations in the drawing section use a
coordinate system that is defined by three parameters of type $double$: 
$xmin$, the minimal x-coordinate, $xmax$, the maximal x-coordinate, 
and $ymin$, the minimal y-coordinate. The two parameters $xmin$ and $xmax$
define the scaling factor $scaling$  as $w/(xmax-xmin)$, where $w$ is the width 
of the drawing section in pixels. The maximal y-coordinate $ymax$ of the
drawing section is equal to $ymin + h \cdot  scaling$ and depends on the 
actual shape of the window on the screen. Here, $h$ is the height of the
drawing section in pixels.


A list of all window parameters:

\begin{enumerate}

\item
The {\em foreground color} parameter (default $black$) defines 
the default color to be used in all drawing operations.
There are 18 predefined colors (enumeration in \<LEDA/graphics/x\_window.h\>):
$black$, $white$, $red$, $green$, $blue$, $yellow$, $violet$, $orange$,
$cyan$, $brown$, $pink$, $green2$, $blue2$, $grey1$, $grey2$, $grey3$
$ivory$, and $invisible$. 
Note that all drawing operations have an optional color argument that can
be used to override the default foreground color.
The color $invisible$ can be used for invisible (transparent) objects.


\item
The {\em background color} parameter (default $white$) defines
the default background color (e.g. used by $W$.clear()).

\item
The {\em text font} parameter defines the name of the font to be used
in all text drawing operations.

\item
Minimal and maximal coordinates of the drawing area
$xmin$ (default 0), $xmax$ (default 100), $ymin$ (default 0).

\item
The {\em grid dist} parameter (default 0) defines the width of the
grid that is used in the drawing area. A grid width of 0 indicates
that no grid is to be used.

\item
The {\em frame label} parameter defines a string to be displayed
in the frame of the window.

\item
The {\em show coordinates} flag  (default $true$) determines whether
the current coordinates of the mouse cursor in the drawing section
are displayed in the upper right corner.

\item
The {\em flush output} flag  (default $true$) determines whether
the graphics output stream is flushed after each draw action.

\item
The {\em line width} parameter (default value 1 pixel) defines the width of all
kinds of lines (segments, arrows, edges, circles, polygons).

\item
The {\em line style} parameter defines the style of lines. Possible line
styles are |solid| (default), |dashed|, and |dotted|.

\item
The {\em point style} parameter defines the style points are drawn by 
the |draw_point| operation. Possible point styles are |pixel_point|, 
|cross_point| (default), |plus_point|, |circle_point|, |disc_point|, 
|rect_point|, and |box_point|.

\item
The {\em node width} parameter (default value 8 pixels) defines the diameter
of nodes created by the draw\_node and draw\_filled\_node operations.

\item
The {\em text mode} parameter defines how text is inserted into the window.
Possible values are |transparent| (default)  and |opaque|.

\item 
The {\em show orientation} parameter defines, whether or not the direction
or orientation of segments, lines, rays, triangles, polygons and gen\_polygons
will be shown (default |false|.)

\item
The {\em drawing mode} parameter defines the logical operation that is used
for setting pixels in all drawing operations. Possible values are
|src_mode| (default) and |xor_mode|. In |src_mode| pixels are set to
the respective color value, in |xor_mode| the value is bitwise added to the
current pixel value.

\item
The {\em redraw function} parameter is a pointer to a function of type 
void ($*$F)(window$*$). It is called with a pointer to the corresponding window
as argument to redraw (parts of) the window whenever a redrawing 
is necessary, e.g., if the shape of the window is changed or previously
hidden parts of it become visible. 

\item
The {\em window close handler} parameter is a pointer to a function of type 
void ($*$F)(window$*$). It is called with a pointer to the corresponding window
as argument when the window is to be closed by the window manager (e.g. by
pressing the $\times$-button on Windows-NT systems). The default
window close handler closes the window and terminates the program.

\item
The {\em buttons per line} parameter (default $\infty$) defines
the maximal number of buttons in one line of the panel section.


\item
The {\em precision} parameter (default $16$) defines the precision
that is used for representing window coordinates, more precisely,
all $x$ and $y$ coordinates generated by window input operations 
are doubles whose mantissa are truncated after $precision-1$ bits
after the binary point.


\end{enumerate} 

In addition to call-back (handler) functions LEDA windows now also
support the usage of function objects. Function object classes have
to be derived from the |window_handler| base class.
\begin{verbatim}
class window_handler {
  ...
  virtual void operator()() { }
  
  // parameter access functions
  double  get_double(int nr) const;
  int     get_int() const; 
  window* get_window_ptr() const;
  char*   get_char_ptr() const;
};
\end{verbatim}

Derived classes have to implement the handling function in the definition
of the |operator()| method. The different |get_| methods can be
called to retrieve parameters.

If both, a handler function and an object for the same action is supplied
the object has higher priority.\\
}*/


private: 


// windows cannot be copied, use reference parameters! 

window(const window&) { }
window& operator=(const window&) { return *this; }

char* access_str(GenPtr p) { return ((string*)p)->cstring(); }
void  assign_str(GenPtr p, const char* s) { *((string*)p) = s; }

point* point_buffer;

public:

static color fgcol;
static color bgcol;

static int dpi() { return BASE_WINDOW::screen_dpi(); }

static void win_error_handler(int i, const char* s);

bool normalize_rat;
bool show_orientation;


/*{\Mcreation W }*/ 

window();
/*{\Mcreate creates a squared window with maximal possible edge length
            (minimum of width and height of the display).}*/


window(const char* label);
/*{\Mcreate creates a maximal squared window with frame label $label$.}*/

window(int w, int h);
/*{\Mcreate creates a window $W$ of physical size $w$ pixels 
            $\times$ $h$ pixels .}*/


window(int w, int h, const char* label);
/*{\Mcreate creates a window $W$ of physical size $w$ pixels 
            $\times$ $h$ pixels and frame label $label$.}*/



/*{\Mtext

\medskip
All four variants initialize the coordinates of $W$ to $xmin = 0$,
$xmax = 100$ and $ymin = 0$. The $init$ operation (see  below) can later
be used to change the window coordinates and scaling. Please note, that a 
window is not displayed before the function $display$ is called for it.}*/


~window() {}


/*{\Moperations 3.1 4.4}*/

/*{\Mtext
{\bf 3.1 Initialization} }*/

void init(double x0, double x1, double y0) { BASE_WINDOW::init(x0,x1,y0); }
/*{\Mopl     sets $xmin$ to $x_0$, $xmax$ to $x_1$, and $ymin$ to $y_0$, 
             the scaling factor $scaling$ to $w / (xmax-xmin)$, and 
             $ymax$ to $ymin + h/scaling$. Here $w$ and $h$ are the
             width and height of the drawing section in pixels. }*/

/*{\Moptions nextwarning=no}*/
void init_rectangle(double x0, double x1, double y0, double y1) 
{ BASE_WINDOW::init(x0,x1,y0,y1); }

void init(double x0, double x1, double y0, double y1) 
{ BASE_WINDOW::init(x0,x1,y0,y1); }
/*{\Mopl     adjusts the window such that the points $(x_0,y_0)$ and 
             $(x_1,y_1)$ are contained in the drawing section. }*/

double set_grid_dist(double d) 
{ return BASE_WINDOW::set_grid_dist(d); }
/*{\Mopl     sets the grid distance of $W$ to $d$. }*/

grid_style set_grid_style(grid_style s) 
{ return BASE_WINDOW::set_grid_style(s); }
/*{\Mopl     sets the grid style of $W$ to $s$. }*/

int set_grid_mode(int d) 
{ return BASE_WINDOW::set_grid_mode(d); }
/*{\Mopl     sets the grid distance of $W$ to $d$ pixels. }*/

bool set_normalize_rational_objects(bool b)
{ bool prev = normalize_rat; 
  normalize_rat = b;
  return prev;
}

int set_precision(int prec) 
{ return BASE_WINDOW::set_precision(prec); }
/*{\Mopl     sets the precision of $W$ to $prec$. }*/


void init(double x0, double x1, double y0, int d, bool erase=true) 
{ BASE_WINDOW::init(x0,x1,y0,d,erase); }
/*{\Mopl     same as $W$.init($x_0,x_1,y_0$) followed by 
             $W$.set\_grid\_mode($d$). If the optional flag |erase| is
             set to |false| the window will not be erased. }*/


void display() { BASE_WINDOW::display(window::center,window::center,0); }
/*{\Mopl      opens $W$ and displays it at the center of the screen.
              Note that $W$.display() has to be called before
              all drawing operations and that all operations adding panel 
              items to $W$ (cf. \ref{panel-operations}) have to be called 
              before the first call of $W$.display(). }*/

void display(int x, int y) { BASE_WINDOW::display(x,y,0); }
/*{\Mopl      opens $W$ and displays it with its left upper corner at position
              $(x,y)$. Special 
              values for $x$ and $y$ are  $window::min$, $window::center$, 
              and $window::max$ for positioning $W$ at the minimal or maximal 
              $x$ or $y$ coordinate or centering it in the $x$ or $y$ 
              dimension. }*/

/*{\Moptions nextwarning=no}*/
void display(window& W0, int x, int y) { BASE_WINDOW::display(x,y,&W0); }
void display(int x, int y, window& W0) { BASE_WINDOW::display(x,y,&W0); }
/*{\Mopl      opens $W$ and displays it with its left upper corner at position 
              $(x,y)$ relative to the upper left corner of  window $W_0$.   }*/ 
/*{\Mtext
$W.open$\dots can be used as a synonym for $W.display$\dots\ Note,
that the $open$ operation for panels (cf. \ref{Panels}) is defined 
slightly different.}*/

void open()                        { display(); }
void open(int x, int y)            { display(x,y); }
void open(window& w, int x, int y) { display(w,x,y); }
void open(int x, int y, window& w) { display(x,y,w); }

void open_hidden() { BASE_WINDOW::display(0, 0, 0, true); }


void close() { BASE_WINDOW::close(); }
/*{\Mopl      closes $W$ by removing it from the display. }*/


void clear() { BASE_WINDOW::clear(); }
/*{\Mopl      clears $W$ using the current background color or pixmap,
              i.e., if $W$ has a background pixmap defined it is tiled with
              $P$ such that the upper left corner is the tiling origin.
              Otherwise, it is filled with background color of $W$. }*/

void clear(double x0,double y0,double x1,double y1)
{ BASE_WINDOW::clear(x0,y0,x1,y1); }
/*{\Mopl      only clears the rectangular area $(x0,y0,x1,y1)$ of window $W$
              using the current background color or pixmap.}*/

void clear(double x0,double y0,double x1,double y1, double xorig, double yorig)
{ BASE_WINDOW::clear(x0,y0,x1,y1,xorig,yorig); }


void clear(color c) { BASE_WINDOW::clear(c); }
/*{\Mopl      clears $W$ with color $c$ and sets the background color of $W$
              to $c$. }*/

void clear(double xorig, double yorig) { BASE_WINDOW::clear(xorig,yorig); }
/*{\Mopl      clears $W$. If a background pixmap is defined the point
              $(xorig,yorig)$ is used as the origin of tiling. }*/

void redraw() { BASE_WINDOW::redraw(); }
/*{\Mop      repaints the drawing area if $W$ has a redraw function.}*/ 



/*{\Mtext
{\bf 3.2 Setting parameters}\label{parameters} }*/

/*
color set_fg_color(color c) { return BASE_WINDOW::set_fg_color(c); }
*/

color set_color(color c) { return BASE_WINDOW::set_fg_color(c); }
/*{\Mopl     sets the foreground color parameter to $c$ and
	     returns its previous value.}*/


color set_fill_color(color c) { return BASE_WINDOW::set_fill_color(c); }
/*{\Mopl     sets the fill color parameter (used by |<<| operators) 
             to $c$ and returns its previous value.}*/



color set_bg_color(color c) { return BASE_WINDOW::set_bg_color(c); }
/*{\Mopl     sets the background color parameter to $c$ and
	     returns its previous value.}*/

char* set_bg_pixmap(char* pr) { return BASE_WINDOW::set_bg_pixrect(pr); }
/*{\Mopl     sets the background pixmap to $pr$ and
	     returns its previous value.}*/


int set_line_width(int pix){return BASE_WINDOW::set_line_width(pix);}
/*{\Mopl     sets the line width parameter to $pix$ pixels and
	     returns its previous value.}*/

line_style set_line_style(line_style s)
{return BASE_WINDOW::set_line_style(s);}
/*{\Mopl     sets the line style parameter to $s$ and returns its
	     previous value.}*/

int set_node_width(int pix) {return BASE_WINDOW::set_node_width(pix);}
/*{\Mopl     sets the node width parameter to $pix$ pixels and
	     returns its previous value.}*/

text_mode set_text_mode(text_mode m)
{return BASE_WINDOW::set_text_mode(m);}
/*{\Mopl     sets the text mode parameter to $m$ and returns
	     its previous value.}*/

drawing_mode set_mode(drawing_mode m)
{return BASE_WINDOW::set_mode(m);}
/*{\Mopl     sets the drawing mode parameter to $m$ and returns 
	     its previous value.}*/

int          set_cursor(int cursor_id = -1)
{return BASE_WINDOW::set_cursor(cursor_id);}
/*{\Mopl     sets the mouse cursor of $W$ to |cursor_id|. Here |cursor_id| 
             must be one of the constants  predefined in |<X11/cursorfont.h>|
             or $-1$ for the system default cursor. Returns the previous 
             cursor. }*/

void set_show_coordinates(bool b) { BASE_WINDOW::set_show_coordinates(b); }
/*{\Mopl     sets the show coordinates flag to $b$. }*/

bool set_show_orientation(bool orient)
/*{\Mop      sets the show orientation parameter to $orient$.}*/
{ bool prev = show_orientation; show_orientation = orient;
  return prev; 
}

void set_frame_label(string s){ BASE_WINDOW::set_frame_label(s); }
/*{\Mopl     makes $s$ the window frame label. }*/

void set_icon_label(string s){ BASE_WINDOW::set_icon_label(s); }
/*{\Mopl     makes $s$ the window icon label. }*/

void reset_frame_label() { BASE_WINDOW::reset_frame_label(); }
/*{\Mop      restores the standard LEDA frame label. }*/


void set_window_close_handler(void (*F)(window*)) 
{ BASE_WINDOW::set_window_close_handler((win_close_handler_func)F);}
/*{\Mopl     sets the window close handler function to $F$.}*/

void set_window_close_object(const window_handler& obj)
{ BASE_WINDOW::set_window_close_object(obj); }
/*{\Mopl     sets the window delete object to $obj$.}*/

void set_event_handler(int (*F)(window*,int,int,double,double,unsigned long)) 
{ BASE_WINDOW::set_event_handler((event_handler_func)F);}

show_coord_handler_func get_show_coord_handler() const
{ return (show_coord_handler_func)BASE_WINDOW::get_coord_handler(); }

void set_show_coord_handler(void (*F)(window*,double,double)) 
{ BASE_WINDOW::set_coord_handler((coord_handler_func)F);}
/*{\Mopl     sets the show coordinate handler function to $F$.}*/

void set_show_coord_object(const window_handler& obj)
{ BASE_WINDOW::set_coord_object(obj); }
/*{\Mopl     sets the show coordinate object to $obj$.}*/

void set_redraw(void (*F)(window*)) 
{ BASE_WINDOW::set_redraw((win_redraw_func1)F);}
/*{\Mopl     sets the redraw function to $F$.}*/

void set_redraw(const window_handler& obj)
{ BASE_WINDOW::set_redraw(obj); }
/*{\Mopl     sets the redraw object to $obj$.}*/

void set_redraw(void (*F)(window*,double,double,double,double)=0) 
{ BASE_WINDOW::set_redraw((win_redraw_func2)F);}
/*{\Mopl     sets the redraw function to $F$.}*/

void set_redraw2(const window_handler& obj)
{ BASE_WINDOW::set_redraw2(obj); }
/*{\Mopl     sets the redraw object to $obj$.}*/


void set_redraw(void (*F)()) { BASE_WINDOW::set_redraw((win_redraw_func0)F);}
/*{\Xopl     for backward compatibility. }*/

void set_bg_redraw(void (*F)(window*,double,double,double,double)=0) 
{ BASE_WINDOW::set_bg_redraw((win_redraw_func2)F);}
/*{\Mopl     sets the background redraw function to $F$.}*/

void set_bg_redraw(const window_handler& obj) 
{ BASE_WINDOW::set_bg_redraw(obj); }
/*{\Mopl     sets the background redraw object to $obj$.}*/


void start_timer(int msec, void (*F)(window*)) 
{ BASE_WINDOW::start_timer(msec,(win_redraw_func1)F);}
/*{\Mopl   starts a timer that runs $F$ every |msec| milliseconds
           with a pointer to |\Mvar|.}*/
	   
void start_timer(int msec, const window_handler& obj)
{ BASE_WINDOW::start_timer(msec,obj); }
/*{\Mopl   starts a timer that runs the $operator()$ of $obj$ every |msec| milliseconds.}*/


void stop_timer() { BASE_WINDOW::stop_timer(); }
/*{\Mopl   stops the timer.}*/


void set_flush(bool b)     { BASE_WINDOW::set_flush(b); }
/*{\Mopl     sets the flush parameter to $b$.}*/

void set_icon_pixrect(char* pr)  { BASE_WINDOW::set_icon_pixrect(pr); }
/*{\Mopl     makes |pr| the new icon of |\Mvar|. }*/


void* set_client_data(void* p, int i=0) { return BASE_WINDOW::set_inf(p,i); }
/*{\Mopl    sets the $i$-th client data pointer of |\Mvar| to $p$ and 
            returns its previous value. \precond $i < 16$. }*/ 



//bool load_text_font(string fn)    { return BASE_WINDOW::load_text_font(fn)!=0; }
/*{\Xopl      loads $X11$ font $fn$ as text font. Returns true on success and 
              false if the font is not available.}*/

//bool load_bold_font(string fn)    { return BASE_WINDOW::load_bold_font(fn)!=0; }
/*{\Xopl      loads $X11$ font $fn$ as bold font. Returns true on success and 
              false if the font is not available.}*/

//bool load_fixed_font(string fn) { return BASE_WINDOW::load_fixed_font(fn)!=0;  }
/*{\Xopl      load $X11$ font $fn$ as fixed font. Returns true on success 
              and false if the font is not available.}*/

//bool load_button_font(string fn) { return BASE_WINDOW::load_button_font(fn)!=0;}
/*{\Xopl      load $X11$ font $fn$ as button font. Returns true on success 
              and false if the font is not available.}*/


/*{\Mtext
{\bf 3.3 Reading parameters} }*/

bool get_normalize_rational_objects() const { return normalize_rat; }


int get_line_width() const {return BASE_WINDOW::get_line_width();}
/*{\Mop      returns the current line width.}*/ 

line_style get_line_style() const {return BASE_WINDOW::get_line_style();}
/*{\Mop      returns the current line style.}*/ 

int get_node_width() const {return BASE_WINDOW::get_node_width();}
/*{\Mop      returns the current node width.}*/ 

text_mode get_text_mode() const {return BASE_WINDOW::get_text_mode();}
/*{\Mop      returns the current text mode.}*/ 

drawing_mode get_mode() const {return BASE_WINDOW::get_mode();}
/*{\Mop      returns the current drawing mode.}*/ 

int          get_cursor() const {return BASE_WINDOW::get_cursor();}
/*{\Mop      returns the id of the current cursor, i.e, one of the constants
             predefined in <X11/cursorfont.h> or $-1$ for the default
             cursor. }*/ 

double xmin() const {return BASE_WINDOW::xmin();}
/*{\Mop      returns the minimal x-coordinate of the drawing area of $W$.}*/ 

double ymin() const {return BASE_WINDOW::ymin();}
/*{\Mop      returns the minimal y-coordinate of the drawing area of $W$.}*/ 

double xmax() const {return BASE_WINDOW::xmax();}
/*{\Mop      returns the maximal x-coordinate of the drawing area of $W$.}*/ 

double ymax() const {return BASE_WINDOW::ymax();}
/*{\Mop      returns the maximal y-coordinate of the drawing area of $W$.}*/ 

double scale() const {return BASE_WINDOW::scale();}
/*{\Mop      returns the scaling factor of the drawing area of $W$, i.e. the 
             number of pixels of a unit length line segment.}*/

double       get_grid_dist()  const { return BASE_WINDOW::get_grid_dist(); }
/*{\Mop      returns the width of the current grid
             (zero if no grid is used). }*/

grid_style   get_grid_style() const 
{ return (grid_style) BASE_WINDOW::get_grid_style(); }
/*{\Mop      returns the current grid style. }*/


int          get_grid_mode()  const { return BASE_WINDOW::get_grid_mode(); }
/*{\Mop      returns the width of the current grid in pixels (zero if
             no grid is used). }*/

bool get_show_orientation() const
/*{\Mop      returns the show orientation parameter.}*/
{ return show_orientation; }

void* get_client_data(int i=0) const { return BASE_WINDOW::get_inf(i); }
/*{\Mop   returns the $i$-th client data pointer of of |\Mvar|. 
          \precond $i < 16$. }*/ 


GraphWin* get_graphwin() const { return BASE_WINDOW::get_graphwin(); }
/*{\Mop   returns a pointer to the |GraphWin| (see \ref{Graph Windows})
          that uses |\Mvar| as its display window or |NULL| if |\Mvar| 
          is not used by any |GraphWin|. }*/ 

GeoWinTypeName*   get_geowin() const { return BASE_WINDOW::get_geowin(); }
/*{\Mop   returns a pointer to the |GeoWin| (see Section \ref{GeoWin})
          that uses |\Mvar| as its display window or |NULL| if |\Mvar| 
          is not used by any |GeoWin|. }*/ 



int width() const { return BASE_WINDOW::width(); }
/*{\Mop      returns the width of $W$ in pixels.}*/ 

int height() const { return BASE_WINDOW::height(); }
/*{\Mop      returns the height of $W$ in pixels.}*/ 

int menu_bar_height() const { return BASE_WINDOW::mb_height(); }
/*{\Mop      returns the height of the menu bar of $W$ in pixels
             and $0$ if $W$ has no menu bar (see |W.make_menu_bar()|). }*/


int xpos() const { return BASE_WINDOW::xpos(); }
/*{\Mop      returns the x-coordinate of the upper left corner of 
             the frame of $W$. }*/ 

int ypos() const { return BASE_WINDOW::ypos(); }
/*{\Mop      returns the y-coordinate of the upper left corner of 
             the frame of $W$. }*/ 


operator void*() const { return (state==0) ? 0 : (void*)this; }

int  get_state() const { return state; }
/*{\Mop      returns the state of  $W$. }*/ 

void set_state(int stat) { state = stat; }
/*{\Mop      sets the state of $W$ to |stat|. }*/ 

bool contains(const point& p) const;
/*{\Mop returns true if $p$ lies in the drawing area. }*/


/*{\Mtext
{\bf 3.4 Drawing Operations}

All drawing operations have an optional color argument at the end of the
parameter list. If this argument is omitted the current foreground color 
(cf. section \ref{parameters}) of $W$ is used.
}*/



// points

/*{\Mtext
{\bf 3.4.1 Drawing points} 
\setopdims{1.2cm}{4.4cm}
}*/

void draw_point(double x, double y, color c=window::fgcol);
/*{\Mopl     draws the point $(x,y)$ (a cross of two short segments). }*/

void draw_point(const point& p, color c=window::fgcol);
/*{\Mopl     draws point $p$. }*/

/*{\Moptions nextwarning=no}*/
void draw_pix(double x, double y, color c=window::fgcol);
void draw_pixel(double x, double y, color c=window::fgcol) { draw_pix(x,y,c); }
/*{\Mopl     sets the color of the pixel at position $(x,y)$ to $c$. }*/


/*{\Moptions nextwarning=no}*/
void draw_pix(const point& p, color c=window::fgcol);
void draw_pixel(const point& p, color c=window::fgcol) { draw_pix(p,c); }
/*{\Mopl     sets the color of the pixel at position $p$ to $c$. }*/

void draw_pixels(const list<point>& L, color c=window::fgcol);
/*{\Mopl     sets the color of all pixels in $L$ to $c$. }*/

void draw_pixels(int n, double* xcoord, double* ycoord,
                                                color c=window::fgcol);
/*{\Mopl     draws all pixels $(xcoord[i],ycoord[i])$ for $0 \le i \le n-1$. }*/



// segments

/*{\Mtext
{\bf 3.4.2 Drawing line segments}
}*/

void draw_segment(double x1, double y1, double x2, double y2, color c=window::fgcol);
/*{\Mopl     draws a line segment from $(x_1,y_1)$ to $(x_2,y_2)$.}*/

void draw_segment(const point& p, const point& q, color c=window::fgcol);
/*{\Mopl     draws a line segment from point $p$ to point $q$.}*/

void draw_segment(const segment& s, color c=window::fgcol);
/*{\Mopl     draws line segment $s$.}*/


void draw_segment(point p, point q, line l, color c = window::fgcol);
/*{\Mop draws the part of the line $l$ between $p$ and $q$. This version of 
        |draw_segment| should be used if $p$ or $q$ may lie far outside $W$. 
        \precond $p$ and $q$ lie on $l$ or at least close to $l$. }*/


void draw_segments(const list<segment>& L, color c=window::fgcol);
/*{\Mopl     draws all segments in $L$.}*/


// lines

/*{\Mtext
{\bf 3.4.3 Drawing lines}
}*/

void draw_line(double x1, double y1, double x2, double y2, color c=window::fgcol);
/*{\Mopl     draws a straight line passing through points $(x_1,y_1)$ and 
	     $(x_2,y_2)$.}*/

void draw_line(const point& p, const point& q, color c=window::fgcol);
/*{\Mopl     draws a straight line passing through points $p$ and $q$.}*/

void draw_line(const segment& s, color c=window::fgcol);
/*{\Mopl     draws the line supporting segment $s$.}*/


void draw_line(const line& l, color c=window::fgcol);
/*{\Mopl     draws line $l$.}*/

void draw_hline(double y, color c=window::fgcol);
/*{\Mopl     draws a horizontal line with y-coordinate $y$. }*/

void draw_vline(double x, color c=window::fgcol);
/*{\Mopl     draws a vertical line with x-coordinate $x$. }*/



/*{\Mtext
{\bf 3.4.4 Drawing Rays}
}*/

void draw_ray(double x1, double y1, double x2, double y2, color c=window::fgcol);
/*{\Mopl     draws a ray starting in $(x_1,y_1)$ and passing through 
	     $(x_2,y_2)$.}*/

void draw_ray(const point& p, const point& q, color c=window::fgcol);
/*{\Mopl     draws a ray starting in $p$ and passing through $q$.}*/


void draw_ray(const segment& s, color c=window::fgcol);
/*{\Mopl     draws a ray starting in $s.source()$ containing $s$. }*/


void draw_ray(const ray& r, color c=window::fgcol);
/*{\Mopl     draws ray $r$.}*/


void draw_ray(point p, point q, line l, color c = window::fgcol);
/*{\Mop draws the part of the line $l$ on the ray with source 
        $p$ and passing through $q$. This version of |draw_ray| 
        should be used if $p$ may lie far outside $W$. \precond $p$ 
        and $q$ lie on $l$ or at least close to $l$. }*/



/*{\Mtext
{\bf 3.4.5 Drawing Arcs and Curves}
}*/

static void compute_bezier(const list<point>&, int,double*,double*);
static void bezier_segments(const list<point>&, int,segment&,segment&);

void draw_arc(point, point, point, int arr, double d, color);
void draw_bezier(const list<point>&, int n, int arr,double d,bool border,color);
void draw_spline(const list<point>&, int n, int arr,double d,bool border,color);


void draw_arc(const point& p, const point& q, const point& r, color c=window::fgcol);
/*{\Mopl     draws a circular arc starting in $p$ passing through $q$ and 
             ending in $r$. }*/

void draw_bezier(const list<point>& C, int n,  color c=window::fgcol);
/*{\Mopl     draws the bezier curve with control polygon $C$ by a polyline 
             with $n$ points. }*/


void draw_spline(const list<point>& L, int n,  color c=window::fgcol);
/*{\Mopl     draws a spline curve through the points of $L$. Each segment
             is approximated by a polyline with $m$ points. }*/

void draw_closed_spline(const list<point>& L, int n,  color c=window::fgcol);
/*{\Mopl     draws a {\em closed} spline through the points of $L$. }*/

void draw_spline(const polygon& P, int n,  color c=window::fgcol);
/*{\Mopl     draws a {\em closed} spline through the vertices of $P$. }*/



// arrows

/*{\Mtext
{\bf 3.4.6 Drawing arrows}
}*/

void draw_filled_arrow(const list<point>& L, int arrow, double d, bool border,
                                                        color=window::fgcol);


void draw_arrow(double x1, double y1, double x2, double y2, color c =window::fgcol);
/*{\Mopl     draws an arrow pointing from $(x_1,y_1)$ to $(x_2,y_2)$.}*/

void draw_arrow(const point& p, const point& q, color c=window::fgcol);
/*{\Mopl     draws an arrow pointing from point $p$ to point $q$.}*/

void draw_arrow(const segment& s, color=window::fgcol);
/*{\Mopl     draws an arrow pointing from $s$.start() to $s$.end().}*/

void draw_polyline_arrow(const list<point>& lp, color c=window::fgcol);
/*{\Mopl     draws a polyline arrow with vertex sequence $lp$.}*/


void draw_arc_arrow(const point& p, const point& q, const point& r, color c=window::fgcol);
/*{\Mopl     draws a circular arc arrow starting in $p$ passing through $q$ 
             and ending in $r$. }*/

void draw_bezier_arrow(const list<point>& C, int n,  color c=window::fgcol);
/*{\Mopl     draws the bezier curve with control polygon $C$ by a polyline 
             with $n$ points, the last segment is drawn as an arrow. }*/


void draw_spline_arrow(const list<point>& L, int n,  color c=window::fgcol);
/*{\Mopl     draws a spline curve through the points of $L$. Each segment
             is approximated by a polyline with $n$ points. The last
             segment is drawn as an arrow. }*/

static point arrow_head(const point&, double, double, double*, double*);
static int   arrow(const point&, const point&, double, int, double*, double*);
static int   arrow(const list<point>&, double, int, double*, double*);

point draw_arrow_head(const point& p, double dir, double d, color c);

point draw_arrow_head(const point& p, double dir, color c=window::fgcol);
/*{\Mopl     draws an arrow head at position $p$ pointing to direction $dir$,
             where $dir$ is an angle from $[0,2\pi]$. }*/



//circles

/*{\Mtext
{\bf 3.4.7 Drawing circles}
}*/

void draw_circle(double x, double y, double r, color c=window::fgcol);
/*{\Mopl     draws the circle with center $(x,y)$ and radius $r$.}*/

void draw_circle(const point& p, double r, color c=window::fgcol);
/*{\Mopl     draws the circle with center $p$ and radius $r$.}*/

void draw_circle(const circle& C, color c=window::fgcol);
/*{\Mopl     draws circle $C$.}*/


void draw_ellipse(double x, double y, double r1, double r2, color c=window::fgcol);
/*{\Mopl     draws the ellipse with center $(x,y)$ and radii $r_1$ and $r_2$.}*/

void draw_ellipse(const point& p, double r1, double r2, color c=window::fgcol);
/*{\Mopl     draws the ellipse with center $p$ and radii $r_1$ and $r_2$.}*/

// rotated ellipses

/*
void draw_ellipse(double x, double y, double r1, double r2, double phi, color c=window::fgcol);
*/
/*{\Mopl     draws the ellipse with center $(x,y)$ and radii $r_1$ and $r_2$ rotated by angle $phi$ around $p$.}*/

/*
void draw_ellipse(const point& p, double r1, double r2, double phi, color c=window::fgcol);
*/
/*{\Mopl     draws the ellipse with center $p$ and radii $r_1$ and $r_2$ rotated by angle $phi$ round $p$.}*/



/*{\Mtext
{\bf 3.4.8 Drawing discs}
}*/

void draw_disc(double x, double y, double r, color c=window::fgcol);
/*{\Mopl     draws a filled circle with center $(x,y)$ and radius $r$.}*/

void draw_disc(const point& p, double r, color c=window::fgcol);
/*{\Mopl     draws a filled circle with center $p$ and radius $r$.}*/

void draw_disc(const circle& C, color c=window::fgcol);
/*{\Mopl     draws filled circle $C$.}*/


void draw_filled_circle(double x, double y, double r, color c=window::fgcol)
{ draw_disc(x,y,r,c); }
/*{\Mopl     draws a filled circle with center $(x,y)$ and radius $r$.}*/

void draw_filled_circle(const point& p, double r, color c=window::fgcol)
{ draw_disc(p,r,c); }
/*{\Mopl     draws a filled circle with center $p$ and radius $r$.}*/

void draw_filled_circle(const circle& C, color c=window::fgcol)
{ draw_disc(C,c); }
/*{\Mopl     draws filled circle $C$.}*/


void draw_filled_ellipse(double x, double y, double r1, double r2, color c=window::fgcol);
/*{\Mopl  draws a filled ellipse with center $(x,y)$ and radii $r_1$ and $r_2$.}*/


/*
void draw_filled_ellipse(double x, double y, double r1, double r2, double phi, color c=window::fgcol);
*/
/*{\Mopl  draws a filled ellipse with center $(x,y)$ and radii $r_1$ and $r_2$ rotated by angle $phi$ around $(x,y)$.}*/


void draw_filled_ellipse(const point& p, double r1, double r2, color c=window::fgcol);
/*{\Mopl  draws a filled ellipse with center $p$ and radii $r_1$ and $r_2$.}*/

/*
void draw_filled_ellipse(const point& p, double r1, double r2, double phi, color c=window::fgcol);
*/
/*{\Mopl  draws a filled ellipse with center $p$ and radii $r_1$ and $r_2$ rotated by angle $phi$ around $p$.}*/


//polygons 

/*{\Mtext
{\bf 3.4.9 Drawing polygons }
}*/

void draw_polyline(const list<point>& lp, int arrow, double d, color c);

void draw_polyline(const list<point>& lp, const list<color>& clr);

void draw_polyline(const list<point>& lp, color c=window::fgcol);
/*{\Mopl     draws a polyline with vertex sequence $lp$.}*/

void draw_polyline(int n, double* xc, double* yc, color c=window::fgcol)
{ BASE_WINDOW::draw_polyline(n,xc,yc,c); }
/*{\Mopl     draws a polyline with vertex sequence 
             $(xc[0],yc[0]), \dots, (xc[n-1],yc[n-1])$.}*/


void draw_polygon(const list<point>& lp, color c=window::fgcol);
/*{\Mopl     draws the polygon with vertex sequence $lp$.}*/

void draw_oriented_polygon(const list<point>& lp, color c=window::fgcol);
/*{\Mopl     draws the polygon with vertex sequence |lp| and indicates the 
              orientation by an arrow.}*/


void draw_polygon(const polygon& P, color c=window::fgcol);
/*{\Mopl     draws polygon $P$.}*/


void draw_oriented_polygon(const polygon& P, color c=window::fgcol);
/*{\Mopl     draws polygon $P$ and indicates the orientation by an arrow.}*/



void draw_filled_polygon(const list<point>& lp, color c=window::fgcol);
/*{\Mopl     draws the filled polygon with vertex sequence $lp$.}*/

void draw_filled_polygon(const polygon& P, color c=window::fgcol);
/*{\Mopl     draws filled polygon $P$.}*/


void clip_mask_polygon(const polygon& pol, int mode);
void clip_mask_polygon(const list<point>& L, int mode);
void clip_mask_polygon(int n, double* xc, double* yc, int mode);


// generalized polygons

void draw_polygon(const gen_polygon& P, color c=window::fgcol);
/*{\Mopl     draws polygon $P$.}*/

void draw_oriented_polygon(const gen_polygon& P, color c=window::fgcol);
/*{\Mopl     draws polygon $P$ and indicates the orientation by an arrow.}*/

void draw_filled_polygon(const gen_polygon& P, color c=window::fgcol);
/*{\Mopl     draws filled polygon $P$.}*/



void draw_rectangle(double x0, double  y0, double x1, double y1, color=window::fgcol);
/*{\Mopl     draws a rectangle with lower left corner $(x_0,y_0)$ and upper
             right corner $(x_1,y_1)$.\\
             \precond $x_0 < x_1$ and $y_0 < y_1$. }*/

void draw_rectangle(point p, point q, color=window::fgcol);
/*{\Mopl     draws a rectangle with lower left corner $p$ and upper
             right corner $q$.\\
             \precond $p < q$. }*/

void draw_rectangle(const rectangle& R, color=window::fgcol);
/*{\Mopl     draws rectangle $R$.}*/


void draw_filled_rectangle(double,double,double,double,color=window::fgcol);

void draw_box(double x0, double y0, double x1, double y1,color c=window::fgcol)
{ draw_filled_rectangle(x0,y0,x1,y1,c); }
/*{\Mopl     draws a filled rectangle with lower left corner $(x_0,y_0)$ and upper
             right corner $(x_1,y_1)$.\\
             \precond $x_0 < x_1$ and $y_0 < y_1$. }*/

void draw_filled_rectangle(point p, point q, color=window::fgcol);
/*{\Mopl     draws a filled rectangle with lower left corner $p$ and upper
             right corner $q$.\\
             \precond $p < q$. }*/

void draw_filled_rectangle(const rectangle& R, color=window::fgcol);
/*{\Mopl     draws rectangle $R$.}*/

void draw_box(point p, point q, color c=window::fgcol)
{ draw_filled_rectangle(p,q,c); }
/*{\Mopl     same as |draw_filled_rectangle(p,q,c)|. }*/

void draw_box(const rectangle& R, color c=window::fgcol)
{ draw_filled_rectangle(R,c); }
/*{\Mopl     same as |draw_filled_rectangle(p,q,c)|. }*/




void draw_roundrect(double x0, double  y0, double x1, double y1, double rndness,
                                                      color col=window::fgcol)
{ BASE_WINDOW::draw_roundrect(x0,y0,x1,y1,rndness,col); }
/*{\Mopl     draws a rectangle $(x_0,y_0,x_1,y_1)$ with round corners.
             The |rndness| argument must be a real number in the interval
             $[0,1]$ and defines the ``roundness'' of the rectangle. }*/

void draw_roundrect(point p, point q, double rndness, color col=window::fgcol)
{ draw_roundrect(p.xcoord(),p.ycoord(),q.xcoord(),q.ycoord(),rndness,col); }
/*{\Mopl     draws a round rectangle with lower left corner $p$, upper
             right corner $q$, and roundness |rndness|. }*/


void draw_roundbox(double x0, double  y0, double x1, double y1, double rndness,
                                                      color col=window::fgcol)
{ BASE_WINDOW::draw_roundbox(x0,y0,x1,y1,rndness,col); }
/*{\Mopl     draws a filled rectangle $(x_0,y_0,x_1,y_1)$ with round corners.
             The |rndness| argument must be a real number in the interval
             $[0,1]$ and defined the ``roundness'' of the rectangle. }*/

void draw_roundbox(point p, point q, double rndness, color col=window::fgcol)
{ draw_roundbox(p.xcoord(),p.ycoord(),q.xcoord(),q.ycoord(),rndness,col); }
/*{\Mopl     draws a round filled rectangle with lower left corner $p$, upper
             right corner $q$, and roundness |rndness|. }*/



void draw_triangle(point a, point b, point c, color=window::fgcol);
/*{\Mopl     draws triangle $(a,b,c)$. }*/

void draw_triangle(const triangle& T, color=window::fgcol);
/*{\Mopl     draws triangle $T$. }*/

void draw_filled_triangle(point a, point b, point c, color=window::fgcol);
/*{\Mopl     draws filled triangle $(a,b,c)$. }*/

void draw_filled_triangle(const triangle& T, color=window::fgcol);
/*{\Mopl     draws filled triangle $T$. }*/


// functions

/*{\Mtext
{\bf 3.4.10 Drawing functions}
}*/

void plot_xy(double x0, double x1, win_draw_func F, color c=window::fgcol);
/*{\Mopl     draws the graph of function $F$ in the x-range $[x_0,x_1]$, i.e., 
             all pixels $(x,y)$ with $y = F(x)$ and $x_0\le x\le x_1$.}*/

void plot_yx(double y0, double y1, win_draw_func F, color c=window::fgcol);
/*{\Mopl     draws the graph of function $F$ in the y-range $[y_0,y_1]$, i.e., 
             all pixels $(x,y)$ with $x = F(y)$ and $y_0\le y\le y_1$.}*/




/*{\Mtext
{\bf 3.4.11 Drawing text}
}*/

void draw_text_with_cursor(double x, double y, string s, int cursor, 
                                                         color c=window::fgcol);

void draw_text(double x, double y, string s, color c=window::fgcol);
/*{\Mopl     writes string $s$ starting at position $(x,y)$.}*/

void draw_text(const point& p, string s, color c=window::fgcol);
/*{\Mopl     writes string $s$ starting at position $p$.}*/

void draw_ctext(double x, double y, string s, color c=window::fgcol);
/*{\Mopl     writes string $s$ centered at position $(x,y)$.}*/

void draw_ctext(const point& p, string s, color c=window::fgcol);
/*{\Mopl     writes string $s$ centered at position $p$.}*/

void draw_ctext(string s, color c=window::fgcol);
/*{\Mopl     writes string $s$ centered in window $W$.}*/

double text_box(double x0, double x1, double y, string s, bool draw=true);
/*{\Mopl     formats and writes string $s$ into a box with its left border
             at x-coordinate $x0$, its right border at $x1$, and its upper 
             border at y-coordinate $y$. Some LaTeX-like formatting commands
             can be used: {\tt $\backslash$bf, $\backslash$tt, $\backslash$rm,
             $\backslash$n, $\backslash$c, $\backslash$<color>,} \dots 
             returns y-coordinate of lower border of box. If the optional
             last parameter |draw| is set to |false| no drawing takes place
             and only the lower y-coordinate of the box is computed. }*/

void text_box(string s);
/*{\Mopl     as above with |x0 = W.xmin()|, |x1 = W.xmax()|, 
             and |y = W.ymax()|. }*/



void message(string s) {BASE_WINDOW::message(s);};
/*{\Mop      displays the message $s$ (each call adds a new line).}*/

/*{\Moptions nextwarning=no}*/
void del_message()  { BASE_WINDOW::del_messages(); };
void del_messages() { BASE_WINDOW::del_messages(); };
/*{\Mop      deletes the text written by all previous message 
	     operations.}*/



// nodes

/*{\Mtext
{\bf 3.4.12 Drawing nodes}

Nodes are represented by circles of diameter $node\_width$.
}*/

void draw_node(double x0, double y0, color c=window::fgcol);
/*{\Mopl     draws a node at position $(x_0,y_0)$.}*/

void draw_node(const point& p, color c=window::fgcol);
/*{\Mopl     draws a node at position $p$.}*/

void draw_filled_node(double x0, double y0, color c=window::bgcol);
/*{\Mopl     draws a filled node at position $(x_0,y_0)$.}*/

void draw_filled_node(const point& p, color c=window::bgcol);
/*{\Mopl     draws a filled node at position $p$.}*/

void draw_text_node(double x, double y, string s, color c=window::bgcol);
/*{\Mopl     draws a node with label $s$ at position $(x,y)$. }*/

void draw_text_node(const point& p, string s, color c=window::bgcol);
/*{\Mopl     draws a node with label $s$ at position $p$. }*/

void draw_int_node(double x, double y, int i, color c=window::bgcol);
/*{\Mopl     draws a node with integer label $i$ at position 
	     $(x,y)$. }*/

void draw_int_node(const point& p, int i, color c=window::bgcol);
/*{\Mopl     draws a node with integer label $i$ at position  $p$. }*/



// edges

/*{\Mtext
{\bf 3.4.13 Drawing edges}

Edges are drawn as straigth line segments or arrows with a clearance
of $node\_width/2$ at each end.  }*/

void draw_edge(double x1, double y1, double x2, double y2, color c=window::fgcol);
/*{\Mopl     draws an edge from $(x_1,y_1)$ to $(x_2,y_2)$.}*/

void draw_edge(const point& p, const point& q, color c=window::fgcol);
/*{\Mopl     draws an edge from $p$ to $q$.}*/

void draw_edge(const segment& s, color c=window::fgcol);
/*{\Mopl     draws an edge from $s$.start() to $s$.end().}*/

void draw_edge_arrow(double x1, double y1, double x2, double y2, color c=window::fgcol);
/*{\Mopl     draws a directed edge from $(x_1,y_1)$ to $(x_2,y_2)$.}*/

void draw_edge_arrow(const point& p, const point& q, color c=window::fgcol);
/*{\Mopl     draws a directed edge from $p$ to $q$.}*/

void draw_edge_arrow(const segment& s, color c=window::fgcol);
/*{\Mopl     draws a directed edge from $s$.start() to $s$.end().}*/ 



/*{\Mtext
{\bf 3.4.14 Bitmaps and Pixrects}
}*/

char* create_bitmap(int w, int h, unsigned char* bm_data)
{ return BASE_WINDOW::create_bitmap(w,h,bm_data); }
/*{\Mopl   creates a bitmap (monochrome pixrect) of width $w$, height $h$, 
           from the bits in |data|. }*/

char* create_pixrect_from_color(int w, int h, unsigned int clr)
{ return BASE_WINDOW::create_pixrect_from_color(w,h,clr); }
/*{\Mopl   creates a a solid pixrect of width $w$ und height $h$. }*/


char* create_pixrect_from_xpm(const char** xpm_str)
{ return BASE_WINDOW::create_pixrect_from_xpm(xpm_str); }
/*{\Mopl   creates a pixrect from the {\bf xpm} data string |xpm_str|. }*/


char* create_pixrect(const char** xpm_str) {
   return create_pixrect_from_xpm(xpm_str);
}
/*{\Mopl   creates a pixrect from the {\bf xpm} data string |xpm_str|. }*/


char* create_pixrect_from_xpm(string xpm_file);
/*{\Mopl   creates a pixrect from the {\bf xpm} file |xpm_file|. }*/


char* create_pixrect(string xpm_file) {
   return create_pixrect_from_xpm(xpm_file);
}
/*{\Mopl   creates a pixrect from the {\bf xpm} file |xpm_file|. }*/


char* create_pixrect_from_bits(int w, int h, unsigned char* bm_data, int fg=window::fgcol,
                                                           int bg=window::bgcol)
{ return BASE_WINDOW::create_pixrect_from_bits(w,h,bm_data,fg,bg); }
/*{\Mopl   creates a pixrect of width $w$, height $h$, foreground color 
           $fg$, and background color $bg$ from bitmap |data|. }*/


char* get_pixrect(double x1, double y1, double x2, double y2)
{ return BASE_WINDOW::get_pixrect(x1,y1,x2,y2); }
/*{\Mopl   creates a color pixrect of width $w=x_2-x_1$, height $h=y2-y1$,
           and  copies all pixels from the rectangular area $(x_1,x_2,y_1,y_2)$
           of $W$ into it. }*/

char* get_window_pixrect()
{ return BASE_WINDOW::get_window_pixrect(); }
/*{\Mopl   creates a pixrect copy of the current window contents. }*/


int get_pixrect_width(char* pr) const { return BASE_WINDOW::get_pixrect_width(pr); }
/*{\Mopl   returns the width (number of pixels in a row) 
           of pixrect |pr|. }*/

int get_pixrect_height(char* pr) const { return BASE_WINDOW::get_pixrect_height(pr); }
/*{\Mopl   returns the height (number of pixels in a column) 
           of pixrect |pr|. }*/


void  put_pixrect(double x, double y, char* pr)
{ BASE_WINDOW::put_pixrect(x,y,pr); }
/*{\Mopl   copies the contents of pixrect $pr$ with lower left corner at
           position $(x,y)$ into $W$. }*/

void  put_pixrect(point p, char* pr)
{ BASE_WINDOW::put_pixrect(p.xcoord(),p.ycoord(),pr); }
/*{\Mopl   copies the contents of pixrect $pr$ with lower left corner at
           position $p$ into $W$. }*/

void  center_pixrect(double x, double y, char* pr)
{ BASE_WINDOW::center_pixrect(x,y,pr); }
/*{\Mopl   copies the contents of pixrect $pr$ into $W$ such that its
           center lies on position $(x,y)$. }*/

void  center_pixrect(char* pr)
{ BASE_WINDOW::center_pixrect(pr); }
/*{\Mopl   copies the contents of pixrect $pr$ into $W$ such that its
           center lies on the center of $W$. }*/



void  put_pixrect(char* pr) { BASE_WINDOW::put_pixrect(xmin(),ymin(),pr); }
/*{\Mopl   copies pixrect $pr$ with lower left corner at
           position |(W.xmin(),W.ymin())| into $W$. }*/

void  set_pixrect(char* pr) { BASE_WINDOW::set_pixrect(pr); }
/*{\Mopl   copies pixrect $pr$ with upper left corner at
           position $(0,0)$ into $W$. }*/

//void  fit_pixrect(char* pr) { BASE_WINDOW::set_pixrect(pr); }
//
void  fit_pixrect(char* pr) { BASE_WINDOW::fit_pixrect(pr); }
/*{\Mopl   scales pixrect $pr$ to fit into $W$. }*/



void  put_bitmap(double x, double y, char* bm, color c=window::fgcol)
{ BASE_WINDOW::put_bitmap(x,y,bm,c); }
/*{\Mopl   draws all pixels corresponding to 1-bits in $bm$ with color $c$,
           here the lower left corner of $bm$ corresponds to the pixel at
           position $(x,y)$ in $W$. }*/

void  put_pixrect(double x, double y, char* pr,int x0, int y0, int w, int h)
{ BASE_WINDOW::put_pixrect(x,y,pr,x0,y0,w,h); }
/*{\Mopl   copies (pixel) rectangle $(x0,y0,x0+w,y0+h)$ of $pr$ with lower left 
           corner at position $(x,y)$ into $W$. }*/


void  del_bitmap(char* bm) { BASE_WINDOW::del_bitmap(bm); }
/*{\Mopl   destroys bitmap $bm$. }*/

void  del_pixrect(char* pr) { BASE_WINDOW::del_pixrect(pr); }
/*{\Mopl   destroys pixrect $pr$. }*/


void  copy_rect(double x0, double y0, double x1, double y1, double x, double y)
{ BASE_WINDOW::copy_rect(x0,y0,x1,y1,x,y); }
/*{\Mopl   copies all pixels of rectangle $(x_0,y_0,x_1,y_1)$ into
           the rectangle $(x,y,x+w,y+h)$, where $w = x_1-x_0$ and 
           $h = y_1-y_0$. }*/


void  screenshot(string fname, bool full_color=true);
/*{\Mopl   creates a screenshot of the current window. On unix
           systems suffix |.ps| is appended to |fname| and
           the output format is postscript. On windows systems
           the suffix |.wmf| is added and the format is windows
           metafile. If the flag |full_color| is set to |false|
           colors will be translated into grey scales. }*/  



/*{\Mtext
{\bf 3.4.15 Buffering}
}*/

void start_buffering() { BASE_WINDOW::start_buffering(); }
/*{\Mopl  starts buffering mode for $W$. If $W$ has no associated buffer
          a buffer pixrect $buf$ of the same size as the current drawing 
          area of $W$ is created. All subsequent drawing operations draw 
          into $buf$ instead of $W$ until buffering mode is ended by 
          calling |W.stop_buffering()|. }*/


void start_buffering(int w, int h) { BASE_WINDOW::start_buffering(w,h); }

void set_buffer(char* pr)          { BASE_WINDOW::set_buffer(pr); }



void flush_buffer() { BASE_WINDOW::flush_buffer(); }
/*{\Mopl copies the contents of the buffer pixrect into the drawing
         area of $W$. }*/

void flush_buffer(double dx, double dy) { BASE_WINDOW::flush_buffer(dx,dy); }
/*{\Mopl copies the contents of the buffer pixrect translated by vector
         $(dx,dy)$ into the drawing area of $W$. }*/


void flush_buffer(double x0, double y0, double x1, double y1) 
{ BASE_WINDOW::flush_buffer(x0,y0,x1,y1); }
/*{\Mopl  copies the contents of rectangle $(x0,y0,x1,y1)$ of the
          buffer pixrect into the corresponding rectangle of the
          window area. }*/

void flush_buffer(double dx,double dy,double x0,double y0,double x1,double y1) 
{ BASE_WINDOW::flush_buffer(dx,dy,x0,y0,x1,y1); }
/*{\Mopl  copies the contents of rectangle $(x0,y0,x1,y1)$ of the
          buffer pixrect into the corresponding rectangle of the
          window area translated by vector $(dx,dy)$. }*/


void stop_buffering() { BASE_WINDOW::stop_buffering(); }
/*{\Mopl ends buffering mode. }*/

void stop_buffering(char*& prect) { BASE_WINDOW::stop_buffering(prect); }
/*{\Mopl ends buffering mode and returns the current buffer pixrect
         in |prect|. }*/



/*{\Mtext
{\bf 3.4.16 Clipping}
}*/

void set_clip_rectangle(double x0, double y0, double x1, double y1)
{ BASE_WINDOW::set_clip_rectangle(x0,y0,x1,y1); }
/*{\Mopl sets the clipping region of $W$ to rectangle $(x0,y0,x1,y1)$. }*/


/*
void set_clip_ellipse(double x0, double y0, double r1, double r2)
{ BASE_WINDOW::set_clip_ellipse(x0,y0,r1,r2); }
void set_clip_polygon(const list<point>&);
void set_clip_polygon(const polygon& P) { set_clip_polygon(P.vertices()); }
*/


void reset_clipping() { BASE_WINDOW::reset_clipping(); }
/*{\Mopl restores the clipping region to the entire drawing area of $W$.}*/





// mouse input

/*{\Mtext
{\bf 3.5 Input}

The main input operation for reading positions, mouse clicks, and buttons
from a window $W$ is the operation $W$.read\_mouse(). This operation is 
blocking, i.e., waits for a button to be pressed which is either a ``real''
button on the mouse device pressed inside the drawing area of $W$ or a 
button in the panel section of $W$.
In both cases, the number of the selected button is returned. Mouse
buttons have pre-defined numbers MOUSE\_BUTTON(1) for the left button, 
MOUSE\_BUTTON(2) for the middle button, and MOUSE\_BUTTON(3) for the
right button. The numbers of the panel buttons can be defined by the
user. If the selected button has an associated action function or sub-window 
this function/window is executed/opened (cf. \ref{panel-operations} for
details).

There is also a non-blocking version $W$.get\_mouse() which returns 
the constant NO\_BUTTON if no button was pressed. 

The window data type also provides two more general input operations 
$W$.read\_event() and $W$.get\_event() for reading events. They return 
the event type (enumeration in \<LEDA/graphics/x\_window.h\>), the value of 
the event, the position of the event in the drawing section, and a time 
stamp of the event.

}*/

/*{\Mtext
{\bf 3.5.1 Read Mouse}
}*/

int read_mouse();
/*{\Mop      waits until a mouse button is pressed inside of the drawing 
             area or until a button of the panel section is selected.  
             In both cases, the number $n$ of the button is 
             returned which is one of the predefined constants 
             MOUSE\_BUTTON($i$) with $i\in\{1,2,3\}$ for mouse buttons and
             a user defined value (defined when adding the button with 
             $W$.button()) for panel buttons.
             If the button has an associated action function this function is 
             called with parameter $n$. If the button has an associated
             window $M$ it is opened and $M$.read\_mouse() is returned. }*/

int read() { return read_mouse(); }

void await_button(int b = MOUSE_BUTTON(1)) { while (read_mouse() != b); }
void await_mouse_button(int b = 1) { await_button( MOUSE_BUTTON(b) ); }

int read_mouse(double& x, double& y);
/*{\Mopl     If a button is pressed inside the drawing area the 
             current position of the cursor is assigned to $(x,y)$. 
             The operation returns the number of the pressed button
             (see $W$.read\_mouse().)}*/ 

int read_mouse(point& p);
/*{\Mopl     as above, the current position is assigned to point |p|. }*/


int read_mouse_seg(double x0, double y0, double& x, double& y);
/*{\Mopl     displays a line segment from $(x_0,y_0)$ to the
	     current cursor position until a mouse button is
	     pressed inside the drawing section of $W$. When a 
             button is pressed the current position is assigned to $(x,y)$ 
             and the number of the pressed button is returned.}*/

int read_mouse_seg(const point& p, point& q);
/*{\Mopl     as above with |x0 = p.xcoord()| and |y0 = p.ycoord()|
             and the current position is assigned to |q|. }*/

int read_mouse_line(double x0, double y0, double& x, double& y);
/*{\Mopl     displays a line passing through $(x_0,y_0)$ and the
	     current cursor position until a mouse button is
	     pressed inside the drawing section of $W$. When a 
             button is pressed the current position is assigned to $(x,y)$ 
             and the number of the pressed button is returned.}*/

int read_mouse_line(const point& p, point& q);
/*{\Mopl     as above with |x0 = p.xcoord()| and |y0 = p.ycoord()|
             and the current position is assigned to |q|. }*/

int read_mouse_ray(double x0, double y0, double& x, double& y);
/*{\Mopl     displays a ray from $(x_0,y_0)$ passing through the
	     current cursor position until a mouse button is
	     pressed inside the drawing section of $W$. When a 
             button is pressed the current position is assigned to $(x,y)$ 
             and the number of the pressed button is returned.}*/

int read_mouse_ray(const point& p, point& q);
/*{\Mopl     as above with |x0 = p.xcoord()| and |y0 = p.ycoord()|
             and the current position is assigned to |q|. }*/

int read_mouse_rect(double x0, double y0, double& x, double& y);
/*{\Mopl     displays a rectangle with diagonal from $(x_0,y_0)$ 
     	     to the current cursor position until a mouse button 
	     is pressed inside the drawing section of $W$.
             When a button is pressed the current 
	     position is assigned to $(x,y)$ and the number of the 
             pressed button is returned.}*/

int read_mouse_rect(const point& p, point& q);
/*{\Mopl     as above with |x0 = p.xcoord()| and |y0 = p.ycoord()|
             and the current position is assigned to |q|. }*/

int read_mouse_circle(double x0, double y0, double& x, double& y);
/*{\Mopl     displays a circle with center $(x_0,y_0)$ passing 
	     through the current cursor position until a mouse 
	     button is pressed inside the drawing section of $W$.
             When a button is pressed the 
	     current position is assigned to $(x,y)$ and the 
	     number of the pressed button is returned.}*/

int read_mouse_circle(const point& p, point& q);
/*{\Mopl     as above with |x0 = p.xcoord()| and |y0 = p.ycoord()|
             and the current position is assigned to |q|. }*/

int read_mouse_arc(double x0, double y0, double x1, double y1, double& x, double& y);
/*{\Mopl     displays an arc that starts in $(x_0,y_0)$, ends in
             $(x_1,y_1)$ and passes through the current cursor 
			 position. When a mouse button is pressed inside the 
			 drawing section of $W$, the current position is 
			 assigned to $(x,y)$ and the number of the pressed 
			 button is returned.}*/

int read_mouse_arc(const point& p, const point& q, point& r);
/*{\Mopl     as above with $(x0,y0) = p$ and $(x1,y1) = q$
             and the current position is assigned to |r|. }*/

int read_mouse_arc_with_fixed_src(const point& src, point& tgt, point& middle);

int read_mouse_action(mouse_action_func, double&, double&);
int read_mouse_action(mouse_action_func, point&);


int get_mouse(unsigned long timeout);
/*{\Mop     non-blocking read operation (with timeout). If a button is pressed 
            within $timeout$ msec its number is returned, otherwise the 
            constant NO\_BUTTON is returned. }*/


int get_mouse(double& x, double& y, unsigned long timeout);
/*{\Mopl    if a mouse button is pressed within $timeout$ milliseconds the 
            corresponding position is assigned to $(x,y)$ and the button number
            is returned, otherwise the constant NO\_BUTTON is returned. }*/


int get_mouse();
/*{\Mop     non-blocking read operation, i.e., if a button is pressed 
            its number is returned, otherwise the constant NO\_BUTTON is 
            returned. }*/

int get_mouse(double& x, double& y);
/*{\Mopl    if a mouse button is pressed the corresponding position is
            assigned to $(x,y)$ and the button number is returned, 
            otherwise the constant NO\_BUTTON is returned. }*/


int get_mouse(point& p);
/*{\Mop     if a mouse button was pressed the corresponding position is
            assigned to $p$ and the button number is returned, 
            otherwise the constant NO\_BUTTON is returned. }*/

// for backward compatibility
int get_button() { return get_mouse(); }
int get_button(point& p) { return get_mouse(p); }
int get_button(double& x, double& y) { return get_mouse(x,y); }

int read_mouse(double& x0, double& y0, int timeout1, int timeout2, 
                       bool& double_click, bool& drag);
/*{\Mop  ... }*/

int read_mouse(point& p, int timeout1, int timeout2, 
                         bool& double_click, bool& drag)
{ double x = p.xcoord();
  double y = p.ycoord();
  int k = read_mouse(x,y,timeout1,timeout2,double_click,drag);
  p = point(x,y);
  return k;
}
/*{\Mop  ... }*/


/*{\Mtext
\bigskip
{\bf 3.5.2 Events}
}*/

int  read_event(int& val, double& x, double& y, unsigned long& t)
{ return BASE_WINDOW::read_event(val,x,y,t); }
/*{\Mopl   waits for next event in window $W$ and returns it. 
           Assigns the button or key to $val$, the position in $W$ 
           to  $(x,y)$, and the time stamp of the event to $t$. 
           Possible events are (cf. \<LEDA/graphics/x\_window.h\>): 
           key\_press\_event, key\_release\_event,
           button\_press\_event, button\_release\_event, 
           configure\_event, motion\_event, destroy\_event. }*/

int  read_event(int& val, double& x, double& y, unsigned long& t, int timeout)
{ return BASE_WINDOW::read_event(val,x,y,t,timeout); }
/*{\Mopl   as above, but waits only $timeout$ milliseconds;
           if no event occured the special event $no\_event$ is 
           returned. }*/

int  read_event(int& val, double& x, double& y)
{ return BASE_WINDOW::read_event(val,x,y); }
/*{\Mopl   waits for next event in window $W$ and returns it. 
           Assigns the button or key to $val$ and the position
           in $W$ to  $(x,y)$. }*/

int  read_event()
{ int val; double x,y; return BASE_WINDOW::read_event(val,x,y); }
/*{\Mopl   waits for next event in window $W$ and returns it. }*/

int  read_event(int timeout)
{ int val; double x,y; unsigned long t;
  return BASE_WINDOW::read_event(val,x,y,t,timeout); }
/*{\Mopl   waits for next event in window $W$ for $timeout$ msec and 
           returns it if no event occured $no\_event$ is returned. }*/


int  get_event(int& val, double& x, double& y)
{ return BASE_WINDOW::get_event(val,x,y); }
/*{\Mopl   if there is an event for window $W$ in the event queue a 
           $W.read\_event$ operation is performed, otherwise the integer 
           constant $no\_event$ is returned. }*/

int  get_event()
{ int val; double x,y; return BASE_WINDOW::get_event(val,x,y); }
/*{\Mopl   if there is an event for window $W$ in the event queue a 
           $W.read\_event$ operation is performed, otherwise the integer 
           constant $no\_event$ is returned. }*/


// get shift key info for last handled mouse button event

bool shift_key_down() { return BASE_WINDOW::shift_key_down()!=0; }
/*{\Mop   returns $true$ if a {\em shift} key was pressed during
          the last handled mouse button event. }*/ 

bool ctrl_key_down()  { return BASE_WINDOW::ctrl_key_down()!=0; }
/*{\Mop   returns $true$ if a {\em ctrl} key was pressed during
          the last handled mouse button event. }*/ 

bool alt_key_down()  { return BASE_WINDOW::alt_key_down()!=0; }
/*{\Mop   returns $true$ if an {\em alt} key was pressed during
          the last handled mouse button event. }*/ 


int button_press_time()
{ return (int)BASE_WINDOW::button_press_time(); }
/*{\Mop     returns the time-stamp (in msec) of the last button press event. }*/


int button_release_time()
{ return (int)BASE_WINDOW::button_release_time(); }
/*{\Mop     returns the time-stamp (in msec) of the last button release event. }*/
        
 

/*{\Mtext
\bigskip
{\bf 3.6 Panel Input}

The operations listed in this section are useful for simple input of
strings, numbers, and Boolean values.
}*/


/*{\Moptions nextwarning=no}*/
void    acknowledge(string s);
/*{\Mopl     displays string $s$ and asks for acknowledgement.}*/


bool    confirm(string s);
/*{\Mop      displays string $s$ and asks for confirmation. 
	     Returns true iff the answer was ``yes''.}*/


void    toast(string s, double duration=2.0);
/*{\Mopl     displays string $s$ for $duration$ seconds.}*/


int     read_panel(string h, int n, string* S);
/*{\Mopl     displays a panel with header $h$ and an array of $n$ 
             buttons with labels $S[0..n-1]$, returns the index of 
             the selected button.}*/

int     read_vpanel(string h, int n, string* S);
/*{\Mopl     like read\_panel with vertical button layout.}*/

string  read_string(string p);
/*{\Mop      displays a panel with prompt $p$ for string input, 
    	     returns the input.}*/

double  read_real(string p);
/*{\Mop      displays a panel with prompt $p$ for double input 
 	     returns the input.}*/

int     read_int(string p);
/*{\Mop      displays a panel with prompt $p$ for integer input, 
	     returns the input.}*/


void  panel_read(string p, int& x);
void  panel_read(string p, double& x);
void  panel_read(string p, string& x);




// I/O operators
/*{\Mtext
\bigskip
{\bf 3.7 Input and output operators}

For input and output of basic geometric objects in the plane such as
points, lines, line segments, circles, and polygons the \<\< and \>\>
operators can be used. Similar to \CC input streams windows have an internal 
state indicating whether there is more input to read or not. Its initial value 
is true and it is turned to false if an input sequence is terminated  by 
clicking the right mouse button (similar to ending stream input by the eof 
character). In conditional statements, objects of type $window$ are 
automatically converted to boolean by returning this internal state. Thus, 
they can be used in conditional statements in the same way as \CC input 
streams. For example, to read a sequence of points terminated by a right 
button click,  use `` {\bf while} ($W\ \>\>\ p$) $\{$ \dots $\}$ ''. 
}*/

/*{\Mtext
{\bf 3.7.1 Output}
\setopdims{2.5cm}{4.4cm}
}*/

window& draw(const point& p,color c=window::fgcol);
window& draw(const segment& s,color c=window::fgcol);
window& draw(const ray& r,color c=window::fgcol);
window& draw(const line& l,color c=window::fgcol);
window& draw(const circle& C,color c=window::fgcol);
window& draw(const rectangle& R, color c=window::fgcol);
window& draw(const polygon& P,color c=window::fgcol);
window& draw(const gen_polygon& P,color c=window::fgcol);
window& draw(const triangle& T,color c=window::fgcol);

window& operator<<(const point& p)   { return draw(p); }
/*{\Mbinop   like $W$.draw\_point($p$).}*/

window& operator<<(const segment& s) { return draw(s); }
/*{\Mbinop   like $W$.draw\_segment($s$).}*/

window& operator<<(const ray& r) { return draw(r); }
/*{\Mbinop   like $W$.draw\_ray($r$).}*/

window& operator<<(const line& l)    { return draw(l); }
/*{\Mbinop   like $W$.draw\_line($l$).}*/

window& operator<<(const circle& C)  { return draw(C); }
/*{\Mbinop   like $W$.draw\_circle($C$).}*/

window& operator<<(const polygon& P) { return draw(P); }
/*{\Mbinop   like $W$.draw\_polygon($P$).}*/

window& operator<<(const gen_polygon& P) { return draw(P); }
/*{\Mbinop   like $W$.draw\_polygon($P$).}*/

window& operator<<(const rectangle& R) { return draw(R); }
/*{\Mbinop   like $W$.draw\_rectangle($R$).}*/

window& operator<<(const triangle& T) { return draw(T); }
/*{\Mbinop   like $W$.draw\_triangle($T$).}*/


/*{\Mtext
\bigskip
{\bf 3.7.2 Input}
}*/


window& read(point&);
window& read(segment&);
window& read(ray&);
window& read(line&);
window& read(circle&);
window& read(polygon&);
window& read(gen_polygon&);
window& read(rectangle&);
window& read(triangle&);

window& operator>>(point& p);
/*{\Mbinop   reads a point $p$: clicking the left button 
	     assigns the current cursor position to $p$.}*/

void set_point_buffer(const point p);

window& operator>>(segment& s);
/*{\Mbinop   reads a segment $s$: use the left button to define 
	     the start and end point of $s$.}*/

window& operator>>(ray& r);
/*{\Mbinop   reads a ray $r$: use the left button to define 
	     the start point and a second point on $r$.}*/

window& operator>>(line& l);
/*{\Mbinop   reads a line $l$: use the left button to define 
	     two different points on $l$.}*/

window& operator>>(circle& C);
/*{\Mbinop   reads a circle $C$: use the left button to define 
	     the center of $C$ and a point on $C$.}*/

window& operator>>(rectangle& R);
/*{\Mbinop   reads a rectangle $R$: use the left button to define 
	     two opposite corners of $R$.}*/
	     
window& operator>>(triangle& T);
/*{\Mbinop   reads a triangle $T$: use the left button to define 
	     the corners of $T$.}*/


window& operator>>(polygon& P);
/*{\Mbinop   reads a polygon $P$: use the left button to define 
	     the sequence of vertices of $P$, end the sequence 
	     by clicking the right button.}*/

window& operator>>(gen_polygon& P);
/*{\Mbinop   reads a generalized polygon $P$; input the polygons
             defining $P$ and end the input by clicking the middle
	     button.}*/


list<point> read_polygon();
/*{\Mopl    as above, however, returns list of vertices. }*/

window& read_arc(point& src, point& tgt, point& middle);


/*{\Mtext
As long as an input operation has not been completed the last read point can 
be erased by simultaneously pressing the shift key and the left mouse button.
}*/


/*{\Mtext
\bigskip
{\bf 3.8 Non-Member Functions} 
}*/

friend int  read_event(window*& w, int& val, double& x, double& y,
                                             unsigned long& t, int timeout)
{ return BASE_WINDOW::read_event((BASE_WINDOW*&)w,val,x,y,t,timeout); }

friend int  read_event(window*& w, int& val, double& x, double& y)
{ return BASE_WINDOW::read_event((BASE_WINDOW*&)w,val,x,y); }
/*\{\Mfuncl waits for next event and returns it. Assigns the window to
            $w$, the button or key to $val$ and the position in $w$ to 
            $(x,y)$. Possible events are (cf. <LEDA/graphics/x_window.h>): 
            key_press_event, key_release_event,
            button_press_event, button_release_event, 
            configure_event,motion_event, destroy_event. }*/


friend int  get_event(window*& w, int& val, double& x, double& y)
{ return BASE_WINDOW::get_event((BASE_WINDOW*&)w,val,x,y); }
/*\{\Mfuncl if the event queue is not empty a $read_event$ operation
            is performed, otherwise the integer constant $no\_event$ is 
            returned. }*/


friend int read_mouse(window*& w, double& x, double& y)
{ return BASE_WINDOW::read_mouse((BASE_WINDOW*&)w,x,y); }
/*{\Mfuncl  waits for mouse input, assigns a pointer to the 
            corresponding window to $w$ and the position in 
            $*w$ to $(x,y)$ and returns the pressed button. }*/

friend int get_mouse(window*& w, double& x, double& y)
{ return BASE_WINDOW::get_mouse((BASE_WINDOW*&)w,x,y); }
/*{\Mfuncl  non-blocking variant of |read_mouse|, returns
            NO\_BUTTON if no button was pressed. }*/
 
        
friend void put_back_event();
/*{\Mfunc   puts last handled event back to the event queue. }*/




//------------------------------------------------------------------------------
// panel operations
//------------------------------------------------------------------------------

/*{\Mtext
\bigskip
{\bf 3.9 Panel Operations \label{panel-operations} }

The panel section of a window is used for displaying text messages and 
for updating the values of variables. It consists of a list of panel items and 
a list of buttons.  
The operations in this section add panel items or buttons to the panel section 
of $W$. Note that they have to be called before the window is displayed the
first time.

In general, a panel item consists of a string label and an associated variable
of a certain type (int, bool, string, double, color). The value of this variable
can be manipulated through the item.
Each button has a label (displayed on the button) and an associated number.
The number of a button is either defined by the user or is the rank of the
button in the list of all buttons. If a button is pressed  (i.e. selected
by a mouse click) during a $read\_mouse$ operation its number is returned.

{\em Action functions} can be associated with buttons and some items 
(e.g. slider items) whenever a button with an associated action function
is pressed this function is called with the number of the button as
actual parameter. Action functions of items are called whenever the
value of the corresponding variable is changed with the new value
as actual parameter. All action functions must have the type
$void\ \ func(int)$. 

Another way to define a button is to associate another window with it.
In this case the button will have a menu sign and
as soon as it is pressed the attached window will open. 
This method can be used to implement pop-up menues.
The return value of the current $read\_mouse$ operation will be 
the number associated with the button in the menu.
}*/

/*{\Mtext
\bigskip
{\bf 3.9.1 General Settings}
}*/

void set_panel_bg_color(color c)  { BASE_WINDOW::set_panel_bg_color(c); }
/*{\Mop  sets the background color of the panel area to $c$. }*/

void buttons_per_line(int n) { BASE_WINDOW::buttons_per_line(n); }
/*{\Mop  defines the maximal number $n$ of buttons per line. }*/

void set_button_space(int s) { BASE_WINDOW::set_button_space(s); }
/*{\Mop  sets the space between to adjacent buttons to $s$ pixels. }*/

void set_item_height(int h) { BASE_WINDOW::set_item_height(h); }
/*{\Mop  sets the vertical size of all items to $h$ pixels. }*/

void set_item_width(int w) { BASE_WINDOW::set_item_width(w); }
/*{\Mop  sets the horizontal size of all {\em slider} and {\em string} items
         to $w$ pixels. }*/

void set_bitmap_colors(int c0, int c1) { BASE_WINDOW::set_bitmap_colors(c0,c1);}
/*{\Mop  sets the unpressed/pressed colors used for drawing the pixels in 
         bitmap buttons to $c_0$ and $c_1$. }*/


void set_item_width(panel_item it, int w) { BASE_WINDOW::set_item_width(it,w); }
void set_item_height(panel_item it,int h){ BASE_WINDOW::set_item_height(it,h); }



/*{\Mtext
\bigskip
{\bf 3.9.2 Simple Panel Items}
}*/

panel_item text_item(string s);
/*{\Mop      adds a text\_item $s$ to $W$.}*/

panel_item bool_item(string s, bool& x, const char* hlp=0);
/*{\Mopl     adds a boolean item with label $s$ and variable $x$ to $W$.}*/

panel_item bool_item(string s, bool& x, void (*F)(int), const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item bool_item(string s, bool& x, const window_handler& obj, const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/


panel_item int_item(string s, int& x, const char* hlp=0);
/*{\Mopl     adds an integer item with label $s$ and variable $x$ to $W$.}*/


panel_item string_item(string s, string& x, void (*F)(char*), 
                                            const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item string_item(string s, string& x, const window_handler& obj, 
                                            const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

panel_item string_item(string s, string& x, const char* hlp=0);
/*{\Mopl     adds a string item with label $s$ and variable $x$ to $W$.}*/


panel_item real_item(string s, double& x, const char* hlp=0);

panel_item double_item(string s, double& x, const char* hlp=0);
/*{\Mopl     adds a real item with label $s$ and variable $x$ to $W$.}*/


panel_item color_item(string s, color& x, const char* hlp=0);
/*{\Mopl     adds a color item with label $s$ and variable $x$ to $W$.}*/

panel_item color_item(string s, color& x, void (*F)(int), const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item color_item(string s, color& x, const window_handler& obj, const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

panel_item pstyle_item(string s, point_style& x, const char* hlp=0);
/*{\Mopl     adds a point style item with label $s$ and variable $x$ to $W$.}*/

panel_item pstyle_item(string s,point_style& x,void(*F)(int),const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item pstyle_item(string s,point_style& x,const window_handler& obj,const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/


panel_item lstyle_item(string s, line_style& x, const char* hlp=0);
/*{\Mopl     adds a line style item with label $s$ and variable $x$ to $W$.}*/

panel_item lstyle_item(string s, line_style& x,void(*F)(int),const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item lstyle_item(string s, line_style& x, const window_handler& obj,const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

panel_item lwidth_item(string s, int& x, const char* hlp=0);
/*{\Mopl     adds a line width item with label $s$ and variable $x$ to $W$.}*/

panel_item lwidth_item(string s, int& x, void(*F)(int), const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item lwidth_item(string s, int& x, const window_handler& obj, const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

/*
panel_item lwidth42_item(string s, int& x, const char* hlp=0);
panel_item lwidth42_item(string s, int& x, void(*F)(int), const char* hlp=0);
panel_item lwidth42_item(string s, int& x, const window_handler& obj, const char* hlp=0);
*/


/*{\Mtext
\bigskip
{\bf 3.9.3 Integer Choice Items}
}*/

panel_item int_item(string s, int& x, int l, int h, int step,const char* hlp=0);
/*{\Mopl     adds an integer choice item with label $s$, variable $x$, 
	     range $l$,\dots, $h$, and step size $step$ to $W$.}*/

panel_item int_item(string s, int& x, int l, int h, int step,void (*F)(int),
                                                             const char* hlp=0);
/*{\Mopl     adds an integer choice item with label $s$, variable $x$, 
	     range $l$,\dots, $h$, and step size $step$ to $W$. Function 
             $F(x)$ is executed whenever the value of $x$ is changed. }*/

panel_item int_item(string s, int& x, int l, int h, int step,const window_handler& obj,
                                                             const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

panel_item int_item(string s, int& x, int l, int h, const char* hlp=0);
/*{\Mopl     adds an integer slider item with label $s$, variable $x$, and 
	     range $l$,\dots,$h$ to $W$.}*/

panel_item int_item(string s, int& x, int l, int h, void (*F)(int),const char* hlp=0);
/*{\Mopl     adds an integer slider item with label $s$, variable $x$, and 
	     range $l$,\dots,$h$ to $W$. Function $F(x)$ is executed whenever
             the value of $x$ has changed by moving the slider. }*/

panel_item int_item(string s, int& x, int l, int h, const window_handler& obj,const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

/*{\Mtext
\bigskip
{\bf 3.9.4 String Menu Items}
}*/


panel_item string_item(string s, string& x, const list<string>& L, const char* hlp=0);
/*{\Mopl     adds a string item with label $s$, variable $x$, and menu $L$ 
	     to $W$.}*/


panel_item string_item(string s, string& x, const list<string>& L, 
                                            void (*F)(char*),const char* hlp=0);
					    
panel_item string_item(string s, string& x, const list<string>& L, 
                                            const window_handler& obj,const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

panel_item string_item(string s, string& x, const list<string>& L, int sz,const char* hlp=0);
/*{\Mopl  menu |L| is displayed in a scroll box of height |sz|. }*/


panel_item string_item(string s, string& x, const list<string>& L, int sz,
                                            void (*F)(char*),const char* hlp=0);
/*{\Mopl     as above with action function |F|.}*/

panel_item string_item(string s, string& x, const list<string>& L, int sz,
                                            const window_handler& obj,const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

void set_menu(panel_item it, const list<string>& L, int sz=0);
/*{\Mopl     replaces the menu of string menu item |it| by a menu for 
             list |L| (table style if $sz = 0$ and scroll box with
             $sz$ entries otherwise).}*/

// synonym
void add_menu(panel_item it, const list<string>& L, int sz=0) 
{ set_menu(it,L,sz); }




/*{\Mtext
\bigskip
{\bf 3.9.5 Choice Items}
}*/

panel_item choice_item(string s, int& x, const list<string>& L, 
                       void (*F)(int)=0, const char* hlp=0);
/*{\Mopl     adds an integer item with label $s$, variable $x$, and choices 
	     from $L$ to $W$.}*/
	     
panel_item choice_item(string s, int& x, const list<string>& L, 
                       const window_handler& obj, const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

panel_item  choice_item(string label, int& x, const char* hlp, int n, ... );

panel_item choice_item(string, int& x, const char*, const char*);
panel_item choice_item(string, int& x, const char*, const char*, const char*);
panel_item choice_item(string, int& x, const char*, const char*, const char*, 
                                       const char*);
panel_item choice_item(string, int& x, const char*, const char*, const char*, 
                                       const char*, const char*);
panel_item choice_item(string, int& x, const char*, const char*, const char*, 
                                       const char*, const char*, const char*);
panel_item choice_item(string, int& x, const char*, const char*, const char*, 
                                       const char*, const char*, const char*, 
                                       const char*);
panel_item choice_item(string, int& x, const char*, const char*, const char*, 
                                       const char*, const char*, const char*, 
                                       const char*, const char*);

/*{\Moptions nextwarning=no}*/
/*
panel_item choice_item(string s, int& x, string s1,...,string sk);
*/
/*{\Mopl     adds an integer item with label $s$, variable $x$, and choices 
	     $s_1$, \dots, $s_k$ to $W$ ($k \le 8$).}*/


panel_item choice_item(string s, int& x, int n, int w, int h,unsigned char** bm,
                                                             const char* hlp=0);
/*{\Mopl     adds an integer item with label $s$, variable $x$, and $n$
             bitmaps |bm[0]|, \dots, |bm[n-1]| each of width $w$ 

             and height $h$.}*/ 


panel_item choice_item(string s, int& x, int n, int w, int h,unsigned char** bm,
                                                             void (*F)(int), 
                                                             const char* hlp=0);
/*{\Mopl  }*/


panel_item choice_item(string s, int& x, int n, int w, int h,unsigned char** bm,
                                                             const window_handler& obj, 
                                                             const char* hlp=0);
/*{\Mopl     as above with handler object |obj|.}*/

/*{\Mtext
\bigskip
{\bf 3.9.6 Multiple Choice Items}
}*/

panel_item choice_mult_item(string s,int& x,const list<string>& L, const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s,int& x,string s1, const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s,int& x,string s1, string s2, const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s,int& x,const list<string>& L,void (*F)(int), 
                                                            const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s,int& x,const list<string>& L,const window_handler& obj, 
                                                            const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s, int& x, int n, int w, int h,
                                                            unsigned char** bm,
                                                            const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s, int& x, int n, int w, int h, 
                                                            unsigned char** bm, 
                                                            void (*F)(int), 
                                                            const char* hlp=0);
/*{\Mopl  }*/

panel_item choice_mult_item(string s, int& x, int n, int w, int h, 
                                                            unsigned char** bm, 
                                                            const window_handler& obj, 
                                                            const char* hlp=0);
/*{\Mopl  }*/


/*{\Mtext
\bigskip
{\bf 3.9.7 Buttons}

The first occurence of character |'&'| in a button label makes the
following character |c| an {\em accelerator character}, i.e., the
button can be selected by typing ALT-|c| from the keyboard. 
}*/

int  button(string s, int n, const char* hlp=0);
/*{\Mop      adds a button with label $s$ and number $n$ to $W$.}*/

int  fbutton(string s, int n, const char* hlp=0);
/*{\Mop     as above but makes this button the focus button of $W$, i.e., 
            this button can be selected by pressing the return key. }*/

int  button(string s, const char* hlp=0);
/*{\Mop   adds a new button to $W$ with label $s$ and number equal to its
          position in the list of all buttons (starting with $0$).}*/

int  fbutton(string s, const char* hlp=0);
/*{\Mop     as above but makes this button the focus button. }*/ 


int  button(int w, int h, unsigned char* bm, string s,int n,const char* hlp=0);
/*{\Mop    adds a button with bitmap $bm$, label $s$, and number $n$ to $W$.}*/

int  button(char* pr1, char* pr2, string s, int n, const char* hlp=0);
/*{\Mop    adds a button with pixrects $pr1$ and $pr2$, label $s$, and number 
           $n$ to $W$. }*/

int  button(int w, int h, unsigned char* bm, string s,const char* hlp=0);
/*{\Mop   adds a new button to $W$ with bitmap $bm$, label $s$, and number equal
          to its position in the list of all buttons (starting with $0$).}*/

// leads to ambiguity in current release 
// int  button(char* pr1, char* pr2, string s, const char* hlp=0);
/*{\Xopl  as above, but with pixrects $pr1$ and $pr2$. }*/


int  button(string s, int n, void (*F)(int), const char* hlp=0);
/*{\Mopl  adds a button with label $s$, number $n$ and action 
          function $F$ to $W$. Function $F$ is called with actual
          parameter $n$  whenever the button is pressed. }*/
	  
int  button(string s, int n, const window_handler& obj, const char* hlp=0);
/*{\Mopl  as above with handler object |obj|.}*/

int  fbutton(string s, int n, void (*F)(int), const char* hlp=0);
/*{\Mop     as above but makes this button the focus button. }*/ 

int  fbutton(string s, int n, const window_handler& obj, const char* hlp=0);
/*{\Mopl  as above with handler object |obj|.}*/

int  button(int w, int h, unsigned char* bm, string s, int n, void (*F)(int), 
                                                       const char* hlp=0);
/*{\Mopl  adds a button with bitmap $bm$, label $s$, number $n$ and action 
          function $F$ to $W$. Function $F$ is called with actual
          parameter $n$  whenever the button is pressed. }*/
	  
int  button(int w, int h, unsigned char* bm, string s, int n, const window_handler& obj, 
                                                       const char* hlp=0);
/*{\Mopl }*/

int  button(char* pr1, char* pr2, string s, int n, void (*F)(int), const char* hlp=0);
/*{\Mopl  as above, but with pixrect $pr1$ and $pr2$. }*/

int  button(char* pr1, char* pr2, string s, int n, const window_handler& obj, const char* hlp=0);
/*{\Mopl }*/

int  button(string s, void (*F)(int), const char* hlp=0);
/*{\Mopl  adds a button with label $s$, number equal to its rank and action 
          function $F$ to $W$. Function $F$ is called with the value of the
          button as argument whenever the button is pressed. }*/
	  
int  button(string s, const window_handler& obj, const char* hlp=0);
/*{\Mopl }*/

int  button(int w, int h, unsigned char* bm, string s, void (*F)(int),
                                                       const char* hlp=0);
/*{\Mopl  adds a button with bitmap $bm$, label $s$, number equal to its rank 
          and action function $F$ to $W$. Function $F$ is called with the 
          value of the button as argument whenever the button is pressed. }*/
	  
int  button(int w, int h, unsigned char* bm, string s, const window_handler& obj,
                                                       const char* hlp=0);
/*{\Mopl }*/

int  button(char* pr1, char* pr2, string s, void (*F)(int),const char* hlp=0);
/*{\Mopl  as above, but with pixrect $pr1$ and $pr2$. }*/

int  button(char* pr1, char* pr2, string s, const window_handler& obj,const char* hlp=0);
/*{\Mopl }*/

int  button(string s, int n, window& M, const char* hlp=0);
/*{\Mopl  adds a button with label $s$, number $n$  and attached sub-window
          (menu) $M$ to $W$. Window $M$ is opened whenever the button is
          pressed. }*/

int  button(int w, int h, unsigned char* bm, string s, int n, window& M,
                                                     const char* hlp=0);
/*{\Mopl  adds a button with bitmap $bm$, label $s$, number $n$  and attached 
          sub-window (menu) $M$ to $W$. Window $M$ is opened whenever the 
          button is pressed. }*/

int  button(char* pr1, char* pr2, string s, int n, window& M,const char* hlp=0);
/*{\Mopl  as above, but with pixrect $pr1$ and $pr2$. }*/


int  button(string s, window& M, const char* hlp=0);
/*{\Mopl  adds a button with label $s$ and attached sub-window $M$ to $W$. 
          The number returned by $read\_mouse$ is the number of the
          button selected in sub-window $M$. }*/

int  button(int w, int h, unsigned char* bm, string s, window& M, 
                                                       const char* hlp=0);
/*{\Mopl  adds a button with bitmap $bm$, label $s$ and attached sub-window 
          $M$ to $W$. The number returned by $read\_mouse$ is the number of 
          the button selected in sub-window $M$. }*/

int  button(char* pr1, char* pr2, string s, window& M, const char* hlp=0);
/*{\Mopl  as above, but with pixrect $pr1$ and $pr2$. }*/



void make_menu_bar(int k) { BASE_WINDOW::make_menu_bar(k); }

void make_menu_bar() { BASE_WINDOW::make_menu_bar(); }
/*{\Mop  inserts a menu bar at the top of the panel section that 
         contains all previously added menu buttons (buttons with 
         a subwindow attached). }*/ 


int menu_button(string s, int n, window& M, const char* hlp=0);
/*{\Xopl  adds a {\em menu} button with label $s$, number $n$  and 
          attached sub-window (menu) $M$ to the panel bar of $W$. }*/


int menu_button(string s, window& M, const char* hlp=0);
/*{\Xopl  adds a {\em menu} button with label $s$ and attached sub-window $M$ 
          to $W$. The number returned by $read\_mouse$ is the number of the
          button selected in sub-window the panel bar of $M$. }*/



static window* get_call_window() 
{ return (window*)BASE_WINDOW::get_call_window(); } 
/*{\Mstatic  A static function that can be called in action functions attached 
             to panel items or buttons to retrieve a pointer to the window 
             containing the corresponding item or button. }*/

static panel_item get_call_item()   { return BASE_WINDOW::get_call_item(); } 
/*{\Mstatic  A static function that can be called in action functions attached
             to panel items to retrieve the corresponding item. }*/


static int   get_call_button() { return BASE_WINDOW::get_call_button(); } 
/*{\Mstatic  A static function that can be called in action functions attached
             to panel buttons to retrieve the number of the corresponding 
             button. }*/



/*{\Mtext
\bigskip
{\bf 3.9.8. Manipulating Panel Items and Buttons}
}*/


/*{\Mtext
{\bf Disabling and Enabling Items or buttons}
}*/

void disable_item(panel_item it) { BASE_WINDOW::disable_item(it); }
/*{\Mopl  disables panel item $it$. }*/

void enable_item(panel_item it)  { BASE_WINDOW::enable_item(it); }
/*{\Mopl  enables panel item $it$. }*/

bool is_enabled(panel_item it)   { return BASE_WINDOW::is_enabled(it); }
/*{\Mopl  tests whether item $it$ is enabled or not. }*/


void disable_button(int b) { BASE_WINDOW::disable_button(b); }
/*{\Mopl  disables button $b$. }*/

void enable_button(int b) { BASE_WINDOW::enable_button(b); }
/*{\Mopl  enables button $b$. }*/

void disable_buttons() { BASE_WINDOW::disable_buttons(); }
/*{\Mopl  disables all buttons. }*/

void enable_buttons() { BASE_WINDOW::enable_buttons(); }
/*{\Mopl  enables all buttons. }*/

bool is_enabled(int b)   { return is_enabled(get_button_item(b)); }
/*{\Mopl  tests whether button $b$ is enabled or not. }*/


void disable_panel(bool disable_items=true) 
{ BASE_WINDOW::disable_panel(disable_items); }
/*{\Mopl  disables the entire panel section of $W$. }*/

void enable_panel()  
{ BASE_WINDOW::enable_panel(); }
/*{\Mopl  enables the entire panel section of $W$. }*/



/*{\Mtext
{\bf Accessing and Updating Item Data}
}*/

void set_text(panel_item it, string s);
/*{\Mopl  replaces the text of text item |it| by $s$. }*/


panel_item  get_item(string s) { return BASE_WINDOW::get_item(s); }
/*{\Mopl  returns the item with label $s$ and |NULL| if no such
          item exists in $W$. }*/


int  get_button(string s) { return BASE_WINDOW::get_button(s); }
/*{\Mopl  returns the button with label $s$ and $-1$ if no such
          button exists in $W$. }*/


string  get_button_label(int but) 
{ return BASE_WINDOW::get_button_label(but); }
/*{\Mopl  returns the label of button $but$. }*/

void    set_button_label(int but, string s) 
{ BASE_WINDOW::set_button_label(but,s); }
/*{\Mopl  sets the label of button $but$ to $s$. }*/

void    set_button_pixrects(int but, char *pr1, char* pr2)
{ BASE_WINDOW::set_button_pixrects(but,pr1,pr2); }
/*{\Mopl  sets the pixrects of button $but$ to $pr1$ and $pr2$. }*/


window* get_window(panel_item it)
{ return (window*)BASE_WINDOW::get_window(it); }


window* get_window(int but);
/*{\Mopl     returns a pointer to the subwindow attached to button $but$ 
             (|NULL| if $but$ has no subwindow) }*/

window* set_window(panel_item it, window* M);

window* set_window(int but, window* M);
/*{\Mopl     associates subwindow (menu) $*M$ with button $but$. Returns 
             a pointer to the window previously attached to $but$. }*/

void set_function(int but, void (*F)(int) )
{ BASE_WINDOW::set_item_func(get_button_item(but),F); }
/*{\Mopl     assign action function $F$ to button $but$. }*/

void set_object(int but, const window_handler& obj)
{ BASE_WINDOW::set_item_object(get_button_item(but),obj); }
/*{\Mopl     assign handler object $obj$ to button $but$. }*/


/*{\Mtext
\bigskip
{\bf 3.9.9. Miscellanous}
}*/

void redraw_panel() { BASE_WINDOW::redraw_panel(); }
/*{\Mopl     redraw the panel area of $W$. }*/

void redraw_panel(panel_item it) { BASE_WINDOW::draw_item(it); }
/*{\Mopl     redraw item $i$ in the panel area of $W$. }*/

void display_help_text(string fname);
/*{\Mop  displays the help text contained in |name.hlp|. The file 
         |name.hlp| must exist either in the current working directory or in
         |\$LEDAROOT/incl/Help|. }*/

void set_tooltip(int i, double x0, double y0, double x1, double y1, string txt)
{ BASE_WINDOW::set_tooltip(i,x0,y0,x1,y1,txt); }
/*{\Mopl inserts a tooltip with id $i$, rectangle ($x_0$, $y_0$,$x_1$,$y_1$)
         and text $txt$ into the window. The text is shown when the mouse 
         pointer enters the rectangle. The text disappears as soon as the 
         mouse pointer leaves the rectangle.\\
         CAUTION: Currently the method has to be called after the call of
         $W$.display(). Setting a tooltip before the call $W$.display() has no
         effect.}*/

void del_tooltip(int i) { BASE_WINDOW::del_tooltip(i); }
/*{\Mopl     removes the tooltip with id $i$.}*/


void string_edit(point p, string& s);

int string_edit(double x, double y, string& s, int& curs_pos);
int string_edit(double x, double y, string& s, int& curs_pos, int& timeout);


/*
// status_window
void    create_status_window()      { BASE_WINDOW::create_status_window(); }
void    open_status_window()        { BASE_WINDOW::open_status_window(); }
void    close_status_window()       { BASE_WINDOW::close_status_window(); }
void    destroy_status_window()     { BASE_WINDOW::destroy_status_window(); }
void    set_status_string(string s) { BASE_WINDOW::set_satus_string(s); }
window* get_status_window()         { return BASE_WINDOW::get_status_window(); }
*/



// zooming

bool read_zoom_rect(const point& center,point& p, point& q );
bool read_zoom_rect(point& p, point& q);

void adjust_zoom_rect(double& x0, double& y0, double& x1, double& y1);

void zoom_area(double x0, double y0, double x1, double y1, int steps = 16, 
                                     void (*redraw)(window*) = 0);

void zoom_area(const point& p, const point& q, int steps = 16, 
                                     void (*redraw)(window*) = 0)
{ zoom_area(p.xcoord(),p.ycoord(),q.xcoord(),q.ycoord(),steps,redraw); }

void zoom(double f, int steps = 16, void(*redraw)(window*) = 0);

void scroll_window(const point& p, 
             void (*redraw_func_start)(window*,double,double,double,double),
             void (*redraw_func_drag)(window*,double,double,double,double),
             void (*redraw_func_end)(window*,double,double,double,double));

void scroll_window(const point& p, 
                   void (*redraw_func)(window*,double,double,double,double)=0);


};

inline void put_back_event()      { BASE_WINDOW::put_back_event(); }



extern __exportF void LedaFileViewer(window& W, string fname, string dname, string pat);
extern __exportF void LedaFileViewer(window& W, string fname, string dname);
extern __exportF void LedaFileViewer(window& W, string fname);


extern __exportF void LedaFileViewer(string fname, string dname, string pat);
extern __exportF void LedaFileViewer(string fname, string dname);
extern __exportF void LedaFileViewer(string fname);


extern __exportF void LedaFileViewer(const list<string>& L, int w, int h, 
                                                               string label);

extern __exportF void LedaFileViewer(window& W, const list<string>& L);

extern __exportF void LedaFileViewer(const list<string>& L);



/*{\Mexample
Example programs can be found on LEDAROOT/demo/win and LEDAROOT/test/win. 
}*/


/*{\Moptions usesubscripts=no}*/

LEDA_END_NAMESPACE

#include <LEDA/graphics/panel.h>
#include <LEDA/graphics/menu.h>


#if (defined(__win32__) || defined(__win64__)) && defined(WINMAIN)

#if !defined(_WINDOWS_)
extern "C" int   __stdcall WinMain(void*,void*,char*,int);
int main_tmp();
int __stdcall WinMain(void*,void*,char*,int) { return main_tmp(); }
#define main  main_tmp
#endif

#endif



#if LEDA_ROOT_INCL_ID == 723215
#undef LEDA_ROOT_INCL_ID
#include <LEDA/internal/POSTAMBLE.h>
#endif


#endif
