3 // Copyright (c) 2001-2004 David Ward
5 #ifndef __DasherScreen_h_
6 #define __DasherScreen_h_
8 #include "DasherTypes.h"
9 #include "../DasherCore/ColourIO.h"
12 // DJW20050505 - renamed DrawText to DrawString - windows defines DrawText as a macro and it's
13 // really hard to work around
14 // Also make CDasher screen operate in UTF8 strings only
18 class CLabelListScreen
;
19 class CDasherInterfaceBase
;
24 /// Abstract interface for drawing operations, implemented by platform-specific canvases.
25 /// Instances have _mutable_ dimensions; changes should be reported to the
26 /// interface's ScreenResized method.
27 /// Note the DrawString and TextSize methods: these now take platform-specific
28 /// Label objects returned from MakeLabel. Thus, it is up to external clients to
29 /// cache and reuse Labels. (This replaces the previous scheme where these methods
30 /// took arbitrary std::strings, which were cached in a hashmap internal to each
31 /// platform's screen. The new scheme allows clients to control cache preloading
33 class Dasher::CDasherScreen
36 //! \param width Width of the screen
37 //! \param height Height of the screen
38 CDasherScreen(screenint width
, screenint height
)
39 :m_iWidth(width
), m_iHeight(height
) {
42 virtual ~ CDasherScreen() {
45 /* //! Set the widget interface used for communication with the core */
46 /* virtual void SetInterface(CDasherInterfaceBase * DasherInterface) { */
47 /* m_pDasherInterface = DasherInterface; */
50 //! Return the width of the screen
51 screenint
GetWidth() {
54 //! Return the height of the screen screen
58 //! Structure defining a point on the screen
59 typedef struct tagpoint
{
64 /// (Default implementation returns false)
65 ///\return true if this Screen can efficiently support fonts of many sizes (by continuous scaling);
66 /// false if clients should try to minimise the number of distinct font sizes required.
67 virtual bool MultiSizeFonts() {return false;}
69 ///Abstract class for objects representing strings that can be drawn on the screen.
70 /// Platform-specific instances are created by the MakeLabel(String) method, which
71 /// may then be passed to GetSize() and DrawText().
73 friend class CDasherScreen
;
75 Label(const std::string
&strText
, unsigned int iWrapSize
)
76 : m_strText(strText
), m_iWrapSize(iWrapSize
) {};
78 const std::string m_strText
;
79 ///If 0, Label is to be rendered on a single line.
80 /// Any other value, Label need only be renderable at that size, but should
81 /// be _wrapped_ to fit the screen width. (It is up to platforms to decide
82 /// whether to support DrawString/TextSize at any other size but this is
84 unsigned int m_iWrapSize
;
85 ///Delete the label. This should free up any resources associated with
86 /// drawing the string onto the screen, e.g. layouts or textures.
90 ///Make a label for use with this screen.
91 /// \param strText UTF8-encoded text.
92 /// \param iWrapSize 0 => create a Label that will be rendered on a single line,
93 /// potentially at multiple sizes; appropriate for DasherNode labels.
94 /// Any other value => Label SHOULD ONLY BE USED AT THAT SIZE, but should
95 /// be _wrapped_ onto multiple lines if necessary to fit within the screen width.
96 /// (DrawString/TextSize with any other font size may produce unpredictable results,
97 /// depending on platform.)
98 virtual Label
*MakeLabel(const std::string
&strText
, unsigned int iWrapSize
=0) {return new Label(strText
,iWrapSize
);}
100 ///Get Width and Height of a Label previously created by MakeLabel. Note behaviour
101 /// undefined if the Label is not one returned from a call to MakeLabel _on_this_Screen_.
102 virtual std::pair
<screenint
,screenint
> TextSize(Label
*label
, unsigned int iFontSize
) = 0;
104 /// Draw a label at position (x1,y1)
105 /// \param label a Label previously created by MakeLabel. Note behaviour
106 /// undefined if the Label is not one returned from a call to MakeLabel _on_this_Screen_.
107 /// \param x Coordinate of top left corner (i.e., left hand side)
108 /// \param y Coordinate of top left corner (i.e., top)
109 virtual void DrawString(Label
*label
, screenint x
, screenint y
, unsigned int iFontSize
, int iColour
) = 0;
111 // Send a marker to indicate 'phases' of drawing.
113 virtual void SendMarker(int /*iMarker*/ ) {
116 /// Draw a filled rectangle
118 /// Draw a coloured rectangle on the screen
119 /// \param x1 top left of rectangle (x coordinate)
120 /// \param y1 top left corner of rectangle (y coordinate)
121 /// \param x2 bottom right of rectangle (x coordinate)
122 /// \param y2 bottom right of rectangle (y coordinate)
123 /// \param Colour the colour to be used (numeric), or -1 for no fill
124 /// \param iOutlineColour The colour for the node outlines; -1 = use default
125 /// \param iThickness Line thickness for outline; <1 for no outline
126 virtual void DrawRectangle(screenint x1
, screenint y1
, screenint x2
, screenint y2
, int Colour
, int iOutlineColour
, int iThickness
) = 0;
128 ///Draw a circle, potentially filled and/or outlined
129 /// \param iFillColour colour in which to fill; -1 for no fill
130 /// \param iLineColour colour to draw outline; -1 = use default
131 /// \param iLineWidth line width for outline; <1 for no outline
132 virtual void DrawCircle(screenint iCX
, screenint iCY
, screenint iR
, int iFillColour
, int iLineColour
, int iLineWidth
) = 0;
134 /// Draw a line of fixed colour (usually black). Intended for static UI elements such as a cross-hair
135 /// Draw a line between each of the points in the array
137 /// \param Points an array of points
138 /// \param Number the number of points in the array
139 /// \param iWidth The line width
140 /// \todo This is dumb - why does this need to be a separate function to the coloured version?
142 virtual void Polyline(point
* Points
, int Number
, int iWidth
) {
143 Polyline(Points
, Number
, iWidth
, 0);
146 // Draw a line of arbitrary colour.
147 //! Draw a line between each of the points in the array
149 //! \param Points an array of points
150 //! \param Number the number of points in the array
151 //! \param iWidth Width of the line
152 //! \param Colour the colour to be drawn
154 virtual void Polyline(point
* Points
, int Number
, int iWidth
, int Colour
) = 0;
156 /// Draw a polygon - given vertices and colour id
158 /// \param Points Vertices of polygon in clockwise order. (No need to repeat the first point at the end)
159 /// \param Number number of points in the array
160 /// \param fillColour colour to fill polygon (numeric); -1 for don't fill
161 /// \param outlineColour colour to draw polygon outline (right the way around, i.e. repeating first point)
162 /// \param lineWidth thickness of outline; 0 or less => don't draw outline.
163 virtual void Polygon(point
* Points
, int Number
, int fillColour
, int outlineColour
, int lineWidth
) = 0;
165 //! Signal that a frame is finished - the screen should be updated
166 virtual void Display() = 0;
168 /// Set a colour scheme
170 /// \param pColourScheme A colour scheme that should be used
171 virtual void SetColourScheme(const Dasher::CColourIO::ColourInfo
*pColourScheme
) = 0;
173 // Returns true if cursor is over visible part of this window.
174 virtual bool IsWindowUnderCursor() = 0;
177 //! Width and height of the screen
178 screenint m_iWidth
, m_iHeight
;
181 ///Subclasses should call this if the canvas dimensions have changed.
182 /// It is up to subclasses to make sure they also call
183 /// ScreenResized on the intf.
184 void resize(screenint width
, screenint height
) {
185 m_iWidth
= width
; m_iHeight
= height
;
189 /// Subclass that preserves a list of all labels returned from MakeLabel
190 /// (and not yet deleted) so that they can be mutated en mass (by further
191 /// subclasses) if necessary. Note we have to return a new Labels each time,
192 /// and cannot hash/flyweight together similar Labels, because _clients_ are
193 /// in control of deletion.
194 class Dasher::CLabelListScreen
: public Dasher::CDasherScreen
{
196 CLabelListScreen(screenint width
, screenint height
) : CDasherScreen(width
,height
) {
198 class Label
: public CDasherScreen::Label
{
199 public: //to instances of CLabelListScreen and subclasses
200 Label(CLabelListScreen
*pScreen
, const std::string
&strText
, unsigned int iWrapSize
)
201 : CDasherScreen::Label(strText
, iWrapSize
), m_pScreen(pScreen
) {
202 m_pScreen
->m_sLabels
.insert(this);
205 std::set
<Label
*>::iterator it
= m_pScreen
->m_sLabels
.find(this);
206 DASHER_ASSERT(it
!= m_pScreen
->m_sLabels
.end());
207 m_pScreen
->m_sLabels
.erase(it
);
209 CLabelListScreen
* const m_pScreen
;
211 ///An iterator pointing to the first extant (non-deleted) label created
212 /// from this screen. This allows iteration through modifiable labels,
213 /// but without being able to access or hence modify the set.
214 std::set
<Label
*>::iterator
LabelsBegin() {return m_sLabels
.begin();}
216 ///An iterator pointing just beyond the last extant (non-deleted) label
217 /// created from this screen. This allows iteration through modifiable labels,
218 /// but without being able to access or hence modify the set.
219 std::set
<Label
*>::iterator
LabelsEnd() {return m_sLabels
.end();}
221 std::set
<Label
*> m_sLabels
;
225 #endif /* #ifndef __DasherScreen_h_ */