Updated German translation
[dasher.git] / Src / DasherCore / DasherModel.h
blob2c433a8679f9b799a168cbf84e3ee97e0f9f226e
1 // DasherModel.h
2 //
3 // Copyright (c) 2008 The Dasher Team
4 //
5 // This file is part of Dasher.
6 //
7 // Dasher is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
12 // Dasher is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with Dasher; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef __DasherModel_h__
22 #define __DasherModel_h__
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include <climits>
29 #include <deque>
30 #include <cmath>
31 #include <vector>
33 #include "../Common/NoClones.h"
34 #include "DasherNode.h"
35 #include "DasherTypes.h"
36 #include "ExpansionPolicy.h"
37 #include "SettingsStore.h"
38 #include "AlphabetManager.h"
40 namespace Dasher {
41 class CDasherModel;
42 class CDasherView;
45 /// \defgroup Model The Dasher model
46 /// @{
48 /// \brief Dasher 'world' data structures and dynamics.
49 ///
50 /// The DasherModel implements arithmetic coding for Dasher.
51 /// It contains a tree of DasherNodes and the current viewpoint,
52 /// and evolves the tree by expanding leaves (somewhat in response to DasherView) and
53 /// (eventually) deleting ancestors/parents.
55 ///
56 /// DasherModel does not care what the nodes in the tree are or mean, tho it does handle
57 /// calling CDasherNode::Output() / Undo() on nodes falling under/leaving the crosshair
58 /// (However, determining which nodes are under the crosshair, is done by the CDasherView).
59 ///
60 /// The class is Observable in that it broadcasts a pointer to a CDasherNode when the node's
61 /// children are created.
62 class Dasher::CDasherModel: public Observable<CDasherNode*>, private NoClones
64 public:
65 static const unsigned int NORMALIZATION = 1<<16;
66 static const myint ORIGIN_X=2048, ORIGIN_Y=2048, MAX_Y=4096;
68 /// Constructs a new CDasherModel. Note, must be followed by a call to
69 /// SetNode() before the model can be used.
70 CDasherModel();
71 ~CDasherModel();
73 /// @name Offset routines
74 /// For "bouncing" the display up and down (dynamic button modes)
75 /// @{
78 ///
79 /// Apply an offset to the 'target' coordinates - implements the jumps in
80 /// two button dynamic mode.
81 ///
82 void Offset(int iOffset);
84 ///
85 /// Make the 'target' root coordinates match those currently visible, so any
86 /// Offset(int) currently in progress (i.e. being smoothed over several
87 /// frames) stops (at whatever point it's currently reached). Appropriate for
88 /// abrupt changes in behaviour (such as backing off in button modes)
89 void AbortOffset();
91 /// @}
93 ///
94 /// Reset counter of total nats entered
95 ///
97 void ResetNats() {
98 m_dTotalNats = 0.0;
102 /// Return the total nats entered
105 double GetNats() {
106 return m_dTotalNats;
110 /// @name Rendering
111 /// Methods to do with rendering the model to a view
112 /// @{
115 /// Render the model to a given view, and cause output to happen.
116 /// Note, enqueues nodes onto the Expansion Policy, but does not apply it.
118 void RenderToView(CDasherView *pView, CExpansionPolicy &policy);
120 /// @}
123 /// @name Dynamics
124 /// For controlling movement of the model
125 /// @{
128 /// Schedule a zoom over many frames, such that after the last frame,
129 /// the given range of Dasher coordinates (in the current view)
130 /// will fill the Y-axis. (Used by click mode, button mode etc.)
131 /// Note any safety margin, max-zoom, etc., are the responsibility
132 /// of the caller; this method requires only that y2 > y1.
133 /// \param y1,y2 - target range of y axis, i.e. to move to 0,MAXY
134 /// \param nSteps number of steps to schedule to take us all the way there
135 void ScheduleZoom(dasherint y1, dasherint y2, int nSteps);
137 /// Schedule one frame of movement, with the property that
138 /// <nsteps> calls with the same parameter, should bring
139 /// the given range of Dasher Y-space to fill the axis.
140 /// (Roughly - we use approximations! - but more accurate
141 /// than the first step of a zoom).
142 /// \param y1,y2 - target range of y axis, i.e. to move to 0,MAXY
143 /// \param nSteps number of steps that would take us all the way there
144 /// \param limX X coord at which max speed achieved (any X coord lower than
145 /// this, will be slowed down to that speed).
146 /// \param bExact whether to do "exact" calculations (slower, using floating-point
147 /// pow), or approximate with integers (will move at not-ideal rate in some directions)
148 void ScheduleOneStep(dasherint y1, dasherint y2, int nSteps, int limX, bool bExact);
150 ///Cancel any steps previously scheduled (most likely by ScheduleZoom)
151 void ClearScheduledSteps();
154 /// Called by DasherInterfaceBase to update the bounds of the root node for
155 /// the next step that has been scheduled (whether a multi-step zoom or a
156 /// single step from ScheduleOneStep).
157 /// \return True if this moves the model (by applying a previously-scheduled
158 /// step); false if there were no scheduled steps (=> the model hasn't moved).
160 bool NextScheduledStep();
162 /// @}
164 /// Returns the node that was under the crosshair in the
165 /// last frame that was rendered. (I.e., this is the last
166 /// node output.)
167 CDasherNode *Get_node_under_crosshair();
170 /// This is pretty horrible - a rethink of the start/reset mechanism
171 /// is definitely in order. Used to prevent the root node from being
172 /// too large in various modes before Dasher is started.
175 void LimitRoot(int iMaxWidth);
178 /// Rebuild the tree of nodes from a given root
181 void SetNode(CDasherNode *pNewRoot);
184 /// The current offset of the cursor/insertion point in the text buffer
185 /// - measured in (unicode) characters, _not_ octets.
188 int GetOffset();
190 /// Create the children of a Dasher node
191 void ExpandNode(CDasherNode * pNode);
193 private:
195 // The root of the Dasher tree
196 CDasherNode *m_Root;
198 // Old root notes
199 // TODO: This should probably be rethought at some point - it doesn't really make a lot of sense
200 std::deque < CDasherNode * >oldroots;
202 // Rootmin and Rootmax specify the position of the root node in Dasher coords
203 myint m_Rootmin;
204 myint m_Rootmax;
206 // Permitted range for root node - model cannot zoom beyond this
207 // point without falling back to a new root node.
208 myint m_Rootmin_min;
209 myint m_Rootmax_max;
211 // TODO: Does this need to be brought back? Make it relative to visible region?
212 // The active interval over which Dasher nodes are maintained - this is most likely bigger than (0,DasherY)
213 // CRange m_Active;
215 // Offset used when presenting the model to the user, specified as
216 // Displayed rootmin/max - actual rootmin/rootmax
217 myint m_iDisplayOffset;
219 CDasherNode *m_pLastOutput;
221 // Queue of steps scheduled, represented as pairs
222 // of min/max coordinates for root node
223 std::deque<std::pair<myint,myint> > m_deGotoQueue;
225 /// TODO: Not sure what this actually does
226 double m_dAddProb;
228 // Model parameters... (cached from settings store)
230 // Whether characters entered by alphabet manager are expected to
231 // require conversion.
232 // TODO: Need to rethink this at some point.
233 bool m_bRequireConversion;
235 // Information entered so far in this model
236 double m_dTotalNats;
239 /// Make a child of the root into a new root
242 void Make_root(CDasherNode *pNewRoot);
245 /// Make the parent of the current root into the new root (rebuilding if necessary) - used during backing off
246 /// Return true if successful, false if couldn't.
248 bool Reparent_root();
250 /// Handle the output caused by a change in node over the crosshair. Specifically,
251 /// deletes from m_pLastOutput back to closest ancestor of pNewNode,
252 /// then outputs from that ancestor to that node
253 /// @param pNewNode innermost node now covering the crosshair
254 void OutputTo(CDasherNode *pNewNode);
258 /// Clear the queue of old roots - used when those nodes become
259 /// invalid, eg during changes to conrol mode
262 void ClearRootQueue();
265 /// @}
267 #endif /* #ifndef __DasherModel_h__ */