Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Cursor$ function
#1
Tongue 
Let me introduce the longest program with absolutely minimal output.

I would call it Cursor$ or InputString$. The program is about cursor control. The entire output of the program is just the cursor. You only need to draw forms and with this function you can insert texts and numbers there (based on Inkey$), it is the first version, so maybe unnecessarily complicated in places in the source.

Function input parameters:

The first two are the graphic coordinates X and Y where the cursor will be displayed, the third parameter is the length of the string to be inserted (calculated here in characters), the fourth parameter is 1 or 0, if there is a 1, the area where the input is expected is highlighted with a rectangle around this area, if there is zero, the area is not visible, the fifth parameter is the color of the box around the area of the expected input (so zero if the previous parameter rectangle is off) and finally the mode. Mode is just cursor style. If it is 1, the cursor flashes as a horizontal line at the bottom, if it is 2, the cursor flashes as a vertical line. I was also thinking about mode 0, where the text would be hidden and replaced by a single character (like when entering a password), but this has not been done yet.

What it can do is described in the program right at the beginning.

Code: (Select All)


'Done:
'Supported doubleclick for end function
'Supported Insert key
'Supported BackSpace key
'Supported bordering with LINE
'Supported Home and End keys
'Supported Delete key
'Support deleting selected area using BackSpace
'repaired text lenght (now is as LENGHT paramater (in characters))
'repaired delete and backspace string deleting if part of the text is selected (add condition above)
'Supported copying selected text to clipboard
'Supported for inserting text from clipboard (3 methods):
'  -insert clipboard string to middle the string if cursor is in middle and nothing is slected
'  -insert clipboard string to the end the string if cursor is at the end
'  -delete selected area and insert clipboard string to this area in string
'Supported cursor position set in text with mouse
'Supported Shift + Home and Shift + End text selecting
'Supported text selecting with mouse
'can be used for 8 bit and 32 bit screens (both tested)


Dim Shared INSERT
Screen _NewImage(1024, 768, 32)
Cls
InputString$ = Cursor$(500, 400, 25, 1, _RGB32(255), 1) '32 bit - try set box (4th) parameter to zero. Then is possible using this to blank form.
'InputString$ = Cursor$(50, 100, 25, 1, 7, 1) '8 bit  - before test this, do not forgot change SCREEN to 256 colors
Print "InputString$ value: "; InputString$
End


Function Cursor$ (Xs, Ys, Lenght, Box, BoxColor~&, Mode)
    Static Active, C$, Selected, SelectStart, SelectEnd, OldK$, OGPos, OmPos, LB

    'function create cursor on selected position with expected behavior

    'Xs - left upper x corner
    'Ys - left upper y corner
    'Lenght - how lenght string is expected (in characters)
    'Box - draw box (Line, B) around? 0 = No, 1 = Yes
    'BoxColor~& - if Box is allowed, so Box color
    'Mode - print characters to screen (1, 2) or not (0) - then it print CHR$(249). 1 Print cursor as "_", 2 Print it as "ł"

    Bck~& = _CopyImage(0)
    GLen = Lenght * _FontWidth 'maximal text lenght in pixels
    If Gpos = 0 Then Gpos = Xs 'cursor graphics position (X axis)
    Dim As _Unsigned Long OnCursorColor, OffCursorColor, SelectColor


    Select Case _PixelSize
        Case 1
            If Box Then Line (Xs - 2, Ys - 2)-(Xs + GLen, Ys + _FontHeight + 2), BoxColor~&, B
            OnCursorColor = 15
            OffCursorColor = 0
            SelectColor = 1
        Case 4
            If Box Then Line (Xs - 2, Ys - 2)-(Xs + GLen, Ys + _FontHeight + 2), BoxColor~&, B
            OnCursorColor = _RGB32(255)
            OffCursorColor = _RGB32(0)
            SelectColor = _RGBA32(255, 255, 0, 150)
    End Select


    Do Until Done
        While _MouseInput
        Wend
        MX = _MouseX
        MY = _MouseY
        LB = _MouseButton(1)


        'click to the cursor's area and activate it until you press enter or escape
        If MX >= Xs And MX <= Xs + GLen Then
            If MY >= Ys - 20 And MY <= Ys + _FontHeight + 20 Then
                _MouseShow "text"
                'click twice and function return output and end
                If LB = -1 Then
                    If Active Then
                        If OmPos = 0 Then 'function can not exit when mouse select text
                            If Timer - t < .3 Then
                                Cursor$ = C$
                                Exit Function
                            End If
                        End If
                    End If
                    Active = 1

                    'calculate graphic cursor position
                    If Gpos = 0 Then Gpos = Xs + Len(C$) * _FontWidth 'default
                    If OmPos = 0 Then
                        'can not use cursor GPOS value here, because mouse use own coordinate
                        chars = (MX - Xs) \ _FontWidth
                        OmPos = chars * _FontWidth + Xs
                        If OmPos < Xs Then OmPos = Xs
                        If OmPos > Xs + _PrintWidth(C$) Then OmPos = Xs + _PrintWidth(C$)
                        'lock default cursor position for mouse selecting
                    End If

                    'zde posledni vklad: oznacit text mysi
                    If Abs(OmPos - Gpos) > _FontWidth \ 2 Then 'if track with mouse is minimal 1 character, select this area
                        mSelected = 1
                        SelectStart = OmPos

                        chars = (MX - Xs) \ _FontWidth
                        SelectEnd = chars * _FontWidth + Xs
                        If SelectEnd < Xs Then SelectEnd = Xs
                        If SelectEnd > Xs + _PrintWidth(C$) Then SelectEnd = Xs + _PrintWidth(C$)
                        Selected = mSelected
                    End If


                    'here - calculate the position for the possibility to set the position of the cursor by clicking in the text
                    If Len(C$) Then
                        If MX > Xs + _PrintWidth(C$) Then Gpos = Xs + _PrintWidth(C$)
                        If MX < Xs Then Gpos = Xs
                        If MX > Xs And MX < Xs + _PrintWidth(C$) Then
                            'calculate pixels from Xs
                            chars = (MX - Xs) \ _FontWidth
                            Gpos = Xs + chars * _FontWidth
                        End If
                    End If


                    t = Timer
                    If OmPos = 0 Then ResetLB
                Else
                    OmPos = 0 'reset mouse graphic cursor position used for text selecting
                    If mSelected = 1 Then
                        mSelected = 0
                    End If
                End If
            End If
        End If

        'move to other area and deactivate cursor without function output
        If MX >= Xs And MX <= Xs + GLen and_
        MY >= Ys - 20 And MY <= Ys + _FontHeight + 20 Then_
        _mouseshow "text" else _mouseshow "default"

        'text insert is possible until is not clicked to other location
        If MX < Xs or MX > Xs + GLen and_
        MY < Ys - 20 or MY > Ys + _FontHeight + 20 and_
        LB = -1 then Active = 0

        Select Case Active
            Case 0
                _PrintMode _FillBackground
            Case 1
                _PrintMode _KeepBackground
                K$ = InKey$
                If Len(K$) Then

                    Select Case Asc(K$)
                        Case 31 To 127 '                        string is created with text
                            If Gpos - Xs = _PrintWidth(C$) Then 'add character this way if cursor is on the end of the string only
                                If Len(C$) < Lenght Then C$ = C$ + K$
                                Selected = 0
                            Else '                              '  add character inside string if cursor is inside
                                If INSERT Then 'ok
                                    T1$ = Left$(C$, (Gpos - Xs) \ _FontWidth) '    the left part of the string
                                    T2$ = Right$(C$, Len(C$) - Len(T1$) - 1) '    right part of the string
                                    C$ = T1$ + K$ + T2$

                                Else
                                    T1$ = Left$(C$, (Gpos - Xs) \ _FontWidth) 'the left part of the string
                                    T2$ = Right$(C$, Len(C$) - Len(T1$)) '    right part of the string
                                    If Len(C$) < Lenght - 1 Then C$ = T1$ + K$ + T2$

                                End If
                            End If
                            If Gpos < Xs + (Lenght - 2) * _FontWidth Then Gpos = Gpos + _FontWidth
                        Case 13 '                      enter end function and return string
                            Cursor$ = C$
                            Selected = 0
                            Gpos = 0
                            Exit Function
                        Case 27 '                      escape end function and return empty string
                            Cursor$ = ""
                            Selected = 0
                            Gpos = 0
                            Exit Function

                        Case 8 '                      backspace
                            If Len(C$) > 0 And Selected = 0 Then
                                If Gpos = Xs Then _Continue
                                T1$ = Left$(C$, (Gpos - Xs) \ _FontWidth - 1) 'the left part of the string
                                T2$ = Right$(C$, Len(C$) - Len(T1$) - 1) 'right part of the string
                                C$ = T1$ + T2$
                                Gpos = Gpos - _FontWidth
                                If Gpos < Xs Then Gpos = Xs
                            End If

                            'condition for text select
                            If Selected Then
                                StringStart = (SelectStart - Xs) \ _FontWidth
                                StringEnd = (SelectEnd - Xs) \ _FontWidth
                                If StringStart > StringEnd Then Swap StringStart, StringEnd
                                'delete selected area in string
                                T1$ = Mid$(C$, 1, StringStart)
                                T2$ = Mid$(C$, StringEnd + 1, Len(C$))
                                C$ = T1$ + T2$
                                If Gpos > Xs + _PrintWidth(C$) Then Gpos = Xs + _PrintWidth(C$)
                            End If


                        Case 22 'Ctrl + V
                            ' if none text is marked and the cursor is at the end, the input is added to the end of the string
                            ' if the text is not marked and the cursor is in the middle of the text, the insert is inserted between
                            ' if the text is marked, the marked part is deleted and overwritten with an insert (inserted between)


                            If Selected = 0 Then
                                If Gpos = Xs + _PrintWidth(C$) Then
                                    C$ = C$ + _Clipboard$
                                    If Len(C$) > Lenght Then C$ = Mid$(C$, 1, Lenght): Gpos = _PrintWidth(C$) 'insert clipboard to end if is cursor at the end
                                Else
                                    T1$ = Mid$(C$, 1, (Gpos - Xs) \ _FontWidth) 'insert clipboard middle to text (to cursor position)
                                    T2$ = Mid$(C$, 1 + (Gpos - Xs) \ _FontWidth, Len(C$))
                                    C$ = T1$ + LTrim$(_Clipboard$) + T2$
                                    If Len(C$) > Lenght Then C$ = Mid$(C$, 1, Lenght)
                                End If
                            Else 'part in text is selected - delete inserted part and place to this place clipboard
                                'test ok
                                StringStart = (SelectStart - Xs) \ _FontWidth
                                StringEnd = (SelectEnd - Xs) \ _FontWidth
                                If StringStart > StringEnd Then Swap StringStart, StringEnd
                                'delete selected area in string
                                T1$ = Mid$(C$, 1, StringStart)
                                T2$ = Mid$(C$, StringEnd + 1, Len(C$))

                                C$ = T1$ + _Clipboard$ + T2$
                                If Len(C$) > Lenght Then C$ = Mid$(C$, 1, Lenght)
                                If Gpos > Xs + _PrintWidth(C$) Then Gpos = Xs + _PrintWidth(C$)
                            End If

                        Case 3 'Ctrl + C                                                    'this copy selected text to clipboard
                            StringStart = (SelectStart - Xs) \ _FontWidth
                            StringEnd = (SelectEnd - Xs) \ _FontWidth
                            If StringStart > StringEnd Then Swap StringStart, StringEnd
                            _Clipboard$ = Mid$(C$, StringStart + 1, StringEnd - StringStart) 'bug repaired
                    End Select

                    If Len(K$) > 1 Then
                        Select Case Asc(K$, 2)
                            Case 75 'left arrow
                                Gpos = Gpos - _FontWidth
                                If Gpos < Xs + 1 Then Gpos = Xs + 1
                                If _KeyDown(100303) = 0 And _KeyDown(100304) = 0 Then

                                    OGPos = 0 'Shift + Home; Shift + End reset (OGpos is previous cursor GPOS graphics variable)
                                    Selected = 0
                                    SelectStart = 0
                                    SelectEnd = 0
                                Else
                                    Selected = 1
                                    If SelectStart = 0 Then
                                        SelectStart = Gpos + _FontWidth
                                        If SelectStart < Xs + 1 Then SelectStart = Xs + 1
                                    End If
                                    SelectEnd = Gpos
                                End If

                            Case 77 'right arrow
                                Gpos = Gpos + _FontWidth
                                If Gpos > Xs + _PrintWidth(C$) Then Gpos = Xs + _PrintWidth(C$)
                                If _KeyDown(100303) = 0 And _KeyDown(100304) = 0 Then

                                    OGPos = 0 'Shift + Home; Shift + End reset
                                    Selected = 0
                                    SelectStart = 0
                                    SelectEnd = 0
                                Else
                                    Selected = 1
                                    If SelectStart = 0 Then
                                        SelectStart = Gpos - _FontWidth
                                        If SelectStart > Xs + _PrintWidth(C$) Then SelectStart = Xs + _PrintWidth(C$)
                                    End If
                                    SelectEnd = Gpos
                                End If

                            Case 82
                                INSERT = Not INSERT 'text insert switch

                            Case 83 'Delete
                                If Len(C$) > 0 And Selected = 0 Then
                                    T1$ = Left$(C$, (Gpos - Xs) \ _FontWidth) 'the left part of the string
                                    T2$ = Right$(C$, Len(C$) - Len(T1$) - 1) 'right part of the string
                                    C$ = T1$ + T2$
                                End If

                                If Selected Then
                                    StringStart = (SelectStart - Xs) \ _FontWidth
                                    StringEnd = (SelectEnd - Xs) \ _FontWidth
                                    If StringStart > StringEnd Then Swap StringStart, StringEnd
                                    'delete selected area in string
                                    T1$ = Mid$(C$, 1, StringStart)
                                    T2$ = Mid$(C$, StringEnd + 1, Len(C$))
                                    C$ = T1$ + T2$
                                    Gpos = SelectStart
                                    If Gpos > Xs + _PrintWidth(C$) Then Gpos = Xs + _PrintWidth(C$)
                                    Selected = 0
                                End If


                            Case 71 'Home key
                                If OGPos = 0 Then OGPos = Gpos
                                Gpos = Xs

                            Case 79 'End key
                                If OGPos = 0 Then OGPos = Gpos
                                Gpos = Xs + _PrintWidth(C$)

                        End Select
                    End If
                End If 'If LEN (K$) condition

                'select mode for selecting part of the text

                kj& = _KeyDown(100304) 'lshift
                kk& = _KeyDown(100303) 'rshift

                If Len(K$) Then OldK$ = K$
                If kk& = -1 Or kj& = -1 Then ' one hour, when my hard stupid head try apply _Keyhit here....
                    If Len(OldK$) = 2 Then
                        If Asc(OldK$, 2) = 77 Or Asc(OldK$, 2) = 75 Then 'if is arrow and shift pressed
                            Selected = 1
                            If SelectStart = 0 Then SelectStart = Gpos 'here its in graphical coordinates
                            SelectEnd = Gpos
                        End If
                    End If
                End If

                If Len(K$) = 1 Then 'reset selected area to none if is something (CHR$ 31 to 127) pressed
                    OldK$ = ""
                    Selected = 0
                    SelectEnd = 0
                    SelectStart = 0
                    ExtraPress = 0
                    OGPos = 0
                End If


                'support for Shift + Home
                kl& = _KeyDown(18176) 'home
                km& = _KeyDown(20224) 'end
                If kk& = -1 And kl& = -1 Or kj& = -1 And kl& = -1 Then 'Shift + HOME
                    If Len(C$) Then
                        SelectStart = Xs
                        SelectEnd = OGPos
                        Selected = 1
                        Gpos = Xs
                    End If
                End If

                If kk& = -1 And km& = -1 Or kj& = -1 And km& = -1 Then 'Shift + END
                    If Len(C$) Then
                        SelectStart = OGPos
                        SelectEnd = Xs + _PrintWidth(C$)
                        Selected = 1
                        Gpos = Xs + _PrintWidth(C$)
                    End If
                End If


                _PrintMode _FillBackground
                'cursor print
                Line (Xs, Ys)-(Xs + GLen - 1, Ys + _FontHeight), OffCursorColor, BF


                Select Case INSERT
                    Case 0 '                                          standard cursor, insert mode is disabled
                        Select Case Mode '                            cursor in mode 1 is line on bottom _
                            Case 1
                                If Timer * 10 Mod 10 < 5 Then
                                    Line (Gpos, Ys + _FontHeight)-(Gpos + _FontWidth, Ys + _FontHeight), OnCursorColor
                                Else
                                    Line (Gpos, Ys + _FontHeight)-(Gpos + _FontWidth, Ys + _FontHeight), OffCursorColor
                                End If

                            Case 2 '                                  cursor in mode 2 is vertical line |
                                If Timer * 10 Mod 10 < 5 Then
                                    Line (Gpos - 1, Ys)-(Gpos - 1, Ys + _FontHeight), OnCursorColor
                                Else
                                    Line (Gpos - 1, Ys)-(Gpos - 1, Ys + _FontHeight), OffCursorColor
                                End If
                        End Select

                    Case -1 '                                        rectangle cursor, insert mode is enabled
                        _PrintMode _KeepBackground
                        If Timer * 10 Mod 10 < 5 Then
                            Line (Gpos, Ys)-(Gpos + _FontWidth, Ys + _FontHeight), OnCursorColor, BF
                        Else
                            Line (Gpos, Ys)-(Gpos + _FontWidth, Ys + _FontHeight), OffCursorColor, BF
                        End If
                End Select

                If Mode = 2 Then _PrintMode _KeepBackground
                _PrintString (Xs, Ys), C$
                _PrintMode _FillBackground

                If Selected Then
                    Line (SelectStart, Ys)-(SelectEnd, Ys + _FontHeight), SelectColor, BF 'for 32 bit screens
                    If _PixelSize = 1 Then 'solution for 8 bit screens
                        _PrintMode _KeepBackground
                        _PrintString (Xs, Ys), C$
                        _PrintMode _FillBackground
                    End If
                End If
        End Select
        _Limit 20
    Loop
End Function

Sub ResetLB
    MB = _MouseButton(1)
    Do Until MB = 0
        While _MouseInput
        Wend
        MB = _MouseButton(1)
    Loop
End Sub 


Reply
#2
Interesting idea, if I have quessed correctly, this is similar to your previous post of allowing multiple text boxes on one screen, ie you are on your way to GUI whether you know it or not. Smile I intend to study that last post and this to confirm my guess. I mean you woke up Keybone!!! My God man!!! Big Grin

more, re GUI: Buttons are a dime a dozen but the Holy Grail of GUI are List Boxes and Text Boxes.
b = b + ...
Reply
#3
BPlus, it could actually can be combined with the previous program so that you could not only read the text in multiple windows at the same time, but also rewrite it. In fact, nothing prevents windows from the previous program to be moved around the monitor by dragging the mouse. Only perhaps the time that the adjustment will take.

When I was writing the InputBox, I realized that I needed to separate the function directly for the cursor. Because the problem is repeated: When entering a file name, when entering a label for an element in the program, and simply at any time you need input from the user. For example - let's say that you build a function for editing the ID3 tag into the player. There are also a couple of those text fields. Or for any form. And it needs cooperation with the mouse, because that is the standard. And that actually gets us to what you're saying, and we can also directly get to InForm (which is a very good thing)


Reply
#4
Yeah for my GUI, I used central handler for mouse and keypresses but it had to figure out what kind of control box it was in.
b = b + ...
Reply




Users browsing this thread: 1 Guest(s)