libraries / Mitov / Mitov_Text.hon commit Added link to project report (97a3ba0)
   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