]> git.saurik.com Git - wxWidgets.git/blobdiff - docs/latex/book/chap_drawing.tex
Added "metal" theme.
[wxWidgets.git] / docs / latex / book / chap_drawing.tex
index 7e84942414024b2e024dd6cadb3fc086af7f3ffe..1bd36c95b584b3c77d61497e47d3898ebd070431 100644 (file)
@@ -3,5 +3,116 @@
 \setheader{{\it CHAPTER \thechapter: DRAWING ON DEVICE CONTEXTS}}{}{}{}{}{{\it CHAPTER \thechapter: DRAWING ON DEVICE CONTEXTS}}%
 \setfooter{\thepage}{}{}{}{}{\thepage}%
 
-Device contexts, a great abstraction...
+\section{The concept of device contexts}
+
+Device contexts, commonly referred as DCs, represent more or less anything
+you can draw into, i.e. a window, a bitmap, the screen, a printer, a Postscript
+file, most recently even an SVG file. There is one abstract base class (wxDC)
+which defines the interface for all other classes so that drawing code for
+one device context can be used for all others as well - with certain limitation
+as the hardware specifies (e.g. you cannot read a pixel from a printer).
+
+\section{Drawing into windows}
+
+Let's start with the most simple case: you want to draw a line in a window.
+Or rather not the window, but its client area, the usually white or grey
+large area that is surrounded by the window's decorations such as its border
+which you normally would not want to draw over.
+
+In addition to defining classes that represent devices, wxWindows has a few
+of classes that define colours and so-called pens and brushes. A pen is used
+for drawing lines (which can be a curve or a rectangle) whereas brushes are
+used to paint areas, such as a filled rectangle or a filled circle. Indeed,
+you can use both at the same time for drawing a rectangle which is both filled
+and has a border. If you want to draw a red rectangle with a black border,
+you will do this:
+
+\begin{verbatim}
+void MyWindow::DrawSomething()
+{
+    wxClientDC dc(this);
+    
+    dc.SetPen( *wxBLACK_PEN );
+    dc.SetBrush( *wxRED_BRUSH );
+    
+    dc.DrawRectangle( 0, 0, 100, 100 );
+}
+\end{verbatim}
+
+If you want to draw a rectangle without any border, you can use the special
+oen wxTRANSPARENT_PEN, if the rectangle is not supposed to be filled with
+any colour, you use the special brush wxTRANSPARENT_BRUSH. When using both
+these special classes, you could draw an invisible rectangle like this:
+
+\begin{verbatim}
+void MyWindow::DrawNothing()
+{
+    wxClientDC dc(this);
+    
+    dc.SetPen( *wxTRANSPARENT_PEN );
+    dc.SetBrush( *wxTRANSPARENT_BRUSH );
+    
+    dc.DrawRectangle( 0, 0, 100, 100 );
+}
+\end{verbatim}
+
+Now what happens when you window gets obscured by another window and 
+then returns to the surface again? The rectangle will not appear again
+because a window does not remember what has been drawn into it. Instead,
+your program has to remember what to draw and where and it will receive
+a so called wxPaintEvent indicating that some region has been unobscured
+and needs repainting. In order to catch such an event so that you can
+react appropriately to it, you will have to set up an event handler
+like this:
+
+\begin{verbatim}
+BEGIN_EVENT_TABLE(MyWindow, wxWindow)
+    EVT_PAINT  (MyWindow::OnPaint)
+END_EVENT_TABLE()
+
+void MyWindow::OnPaint( wxPaintEvent &event )
+{
+    wxPaintDC dc(this);
+    
+    dc.SetPen( *wxBLACK_PEN );
+    dc.SetBrush( *wxRED_BRUSH );
+    
+    dc.DrawRectangle( 0, 0, 100, 100 );
+}
+\end{verbatim}
+
+Note that this time, you have to use a wxPaintDC as these are used
+in connection with wxPaintEvents. Note also, that every such handler
+has to use a wxPaintDC even of you (for the moment) don't draw anything.
+If there is no such wxPaintDC, your program will not work under Windows.
+
+One difference between a wxPaintDC and a wxClientDC is that the wxPaintDC
+always sets a clipping region to the region of the window that was
+unobscured with the effect that all drawing commands will be clipped to
+that region. This leads to a reduction of flicker as only those
+areas of the window get redrawn, which actually need to get redrawn.
+
+\section{Querying the update region}
+
+Call me lazy:
+
+\begin{verbatim}
+BEGIN_EVENT_TABLE(MyWindow, wxWindow)
+    EVT_PAINT  (MyWindow::OnPaint)
+END_EVENT_TABLE()
+
+void MyWindow::OnPaint( wxPaintEvent &event )
+{
+    wxPaintDC dc(this);
+    
+    if (IsExposed( 0, 0, 100, 100))
+    {
+        dc.SetPen( *wxBLACK_PEN );
+        dc.SetBrush( *wxRED_BRUSH );
+        
+        dc.DrawRectangle( 0, 0, 100, 100 );
+    }
+}
+\end{verbatim}
+