Browse Source

Adds ability for MLTextCtrl to type the characters out over time

Areloch 1 year ago
parent
commit
6de92264f6

+ 80 - 12
Engine/source/gui/controls/guiMLTextCtrl.cpp

@@ -224,6 +224,13 @@ DefineEngineMethod( GuiMLTextCtrl, forceReflow, void, (),,
       object->reflow();
 }
 
+DefineEngineMethod(GuiMLTextCtrl, isTypingOut, bool, (), ,
+   "@brief Returns true if the text is being actively typed out.\n\n"
+   "@see GuiControl")
+{
+   return object->isTypingOut();
+}
+
 //--------------------------------------------------------------------------
 GuiMLTextCtrl::GuiMLTextCtrl()
 : mTabStops( NULL ), 
@@ -264,7 +271,13 @@ GuiMLTextCtrl::GuiMLTextCtrl()
   mDirty( true ), 
   mAlpha( 1.0f ),
   mHitURL( 0 ),
-  mFontList( NULL )
+  mFontList( NULL ),
+  mUseTypeOverTime(false),
+  mTypeOverTimeStartMS(0),
+  mTypeOverTimeSpeedMS(10),
+  mTypeOverTimeIndex(0),
+   mTypeoutSoundRate(-1),
+   mTypeoutSound(nullptr)
 {   
    mActive = true;
    //mInitialText = StringTable->EmptyString();
@@ -295,6 +308,11 @@ void GuiMLTextCtrl::initPersistFields()
       addField("text",              TypeCaseString,  Offset( mInitialText, GuiMLTextCtrl ), "Text to display in this control.");
       addField("useURLMouseCursor", TypeBool,   Offset(mUseURLMouseCursor,   GuiMLTextCtrl), "If true, the mouse cursor will turn into a hand cursor while over a link in the text.\n"
                                                                       "This is dependant on the markup language used by the GuiMLTextCtrl\n");
+
+      addField("useTypeOverTime", TypeBool, Offset(mUseTypeOverTime, GuiMLTextCtrl), "");
+      addField("typeOverTimeSpeedMS", TypeF32, Offset(mTypeOverTimeSpeedMS, GuiMLTextCtrl), "");
+      addField("typeoutSound", TypeSFXTrackName, Offset(mTypeoutSound, GuiMLTextCtrl), "Played when the text is being typed out");
+      addField("typeoutSoundRate", TypeS32, Offset(mTypeoutSoundRate, GuiMLTextCtrl), "Dictates how many characters must be typed out before the sound is played again. -1 for the sound to only play once at the start.");
    
    endGroup( "Text" );
    
@@ -464,22 +482,46 @@ void GuiMLTextCtrl::onRender(Point2I offset, const RectI& updateRect)
 
       for(Atom *awalk = lwalk->atomList; awalk; awalk = awalk->next)
       {
-         if(!mSelectionActive || mSelectionEnd < awalk->textStart || mSelectionStart >= awalk->textStart + awalk->len)
-            drawAtomText(false, awalk->textStart, awalk->textStart + awalk->len, awalk, lwalk, offset);
+         if (mUseTypeOverTime)
+         {
+            F32 timeDif = Platform::getRealMilliseconds() - mTypeOverTimeStartMS;
+            if (timeDif > mTypeOverTimeSpeedMS)
+            {
+               //It's over the time increment, so update our index and next update timestamp start
+               mTypeOverTimeIndex++;
+               mTypeOverTimeStartMS = Platform::getRealMilliseconds();
+
+               if (mTypeoutSound)
+               {
+                  if((mTypeoutSoundRate <= 0 && mTypeOverTimeIndex == 1) || mTypeOverTimeIndex % mTypeoutSoundRate > 0)
+                     SFX->playOnce(mTypeoutSound);
+               }
+            }
+
+            U32 endPoint = getMin(awalk->textStart + awalk->len, mTypeOverTimeIndex);
+            endPoint = getMax(awalk->textStart, endPoint);
+
+            drawAtomText(false, awalk->textStart, endPoint, awalk, lwalk, offset);
+         }
          else
          {
-            U32 selectionStart = getMax(awalk->textStart, mSelectionStart);
-            U32 selectionEnd = getMin(awalk->textStart + awalk->len, mSelectionEnd + 1);
+            if (!mSelectionActive || mSelectionEnd < awalk->textStart || mSelectionStart >= awalk->textStart + awalk->len)
+               drawAtomText(false, awalk->textStart, awalk->textStart + awalk->len, awalk, lwalk, offset);
+            else
+            {
+               U32 selectionStart = getMax(awalk->textStart, mSelectionStart);
+               U32 selectionEnd = getMin(awalk->textStart + awalk->len, mSelectionEnd + 1);
 
-            // draw some unselected text
-            if(selectionStart > awalk->textStart)
-               drawAtomText(false, awalk->textStart, selectionStart, awalk, lwalk, offset);
+               // draw some unselected text
+               if (selectionStart > awalk->textStart)
+                  drawAtomText(false, awalk->textStart, selectionStart, awalk, lwalk, offset);
 
-            // draw the selection
-            drawAtomText(true, selectionStart, selectionEnd, awalk, lwalk, offset);
+               // draw the selection
+               drawAtomText(true, selectionStart, selectionEnd, awalk, lwalk, offset);
 
-            if(selectionEnd < awalk->textStart + awalk->len)
-               drawAtomText(false, selectionEnd, awalk->textStart + awalk->len, awalk, lwalk, offset);
+               if (selectionEnd < awalk->textStart + awalk->len)
+                  drawAtomText(false, selectionEnd, awalk->textStart + awalk->len, awalk, lwalk, offset);
+            }
          }
       }
    }
@@ -1678,6 +1720,12 @@ void GuiMLTextCtrl::reflow()
    U32 idx;
    U32 sizidx;
 
+   if (mUseTypeOverTime)
+   {
+      mTypeOverTimeStartMS = Platform::getRealMilliseconds();
+      mTypeOverTimeIndex = 1;
+   }
+
    for(;;)
    {
       UTF16 curChar = mTextBuffer.getChar(mScanPos);
@@ -2381,3 +2429,23 @@ bool GuiMLTextCtrl::resize( const Point2I& newPosition, const Point2I& newExtent
    
    return false;
 }
+
+bool GuiMLTextCtrl::isTypingOut()
+{
+   if (!mUseTypeOverTime)
+      return false;
+
+   U32 fullLength = 0;
+   for (Line* lwalk = mLineList; lwalk; lwalk = lwalk->next)
+   {
+      for (Atom* awalk = lwalk->atomList; awalk; awalk = awalk->next)
+      {
+         fullLength += awalk->len;
+      }
+   }
+
+   if (fullLength > mTypeOverTimeIndex)
+      return true;
+
+   return false;
+}

+ 13 - 0
Engine/source/gui/controls/guiMLTextCtrl.h

@@ -99,6 +99,8 @@ class GuiMLTextCtrl : public GuiControl
       Style *style;
       bool isClipped;
 
+      U32 pauseTime;
+
       URL *url;
       Atom *next;
    };
@@ -264,6 +266,15 @@ class GuiMLTextCtrl : public GuiControl
    // Too many chars sound:
    DECLARE_SOUNDASSET(GuiMLTextCtrl, DeniedSound);
    DECLARE_ASSET_SETGET(GuiMLTextCtrl, DeniedSound);
+   // Typeout over time
+   bool mUseTypeOverTime;
+   U32 mTypeOverTimeStartMS;
+   F32 mTypeOverTimeSpeedMS;
+   U32 mTypeOverTimeIndex;
+   U32 mTypeOverTimeTextLen;
+
+   SFXTrack *mTypeoutSound;
+   S32 mTypeoutSoundRate;
    //-------------------------------------- Protected interface
   protected:
    // Inserting and deleting character blocks...
@@ -304,6 +315,8 @@ class GuiMLTextCtrl : public GuiControl
    S32 getCursorPosition()  { return( mCursorPosition ); }
 
    virtual bool resize(const Point2I &newPosition, const Point2I &newExtent);
+
+   bool isTypingOut();
 };
 
 #endif  // _H_GUIMLTEXTCTRL_