1////////////////////////////////////////////////////////////////////////////////
2// //
3// This software is supplied under the terms of a license agreement or //
4// nondisclosure agreement with Mitov Software and may not be copied //
5// or disclosed except in accordance with the terms of that agreement. //
6// Copyright(c) 2002-2016 Mitov Software. All Rights Reserved. //
7// //
8////////////////////////////////////////////////////////////////////////////////
9
10#ifndef _MITOV_TEXT_h
11#define _MITOV_TEXT_h
12
13#include <Mitov.h>
14
15namespace Mitov
16{
17//---------------------------------------------------------------------------
18 class TextValue : public Mitov::CommonSource, public Mitov::ClockingSupport
19 {
20 typedef Mitov::CommonSource inherited;
21
22 public:
23 String Value;
24
25 protected:
26 virtual void SystemStart() override
27 {
28 inherited::SystemStart();
29 OutputPin.Notify( (void *)Value.c_str() );
30 }
31
32 virtual void DoClockReceive( void *_Data ) override
33 {
34 OutputPin.Notify( (void *)Value.c_str() );
35 }
36
37 public:
38 TextValue( char *AValue ) :
39 Value( AValue )
40 {
41 }
42
43 };
44//---------------------------------------------------------------------------
45 class BindableTextValue : public TextValue
46 {
47 typedef TextValue inherited;
48
49 protected:
50 String OldValue = inherited::Value;
51
52 protected:
53 virtual void SystemInit()
54 {
55 inherited::SystemInit();
56 OldValue = inherited::Value;
57 }
58
59 virtual void SystemLoopBegin( unsigned long currentMicros )
60 {
61 if( inherited::Value == OldValue )
62 return;
63
64 OldValue = inherited::Value;
65 inherited::OutputPin.Notify( (void *)OldValue.c_str() );
66 }
67
68 public:
69 BindableTextValue( char *AValue ) :
70 inherited( AValue ),
71 OldValue( AValue )
72 {
73 }
74
75 };
76//---------------------------------------------------------------------------
77 class BasicFormattedText;
78//---------------------------------------------------------------------------
79 class FormattedTextElementBasic : public OpenWire::Object // : public OpenWire::Component
80 {
81// typedef OpenWire::Component inherited;
82 protected:
83 BasicFormattedText &FOwner;
84
85 public:
86 virtual String GetText() = 0;
87
88 virtual void SystemStart()
89 {
90 }
91
92 public:
93 FormattedTextElementBasic( BasicFormattedText &AOwner );
94
95 };
96//---------------------------------------------------------------------------
97 class BasicFormattedText : public Mitov::CommonSource, public Mitov::ClockingSupport
98 {
99 typedef Mitov::CommonSource inherited;
100
101 public:
102 Mitov::SimpleList<FormattedTextElementBasic *> FElements;
103
104 protected:
105 bool FModified = false;
106
107 public:
108 inline void SetModified()
109 {
110 FModified = true;
111 }
112
113 };
114//---------------------------------------------------------------------------
115 template <typename T_STRING> class BasicTypedFormattedText : public Mitov::BasicFormattedText
116 {
117 typedef Mitov::BasicFormattedText inherited;
118
119 protected:
120 struct TStringItem
121 {
122 T_STRING Text;
123 FormattedTextElementBasic *Element;
124 };
125
126 protected:
127 Mitov::SimpleList<TStringItem *> FReadyElements;
128
129 public:
130 void AddReadyElement( T_STRING ATextItem, int AIndex )
131 {
132// Serial.print( "AddElement: " ); Serial.print( ATextItem ); Serial.println( AIndex );
133
134 TStringItem *AItem = new TStringItem;
135 AItem->Text = ATextItem;
136// Serial.print( "AddElement: " ); Serial.println( AItem->Text );
137 if( AIndex < FElements.size() )
138 AItem->Element = FElements[ AIndex ];
139
140 else
141 AItem->Element = NULL;
142
143 FReadyElements.push_back( AItem );
144
145// Serial.println( FReadyElements[ FReadyElements.size() - 1 ]->Text );
146// Serial.println( "DEBUG>>" );
147// for( Mitov::SimpleList<TStringItem *>::iterator Iter = FReadyElements.begin(); Iter != FReadyElements.end(); ++Iter )
148// Serial.println( ( *Iter )->Text );
149
150// Serial.println( "<<DEBUG" );
151 }
152
153 protected:
154 void ProcessSendOutput()
155 {
156// Serial.println( "ProcessSendOutput" );
157 String AText;
158 for( typename Mitov::SimpleList<TStringItem *>::iterator Iter = FReadyElements.begin(); Iter != FReadyElements.end(); ++Iter )
159 {
160// Serial.println( ( *Iter )->Text );
161 AText += ( *Iter )->Text;
162 if( ( *Iter )->Element )
163 AText += ( *Iter )->Element->GetText();
164 }
165
166// Serial.println( AText );
167 inherited::OutputPin.Notify( (void *)AText.c_str() );
168 FModified = false;
169 }
170
171 protected:
172 virtual void SystemLoopEnd() override
173 {
174 if( FModified )
175 if( ! ClockInputPin.IsConnected() )
176 ProcessSendOutput();
177
178 inherited::SystemLoopEnd();
179 }
180
181 protected:
182 virtual void DoClockReceive( void *_Data ) override
183 {
184 ProcessSendOutput();
185 }
186
187 };
188//---------------------------------------------------------------------------
189 class FormattedText_Fixed : public Mitov::BasicTypedFormattedText<char *>
190 {
191 typedef Mitov::BasicTypedFormattedText<char *> inherited;
192
193 public:
194 void AddNullElement( char *ATextItem )
195 {
196 TStringItem *AItem = new TStringItem;
197
198 AItem->Text = ATextItem;
199 AItem->Element = NULL;
200
201 inherited::FReadyElements.push_back( AItem );
202 }
203
204 protected:
205 virtual void SystemStart() override
206 {
207 for( Mitov::SimpleList<FormattedTextElementBasic *>::iterator Iter = FElements.begin(); Iter != FElements.end(); ++Iter )
208 (*Iter )->SystemStart();
209
210 inherited::SystemStart();
211 ProcessSendOutput();
212 }
213
214 };
215//---------------------------------------------------------------------------
216 class FormattedText : public Mitov::BasicTypedFormattedText<String>
217 {
218 typedef Mitov::BasicTypedFormattedText<String> inherited;
219
220 public:
221 String Text;
222
223 protected:
224 void InitElements()
225 {
226 FReadyElements.clear();
227 String ATextItem;
228 String AIndexText;
229 bool AInEscape = false;
230
231// Serial.println( "INIT" );
232// Serial.println( Text );
233// delay( 1000 );
234
235 for( int i = 0; i < Text.length(); ++ i )
236 {
237 char AChar = Text[ i ];
238 if( AInEscape )
239 {
240 if( AChar >= '0' && AChar <= '9' )
241 AIndexText += AChar;
242
243 else
244 {
245 if( AChar == '%' )
246 {
247 if( AIndexText.length() == 0 )
248 ATextItem += '%';
249
250 else
251 {
252 AddReadyElement( ATextItem, AIndexText.toInt() );
253 ATextItem = "";
254 }
255
256 }
257
258 else
259 {
260 if( AIndexText.length() == 0 )
261 ATextItem += '%';
262
263 else
264 {
265 AddReadyElement( ATextItem, AIndexText.toInt() );
266 ATextItem = "";
267 }
268
269 ATextItem += AChar;
270 }
271
272 AInEscape = false;
273 }
274 }
275
276 else
277 {
278 if( AChar == '%' )
279 {
280 AInEscape = true;
281 AIndexText = "";
282 }
283
284 else
285 ATextItem += AChar;
286
287 }
288
289 }
290
291 if( AInEscape )
292 AddReadyElement( ATextItem, AIndexText.toInt() );
293
294 else if( ATextItem.length() )
295 {
296 TStringItem *AItem = new TStringItem;
297
298 AItem->Text = ATextItem;
299 AItem->Element = NULL;
300
301 FReadyElements.push_back( AItem );
302 }
303
304// Serial.println( "DEBUG>>" );
305// for( Mitov::SimpleList<TStringItem *>::iterator Iter = FReadyElements.begin(); Iter != FReadyElements.end(); ++Iter )
306// Serial.println( ( *Iter )->Text );
307
308// Serial.println( "<<DEBUG" );
309 }
310
311 protected:
312 virtual void SystemStart() override
313 {
314 for( Mitov::SimpleList<FormattedTextElementBasic *>::iterator Iter = FElements.begin(); Iter != FElements.end(); ++Iter )
315 (*Iter )->SystemStart();
316
317 InitElements();
318 inherited::SystemStart();
319 ProcessSendOutput();
320 }
321
322 };
323//---------------------------------------------------------------------------
324 template<typename T_LCD, T_LCD *T_LCD_INSTANCE, typename T> class TextFormatElementInput : public Mitov::CommonSink
325 {
326 typedef Mitov::CommonSink inherited;
327
328 protected:
329 virtual void DoReceive( void *_Data ) override
330 {
331 T_LCD_INSTANCE->SetValue( String( *(T*)_Data ));
332 }
333 };
334//---------------------------------------------------------------------------
335 template<typename T_LCD, T_LCD *T_LCD_INSTANCE> class TextFormatElementStringInput : public Mitov::CommonSink
336 {
337 typedef Mitov::CommonSink inherited;
338
339 protected:
340 virtual void DoReceive( void *_Data ) override
341 {
342 T_LCD_INSTANCE->SetValue( (char*)_Data );
343 }
344 };
345//---------------------------------------------------------------------------
346 template<typename T_LCD, T_LCD *T_LCD_INSTANCE, typename T_OBJECT> class TextFormatElementObjectInput : public Mitov::CommonSink
347 {
348 typedef Mitov::CommonSink inherited;
349
350 protected:
351 virtual void DoReceive( void *_Data ) override
352 {
353 T_LCD_INSTANCE->SetValue( ((T_OBJECT *)_Data)->ToString() );
354 }
355 };
356//---------------------------------------------------------------------------
357 class FormattedTextElementText : public FormattedTextElementBasic
358 {
359 typedef Mitov::FormattedTextElementBasic inherited;
360
361 public:
362 String InitialValue;
363 String FValue;
364
365 public:
366 void SetValue( String AValue )
367 {
368 FOwner.SetModified();
369 FValue = AValue;
370 }
371
372 public:
373 virtual String GetText()
374 {
375 return FValue;
376 }
377
378 public:
379 virtual void SystemStart()
380 {
381// inherited::SystemStart();
382 FValue = InitialValue;
383 }
384
385 public:
386 using inherited::inherited;
387
388 };
389//---------------------------------------------------------------------------
390 class FormattedTextInputElement : public FormattedTextElementBasic
391 {
392 typedef Mitov::FormattedTextElementBasic inherited;
393
394 public:
395 OpenWire::SinkPin InputPin;
396
397 protected:
398 virtual void DoReceive( void *_Data ) = 0;
399
400 public:
401 FormattedTextInputElement( BasicFormattedText &AOwner ) :
402 inherited( AOwner )
403 {
404 InputPin.SetCallback( this, (OpenWire::TOnPinReceive)&FormattedTextInputElement::DoReceive );
405 }
406
407 };
408//---------------------------------------------------------------------------
409 template<typename T> class FormattedTextElementTyped : public FormattedTextInputElement
410 {
411 typedef Mitov::FormattedTextInputElement inherited;
412
413 public:
414 T InitialValue;
415 T FValue;
416
417 public:
418 virtual void SystemStart()
419 {
420// inherited::SystemStart();
421 FValue = InitialValue;
422 }
423
424 protected:
425 virtual void DoReceive( void *_Data )
426 {
427 FOwner.SetModified();
428 FValue = *(T *)_Data;
429 InitialValue = FValue;
430 }
431
432 public:
433 using inherited::inherited;
434
435 };
436//---------------------------------------------------------------------------
437 class FormattedTextElementInteger : public Mitov::FormattedTextElementTyped<long>
438 {
439 typedef Mitov::FormattedTextElementTyped<long> inherited;
440
441 public:
442 int Base = 10;
443
444 public:
445 virtual String GetText()
446 {
447 char AText[ 50 ];
448 itoa( FValue, AText, Base );
449
450 return AText;
451 }
452
453 public:
454 using inherited::inherited;
455
456 };
457//---------------------------------------------------------------------------
458 class FormattedTextElementAnalog : public Mitov::FormattedTextElementTyped<float>
459 {
460 typedef Mitov::FormattedTextElementTyped<float> inherited;
461
462 public:
463 int MinWidth = 1;
464 int Precision = 3;
465
466 public:
467 virtual String GetText()
468 {
469 char AText[ 50 ];
470 dtostrf( FValue, MinWidth, Precision, AText );
471
472 return AText;
473 }
474
475 public:
476 using inherited::inherited;
477
478 };
479//---------------------------------------------------------------------------
480 class FormattedTextElementDigital : public Mitov::FormattedTextElementTyped<bool>
481 {
482 typedef Mitov::FormattedTextElementTyped<bool> inherited;
483
484 public:
485 String TrueValue = "true";
486 String FalseValue = "false";
487
488 public:
489 virtual String GetText()
490 {
491 if( FValue )
492 return TrueValue;
493
494 return FalseValue;
495 }
496
497 public:
498 using inherited::inherited;
499
500 };
501//---------------------------------------------------------------------------
502//---------------------------------------------------------------------------
503//---------------------------------------------------------------------------
504//---------------------------------------------------------------------------
505 FormattedTextElementBasic::FormattedTextElementBasic( BasicFormattedText &AOwner ) :
506 FOwner( AOwner )
507 {
508 AOwner.FElements.push_back( this );
509 }
510//---------------------------------------------------------------------------
511}
512
513#endif