Sync with trunk r58687.
[reactos.git] / boot / freeldr / freeldr / ui / tui.c
index 2fd5b5c..3f34afd 100644 (file)
@@ -318,7 +318,26 @@ VOID TuiDrawText(ULONG X, ULONG Y, PCSTR Text, UCHAR Attr)
        ULONG   i, j;
 
        // Draw the text
-       for (i=X, j=0; Text[j]  && i<UiScreenWidth; i++,j++)
+       for (i = X, j = 0; Text[j] && i < UiScreenWidth; i++, j++)
+       {
+               ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)] = (UCHAR)Text[j];
+               ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)+1] = Attr;
+       }
+}
+
+/*
+ * DrawText2()
+ * This function assumes coordinates are zero-based.
+ * MaxNumChars is the maximum number of characters to display.
+ * If MaxNumChars == 0, then display the whole string.
+ */
+VOID TuiDrawText2(ULONG X, ULONG Y, ULONG MaxNumChars, PCSTR Text, UCHAR Attr)
+{
+       PUCHAR  ScreenMemory = (PUCHAR)TextVideoBuffer;
+       ULONG   i, j;
+
+       // Draw the text
+       for (i = X, j = 0; Text[j] && i < UiScreenWidth && (MaxNumChars > 0 ? j < MaxNumChars : TRUE); i++, j++)
        {
                ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)] = (UCHAR)Text[j];
                ScreenMemory[((Y*2)*UiScreenWidth)+(i*2)+1] = Attr;
@@ -789,19 +808,20 @@ VOID TuiFadeOut(VOID)
 
 BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
 {
-       int             width = 8;
-       unsigned int    height = 1;
-       int             curline = 0;
-       int             k;
-       size_t          i , j;
-       int             x1, x2, y1, y2;
-       char    temp[260];
-       char    key;
-       int             EditBoxLine;
-       ULONG           EditBoxStartX, EditBoxEndX;
-       int             EditBoxCursorX;
-       unsigned int    EditBoxTextCount;
-       int             EditBoxTextDisplayIndex;
+       INT             width = 8;
+       ULONG   height = 1;
+       INT             curline = 0;
+       INT             k;
+       size_t  i , j;
+       INT             x1, x2, y1, y2;
+       CHAR    temp[260];
+       CHAR    key;
+       BOOLEAN Extended;
+       INT             EditBoxLine;
+       ULONG   EditBoxStartX, EditBoxEndX;
+       INT             EditBoxCursorX;
+       ULONG   EditBoxTextLength, EditBoxTextPosition;
+       INT             EditBoxTextDisplayIndex;
        BOOLEAN ReturnCode;
        PVOID   ScreenBuffer;
 
@@ -855,7 +875,8 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
                        temp[j++] = MessageText[i];
        }
 
-       EditBoxTextCount = 0;
+       EditBoxTextLength = 0;
+       EditBoxTextPosition = 0;
        EditBoxLine = y2 - 2;
        EditBoxStartX = x1 + 3;
        EditBoxEndX = x2 - 3;
@@ -871,13 +892,20 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
 
        VideoCopyOffScreenBufferToVRAM();
 
+       //
+       // Enter the text. Please keep in mind that the default input mode
+       // of the edit boxes is in insertion mode, that is, you can insert
+       // text without erasing the existing one.
+       //
        for (;;)
        {
                if (MachConsKbHit())
                {
+                       Extended = FALSE;
                        key = MachConsGetCh();
                        if(key == KEY_EXTENDED)
                        {
+                               Extended = TRUE;
                                key = MachConsGetCh();
                        }
 
@@ -893,23 +921,71 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
                        }
                        else if (key == KEY_BACKSPACE) // Remove a character
                        {
-                               if (EditBoxTextCount)
+                               if ( (EditBoxTextLength > 0) && (EditBoxTextPosition > 0) &&
+                                    (EditBoxTextPosition <= EditBoxTextLength) )
                                {
-                                       EditBoxTextCount--;
-                                       EditTextBuffer[EditBoxTextCount] = 0;
+                                       EditBoxTextPosition--;
+                                       memmove(EditTextBuffer + EditBoxTextPosition,
+                                               EditTextBuffer + EditBoxTextPosition + 1,
+                                               EditBoxTextLength - EditBoxTextPosition);
+                                       EditBoxTextLength--;
+                                       EditTextBuffer[EditBoxTextLength] = 0;
                                }
                                else
                                {
                                        MachBeep();
                                }
                        }
+                       else if (Extended && key == KEY_DELETE) // Remove a character
+                       {
+                               if ( (EditBoxTextLength > 0) &&
+                                    (EditBoxTextPosition < EditBoxTextLength) )
+                               {
+                                       memmove(EditTextBuffer + EditBoxTextPosition,
+                                               EditTextBuffer + EditBoxTextPosition + 1,
+                                               EditBoxTextLength - EditBoxTextPosition);
+                                       EditBoxTextLength--;
+                                       EditTextBuffer[EditBoxTextLength] = 0;
+                               }
+                               else
+                               {
+                                       MachBeep();
+                               }
+                       }
+                       else if (key == KEY_HOME) // Go to the start of the buffer
+                       {
+                               EditBoxTextPosition = 0;
+                       }
+                       else if (key == KEY_END) // Go to the end of the buffer
+                       {
+                               EditBoxTextPosition = EditBoxTextLength;
+                       }
+                       else if (key == KEY_RIGHT) // Go right
+                       {
+                               if (EditBoxTextPosition < EditBoxTextLength)
+                                       EditBoxTextPosition++;
+                               else
+                                       MachBeep();
+                       }
+                       else if (key == KEY_LEFT) // Go left
+                       {
+                               if (EditBoxTextPosition > 0)
+                                       EditBoxTextPosition--;
+                               else
+                                       MachBeep();
+                       }
                        else // Add this key to the buffer
                        {
-                               if (EditBoxTextCount < Length - 1)
+                               if ( (EditBoxTextLength   < Length - 1) &&
+                                    (EditBoxTextPosition < Length - 1) )
                                {
-                                       EditTextBuffer[EditBoxTextCount] = key;
-                                       EditBoxTextCount++;
-                                       EditTextBuffer[EditBoxTextCount] = 0;
+                                       memmove(EditTextBuffer + EditBoxTextPosition + 1,
+                                               EditTextBuffer + EditBoxTextPosition,
+                                               EditBoxTextLength - EditBoxTextPosition);
+                                       EditTextBuffer[EditBoxTextPosition] = key;
+                                       EditBoxTextPosition++;
+                                       EditBoxTextLength++;
+                                       EditTextBuffer[EditBoxTextLength] = 0;
                                }
                                else
                                {
@@ -922,17 +998,17 @@ BOOLEAN TuiEditBox(PCSTR MessageText, PCHAR EditTextBuffer, ULONG Length)
                UiFillArea(EditBoxStartX, EditBoxLine, EditBoxEndX, EditBoxLine, ' ', ATTR(UiEditBoxTextColor, UiEditBoxBgColor));
 
                // Fill the text in
-               if (EditBoxTextCount > (EditBoxEndX - EditBoxStartX))
+               if (EditBoxTextPosition > (EditBoxEndX - EditBoxStartX))
                {
-                       EditBoxTextDisplayIndex = EditBoxTextCount - (EditBoxEndX - EditBoxStartX);
+                       EditBoxTextDisplayIndex = EditBoxTextPosition - (EditBoxEndX - EditBoxStartX);
                        EditBoxCursorX = EditBoxEndX;
                }
                else
                {
                        EditBoxTextDisplayIndex = 0;
-                       EditBoxCursorX = EditBoxStartX + EditBoxTextCount;
+                       EditBoxCursorX = EditBoxStartX + EditBoxTextPosition;
                }
-               UiDrawText(EditBoxStartX, EditBoxLine, &EditTextBuffer[EditBoxTextDisplayIndex], ATTR(UiEditBoxTextColor, UiEditBoxBgColor));
+               UiDrawText2(EditBoxStartX, EditBoxLine, EditBoxEndX - EditBoxStartX + 1, &EditTextBuffer[EditBoxTextDisplayIndex], ATTR(UiEditBoxTextColor, UiEditBoxBgColor));
 
                // Move the cursor
                MachVideoSetTextCursorPosition(EditBoxCursorX, EditBoxLine);
@@ -963,6 +1039,7 @@ const UIVTBL TuiVtbl =
        TuiDrawShadow,
        TuiDrawBox,
        TuiDrawText,
+       TuiDrawText2,
        TuiDrawCenteredText,
        TuiDrawStatusText,
        TuiUpdateDateTime,