Jump to content

Mind Reading


Recommended Posts

  • Moderators

Hi all,

I do not like having to press a button after entering a number in an input to get the value actioned - neither am I great fan of actioning every number that is found in an input while the entire number is entered (i.e. actioning 1, 12, 123, 1234, 12345, etc). So I have been playing around with a way to set a time delay after which the user is deemed to have finished typing and the complete number has been entered. A sort of mind-reading exercise! ;)

Would any readers mind trying the script below and seeing what values work for you? The idea is that you look at the number displayed and then enter it as if it was a number you were inputting yourself. The "Constant delay" slider sets the value in ms after which you are deemed to have stopped typing and current value is actioned. Selecting the "Supplementary delay" radio shows another slider which adds a little to the delay for each additional digit entered - this means that you compensate for any slowing down as you remember the next digit and search for the appropriate key. A MsgBox pops up when the script thinks you have finished and lets you know what number it actually actioned and whether it was what you were supposed to enter, as well as the final delay used to determine the end of the input cycle (intermediate delays are shown in the SciTE console). It distinguishes between not enough characters (it reacted too quickly) and and an incorrect entry (not really a problem as this is not a memory test). I would be grateful if you could please let me know the method and values you find best suited to your own keypress style - it will obviously be a compromise between having sufficient time to enter the digits and reducing to a minimum the wait after you finish entering the complete number. :)

Here is the script to run:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

Global $fReady = True, $iDelay

$hGUI = GUICreate("Test", 500, 500)

$hInput = GUICtrlCreateInput("", 10, 10, 200, 20)

$hCrib = GUICtrlCreateLabel("", 10, 50, 480, 100)
GUICtrlSetFont(-1, 54)

$hRadio_Flat = GUICtrlCreateRadio(" Constant delay", 10, 400, 200, 20)
GUICtrlSetState(-1, $GUI_CHECKED)
$hRadio_Supp  = GUICtrlCreateRadio(" Supplementary delay", 260, 400, 200, 20)

$hTitle_1 = GUICtrlCreateLabel("Select delay", 10, 440, 80, 20)
$hLabel_1 = GUICtrlCreateLabel("800", 90, 440, 100, 20)
$hSlider_1 = GUICtrlCreateSlider(10, 460, 200, 20)
GUICtrlSetData(-1, 50)
$hSlider_1_Handle = GUICtrlGetHandle(-1)

$hTitle_2 = GUICtrlCreateLabel("Select supp delay", 260, 440, 100, 20)
GUICtrlSetState(-1, $GUI_HIDE)
$hLabel_2 = GUICtrlCreateLabel("50", 360, 440, 100, 20)
GUICtrlSetState(-1, $GUI_HIDE)
$hSlider_2 = GUICtrlCreateSlider(260, 460, 200, 20)
GUICtrlSetState(-1, $GUI_HIDE)
GUICtrlSetData(-1, 50)
$hSlider_2_Handle = GUICtrlGetHandle(-1)

GUISetState()

; Register messages
GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")
GUIRegisterMsg($WM_HSCROLL, "_WM_HSCROLL")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hSlider_1, $hSlider_2
            ; Reset focus to input
            GUICtrlSetState($hInput, $GUI_FOCUS)
        Case $hRadio_Flat
            ; Disable Add delay controls
            GUICtrlSetState($hTitle_2, $GUI_HIDE)
            GUICtrlSetState($hLabel_2, $GUI_HIDE)
            GUICtrlSetState($hSlider_2, $GUI_HIDE)
            ; Reset focus to input
            GUICtrlSetState($hInput, $GUI_FOCUS)
        Case $hRadio_Supp
            ; Enable Add delay controls
            GUICtrlSetState($hTitle_2, $GUI_SHOW)
            GUICtrlSetState($hLabel_2, $GUI_SHOW)
            GUICtrlSetState($hSlider_2, $GUI_SHOW)
            ; Reset focus to input
            GUICtrlSetState($hInput, $GUI_FOCUS)
    EndSwitch

    If $fReady = True Then
        $sCrib = ""
        $sCrib &= Random(1, 9, 1)
        For $i = 1 To Random(2, 5)
            $sCrib &= Random(0, 9, 1)
        Next
        GUICtrlSetData($hCrib, $sCrib)
        $fReady = False
        ; Reset focus to input
        GUICtrlSetState($hInput, $GUI_FOCUS)
    EndIf

WEnd

Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam

    If BitShift($wParam, 16) = 0x300 Then ; $EN_CHANGE
        Switch BitAND($wParam, 0xFFFF)
            Case $hInput
                ; Clear Adlib function
                AdlibUnRegister("_DoIt")
                ; Remove any non digits from Line input
                Local $sInput = GUICtrlRead($hInput)
                If StringRegExp($sInput, '[^\d]') Then
                    $sInput = StringRegExpReplace($sInput, '[^\d]', '')
                    GUICtrlSetData($hInput, $sInput)
                EndIf
                ; Get required delay
                $iDelay = 300 + 10 * GUICtrlRead($hSlider_1)
                ; Add supplementary delay if required
                If GUICtrlRead($hRadio_Supp) = 1 Then
                    ConsoleWrite("Initial delay: " & $iDelay & " + ")
                    ; Add required supplementary delay for each digit in input
                    $iAddDelay = StringLen($sInput) * GUICtrlRead($hSlider_2)
                    ConsoleWrite("Supp delay: " & $iAddDelay & " = ")
                    $iDelay += $iAddDelay
                EndIf
                ConsoleWrite("Final delay: " & $iDelay & @CRLF & @CRLF)
                ; Register Adlib function to run if no more entries after delay expires
                AdlibRegister("_DoIt", $iDelay)
        EndSwitch
    EndIf

EndFunc   ;==>_WM_COMMAND

Func _DoIt()

    ; Clear Adlib function to prevent multiple running as this blocking function will take longer than $iDelay to run
    AdlibUnRegister("_DoIt")
    $sCorrect = "All correct"
    ; Action a valid input
    If GUICtrlRead($hInput) <> "" Then
        ; Check if input was correct
        If StringLen(GUICtrlRead($hCrib)) <> StringLen(GUICtrlRead($hInput)) Then
            $sCorrect = "Wrong number of chars"
        ElseIf GUICtrlRead($hCrib) <> GUICtrlRead($hInput) Then
            $sCorrect = "Not accurate"
        EndIf
        MsgBox(0, "Action", "Action on " & GUICtrlRead($hInput) & @CRLF & @CRLF & "Final delay = " & $iDelay & @CRLF & @CRLF & $sCorrect)
        ; Set up for next run
        GUICtrlSetData($hInput, "")
        GUICtrlSetData($hCrib, "")
        $fReady = True
        ; Clear the new Adlib function created by clearing the input
        AdlibUnRegister("_DoIt")
    EndIf

EndFunc

Func _WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam

    Switch $lParam
        Case $hSlider_1_Handle
            GUICtrlSetData($hLabel_1, 300 + 10 * GUICtrlRead($hSlider_1))
        Case $hSlider_2_Handle
            GUICtrlSetData($hLabel_2, GUICtrlRead($hSlider_2))
    EndSwitch
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_HSCROLL

I stress again that it is not a test of memory, purely a trial to see which method and what delays best suit your input speed. My aim is to see if there is general agreement on what method and values are suitable or whether the variance is such that an "Options" menu is required to allow users to set their own values (rather like the Windows mouse double click delay dialog).

Thanks in advance for any assistance. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

Manadar,

:) - purely unintentional that one! ;)

By the way, if anyone knows a better way to do this.............. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

1200 on constant seemed ok for me even if i looked up occasionally, if there had been more digits it would have need more time.

But im not a touch typist so my speed is slow

And i agree a preset delay to stop the 1,12,123 etc would be usefull.

Chimaera

Edited by Chimaera
Link to comment
Share on other sites

Melba23, you never cease to amaze me. I wonder, does this script have anything to do with your post in this thread, Both that code, and this code, will eventually be used in at least two scripts I have written and run on an almost daily basis. In this script, I found the default value (800) to be the median between 600 & 1100, With 600 being almost too fast for 5 digit numbers, and 1100 almost too slow. I found not much use for the Supplemental delay. If this 'feature' is used in a script, I feel both the values should be in a 'options tab' or something, to let the user set his/her personal values.

Good job! Thanks for inadvertently helping to improve a few of my own scripts!

- Bruce /*somdcomputerguy */  If you change the way you look at things, the things you look at change.

Link to comment
Share on other sites

  • Moderators

somdcomputerguy,

you never cease to amaze me

Gosh, what to say...(shuffle, shuffle) :)

No, it has nothing to do with that thread. It is an entirely independent concept but one which has exercised me for some time. I came up with this code but quickly realised that my own preferences for the delay values might not be suitable for everyone - as the replies so far seem to confirm! ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I realize this is just an experiment... but I think you're missing an easier solution. You don't actually have to click a button, you can setup the GUI so that pressing enter will trigger an action. It can be as simple as having a default button moved outside the visible area.

Until computers are controlled via thought, you're going to run into the same problem with your experiment: The time varies from person to person and even situation to situation. You're getting feedback from people in a single usage scenario. Their numbers will change if their usage scenario changes. Just a couple examples that will change an individuals times:

  • Changing keyboards to one that is unfamiliar will slow a person down.
  • Changing the input source from "my brain" to anything else will have the effect of altering the time. The person may be typing in dictation over a phone which will have all kinds of latency as one person speaks, the voice data is transferred, the receiver hears and then types the number.
What this means is that to be reliable you will need to set a very large timeout. Some people won't notice, other people will complete their typing so quick and then be sitting there for what feels like an eternity waiting for something to happen. This will make your brilliant interface design feel awkward and clunky to those people. All to solve problem that can be remedied by requiring a single extra keystroke to press enter.

There are certainly uses for "mind reading". If you're going to dynamically react to the input such as auto-complete or Google Search then it's not a bad idea. I don't think data input is - which is precisely what your experiment describes - the place, though, as it will create an inferior feeling UI.

Link to comment
Share on other sites

I agree with Valik's points, but this has other uses. The one that immediately comes to mind is search-as-you-type. Many apps do this, and it's a nice feature to delay to search until a meaningful search term has been entered, which is usually after a slightly delay once typing has stopped. So yes, choose your battles wisely, but there's definitely usefulness here.

Edited by wraithdu
Link to comment
Share on other sites

  • Moderators

Valik,

Thanks for the comments. I have used the "Enter" key (either on a hidden button or using an accelerator key) to end the input on many occasions. I just wanted to run this experiment to see if the range of responses was as wide as I feared it might be - from the small number of responses so far I can see that these fears were altogether justified. :)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

Hi again,

Despite the valid concerns emitted above by Valik, a few people seemed interested in the idea of getting an input to auto-action. Here is an improved (I hope :)) version which looks at the average time spent entering the digits to set the delay before auto-actioning the content. This caters for fast or slow typists - all you need to be is reasonably consistent. To help in this, you can set a minimum delay to cater for very fast successive inputs (such as repeating the same digit) which could give an artificially reduced average figure: ;)

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

; Only Global in this example to get the value displayed in the MsgBox - normally Static in _WM_COMMAND
Global $iAverage_Delay = 10000

; Create GUI
$hGUI = GUICreate("Test", 500, 500)

$hInput = GUICtrlCreateInput("", 10, 10, 200, 20)

$hCrib = GUICtrlCreateLabel("", 10, 80, 480, 100)
GUICtrlSetFont(-1, 54)

$hTitle_1 = GUICtrlCreateLabel("Select min delay", 10, 440, 80, 20)
$hLabel_1 = GUICtrlCreateLabel("500", 90, 440, 100, 20)
$hSlider_1 = GUICtrlCreateSlider(10, 460, 200, 20)
GUICtrlSetData(-1, 50)
$hSlider_1_Handle = GUICtrlGetHandle(-1)

GUISetState()

; Register messages
GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")
GUIRegisterMsg($WM_HSCROLL, "_WM_HSCROLL")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
        Case $hSlider_1
            ; Reset focus to input
            GUICtrlSetState($hInput, $GUI_FOCUS)
    EndSwitch

    ; Give a new number to enter
    If GUICtrlRead($hCrib) = "" Then
        $sCrib = ""
        $sCrib &= Random(1, 9, 1)
        For $i = 1 To Random(2, 5)
            $sCrib &= Random(0, 9, 1)
        Next
        GUICtrlSetData($hCrib, $sCrib)
        ; Reset focus to input
        GUICtrlSetState($hInput, $GUI_FOCUS)
    EndIf

WEnd

Func _WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $lParam

    Static $iDelay, $iBegin = 0, $iTotal_Delay = 0 ;, $iAverage_Delay ; Set Global in this example as used in _DoIt to display final value

    If BitShift($wParam, 16) = 0x300 Then ; $EN_CHANGE
        Switch BitAND($wParam, 0xFFFF)
            Case $hInput
                AdlibUnRegister("_DoIt")
                $sInput = GUICtrlRead($hInput)
                If StringRegExp($sInput, '[^\d]') Then
                    ; Remove any non-digits - ignore the keypress
                    $sInput = StringRegExpReplace($sInput, '[^\d]', '')
                    GUICtrlSetData($hInput, $sInput)
                    ; Reset the timer
                    If $iBegin <> 0 Then
                        $iBegin = TimerInit()
                    EndIf
                Else
                    Switch StringLen($sInput)
                        Case 0
                            ; Reset all variables as we are starting a new sequence
                            $iBegin = 0
                            $iAverage_Delay = 10000
                        Case 1
                            ; Start count for the second key press
                            $iBegin = TimerInit()
                            $iTotal_Delay = 0
                        Case Else
                            ; Add the last delay time - must be less than the set delay
                            $iTotal_Delay += Int(TimerDiff($iBegin))
                            ConsoleWrite("Total: " & $iTotal_Delay)
                            ; Calculate the average delay so far
                            $iAverage_Delay = Int($iTotal_Delay / (StringLen($sInput) - 1))
                            ConsoleWrite(" gives Average: " & $iAverage_Delay)
                            ; Check if it is below the minimum set
                            If $iAverage_Delay < 10 * GUICtrlRead($hSlider_1) Then
                                $iAverage_Delay = 10 * GUICtrlRead($hSlider_1)
                                ConsoleWrite(" but Average reset to: " & $iAverage_Delay)
                            EndIf
                            ; Restart the timer
                            $iBegin = TimerInit()
                    EndSwitch
                EndIf
                ; Only set the Adlib function if there is some input
                If GUICtrlRead($hInput) <> "" Then
                    ; Set the delay at 1.5 the average so far
                    ConsoleWrite(" --- Setting delay of: " & 1.5 * $iAverage_Delay & @CRLF)
                    AdlibRegister("_DoIt", 1.5 * $iAverage_Delay)
                EndIf
        EndSwitch
    EndIf

EndFunc   ;==>_WM_COMMAND

Func _DoIt()

    ; Clear Adlib function to prevent multiple running as this blocking function will take longer than $iDelay to run
    AdlibUnRegister("_DoIt")
    $sCorrect = "All correct"
    ; Action a valid input
    If GUICtrlRead($hInput) <> "" Then
        ; Check if input was correct
        If StringLen(GUICtrlRead($hCrib)) <> StringLen(GUICtrlRead($hInput)) Then
            $sCorrect = "Wrong number of chars"
        ElseIf GUICtrlRead($hCrib) <> GUICtrlRead($hInput) Then
            $sCorrect = "Not accurate"
        EndIf
        MsgBox(0, "Action", "Action on " & GUICtrlRead($hInput) & @CRLF & @CRLF & "Final delay = " & Int(1.5 * $iAverage_Delay) & @CRLF & @CRLF & $sCorrect)
        ; Set up for next run
        GUICtrlSetData($hInput, "")
        GUICtrlSetData($hCrib, "")
        ConsoleWrite(@CRLF)
    EndIf

EndFunc

Func _WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam)

    #forceref $hWnd, $iMsg, $wParam

    Switch $lParam
        Case $hSlider_1_Handle
            GUICtrlSetData($hLabel_1, 10 * GUICtrlRead($hSlider_1))
    EndSwitch
    Return $GUI_RUNDEFMSG

EndFunc   ;==>_WM_HSCROLL

Not looking for any testing, just offered for interest. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Nice Example Melba and I'm positive I will have some use for this in the future :)

UDF List:

 
_AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

I've been implementing control latency to accomodate certain scenarios - such as keys being held down for a period. I think that such a feature needs to have an adjustable setting. I have a default 700 millisecond delay built into an optional autocorrect feature. It has some very useful attributes. Faulty Dubious (or out of bounds) entries are displayed with errors highlighted issues just long enough for the user to notice a problem with the input, before it is automatically replaced with more accurate data. This in turn triggers other events (multiple readout controls). I wouldn't want to change this behaviour, because it gives the user lots of helpful information.

Edit

Now I run the script. You read my mind. :)

Edit2

The main difference is that I am using timers instead of AdlibRegister. I think that 700 millisceconds is pretty much a minimum latency if information (eg ???) is to be displayed during the delay. Some people might take in information much quicker, but generally between 700 and 1000 ms seems appropriate for my application. It will depend on circumstances, of course. In this case, it is also important that the feature can be turned off. The program can parse the input data anyway, one way or the other.

I'm glad you brought this topic up: I will be following it with interest.

Edited by czardas
Link to comment
Share on other sites

How about this:

When input changes, you perform the calculations, but have a way to stop it, so that if another key is pressed then it starts doing the new ones. This way you will not lose any time waiting to see if a new key is pressed. You will still get elements updating if you are a slow typist. As an example, if you were to perform complex maths with big numbers, that take a noticeable amount of time to complete.

Link to comment
Share on other sites

How about this:

When input changes, you perform the calculations, but have a way to stop it, so that if another key is pressed then it starts doing the new ones. This way you will not lose any time waiting to see if a new key is pressed. You will still get elements updating if you are a slow typist. As an example, if you were to perform complex maths with big numbers, that take a noticeable amount of time to complete.

Yeah, if you do some heavy duty back end stuff, then it will need to be interrupted. The calculations I am using are almost instantaneous, hence the control's sensitivity needs to be set. Rather like the speed of a double click needs to be set. If the control updates too quickly, it becomes unusable because it AutoCorrects before you have finished typing.


BTW, I'm not talking about AutoComplete. What I have is more like a grammar check than a spell check, and is dependant on input data within several controls. For example: control A sends a message to Control B, and the data in Control B is adjusted accordingly (providing several conditions are met). I agree with Valik that inbuilt latency will be annoying for some users, and therefore I have made the feature optional. AutoCorrect is there to assist the majority of users who, I can more or less guarantee, will be unfamiliar with all the 'grammar' of the language that they are typing into the control, including myself.

Sorry for hijacking your thread M23, I thought it might give you some ideas.

Edited by czardas
Link to comment
Share on other sites

Here's out my output. I slowed down my typing speed near the end because I got distracted at work...

--- Setting delay of: 15000
Total: 250 gives Average: 250 but Average reset to: 500 --- Setting delay of: 750
Total: 600 gives Average: 300 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 210 gives Average: 210 but Average reset to: 500 --- Setting delay of: 750
Total: 370 gives Average: 185 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 320 gives Average: 320 but Average reset to: 500 --- Setting delay of: 750
Total: 510 gives Average: 255 but Average reset to: 500 --- Setting delay of: 750
Total: 659 gives Average: 219 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 140 gives Average: 140 but Average reset to: 500 --- Setting delay of: 750
Total: 299 gives Average: 149 but Average reset to: 500 --- Setting delay of: 750
Total: 539 gives Average: 179 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 189 gives Average: 189 but Average reset to: 500 --- Setting delay of: 750
Total: 339 gives Average: 169 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 249 gives Average: 249 but Average reset to: 500 --- Setting delay of: 750
Total: 509 gives Average: 254 but Average reset to: 500 --- Setting delay of: 750
Total: 749 gives Average: 249 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 249 gives Average: 249 but Average reset to: 500 --- Setting delay of: 750
Total: 459 gives Average: 229 but Average reset to: 500 --- Setting delay of: 750
Total: 728 gives Average: 242 but Average reset to: 500 --- Setting delay of: 750
Total: 908 gives Average: 227 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 190 gives Average: 190 but Average reset to: 500 --- Setting delay of: 750
Total: 379 gives Average: 189 but Average reset to: 500 --- Setting delay of: 750
Total: 539 gives Average: 179 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 220 gives Average: 220 but Average reset to: 500 --- Setting delay of: 750
Total: 430 gives Average: 215 but Average reset to: 500 --- Setting delay of: 750
Total: 650 gives Average: 216 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 230 gives Average: 230 but Average reset to: 500 --- Setting delay of: 750
Total: 480 gives Average: 240 but Average reset to: 500 --- Setting delay of: 750
Total: 690 gives Average: 230 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 280 gives Average: 280 but Average reset to: 500 --- Setting delay of: 750
Total: 539 gives Average: 269 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
 --- Setting delay of: 15000
Total: 200 gives Average: 200 but Average reset to: 500 --- Setting delay of: 750
Total: 349 gives Average: 174 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 130 gives Average: 130 but Average reset to: 500 --- Setting delay of: 750
Total: 340 gives Average: 170 but Average reset to: 500 --- Setting delay of: 750
Total: 500 gives Average: 166 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 200 gives Average: 200 but Average reset to: 500 --- Setting delay of: 750
Total: 399 gives Average: 199 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 356 gives Average: 356 but Average reset to: 500 --- Setting delay of: 750
Total: 775 gives Average: 387 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 181 gives Average: 181 but Average reset to: 500 --- Setting delay of: 750
Total: 422 gives Average: 211 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 139 gives Average: 139 but Average reset to: 500 --- Setting delay of: 750
Total: 360 gives Average: 180 but Average reset to: 500 --- Setting delay of: 750
Total: 570 gives Average: 190 but Average reset to: 500 --- Setting delay of: 750

 --- Setting delay of: 15000
Total: 180 gives Average: 180 --- Setting delay of: 270
Total: 310 gives Average: 155 --- Setting delay of: 232.5

 --- Setting delay of: 15000
Total: 200 gives Average: 200 --- Setting delay of: 300
Total: 350 gives Average: 175 --- Setting delay of: 262.5
Total: 590 gives Average: 196 --- Setting delay of: 294

 --- Setting delay of: 15000
Total: 189 gives Average: 189 --- Setting delay of: 283.5
Total: 339 gives Average: 169 --- Setting delay of: 253.5
Total: 589 gives Average: 196 --- Setting delay of: 294
Total: 779 gives Average: 194 --- Setting delay of: 291

 --- Setting delay of: 15000
Total: 209 gives Average: 209 --- Setting delay of: 313.5
Total: 429 gives Average: 214 --- Setting delay of: 321
Total: 558 gives Average: 186 --- Setting delay of: 279
Total: 761 gives Average: 190 --- Setting delay of: 285

 --- Setting delay of: 15000
Total: 160 gives Average: 160 --- Setting delay of: 240
Total: 349 gives Average: 174 --- Setting delay of: 261

 --- Setting delay of: 15000
Total: 160 gives Average: 160 --- Setting delay of: 240
Total: 329 gives Average: 164 --- Setting delay of: 246

 --- Setting delay of: 15000
Total: 300 gives Average: 300 --- Setting delay of: 450

 --- Setting delay of: 15000
Total: 130 gives Average: 130 --- Setting delay of: 195

 --- Setting delay of: 15000
Total: 180 gives Average: 180 --- Setting delay of: 270
Total: 369 gives Average: 184 --- Setting delay of: 276

 --- Setting delay of: 15000
Total: 260 gives Average: 260 --- Setting delay of: 390
Total: 533 gives Average: 266 --- Setting delay of: 399

 --- Setting delay of: 15000
Total: 190 gives Average: 190 --- Setting delay of: 285
Link to comment
Share on other sites

  • Moderators

czardas,

Sorry for hijacking your thread M23

Not a problem - the more the merrier! :)

I posted these scripts in the "Developer Chat" section in the hope of sparking some debate and I am delighted that it has. It makes a change from explaining something simple for the umpteenth time in the "General Help" forum! ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

czardas,

Not a problem - the more the merrier! :)

I posted these scripts in the "Developer Chat" section in the hope of sparking some debate and I am delighted that it has. It makes a change from explaining something simple for the umpteenth time in the "General Help" forum! ;)

M23

Ah okay. Here's a little more then ;) =>

Since trying out a few things myself, the following thought came to my mind: How to create a general delay trigger that could be used in conjunction with other functions. The idea would be to set a flag when a function exits without error. This flag would then trigger a delayed function call responce unless overridden in the interim period. I'm not exactly sure how it would work or be implemented. Perhaps the concept of a general trigger seems a little ambitious, but I'm still toying with the idea.

Link to comment
Share on other sites

I like the search-as-you-type system I wrote for CodecControl. Interruptable, fast, easy.

Here's a exaggerated standalone example:

#include <GuiListView.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>

Opt("GUIOnEventMode", 1)

Global $sDisableSearch = "ABC", $sShowList = $sDisableSearch

Global $aiRandomStuff[1000 * 1000] ;One freaking million!!

For $iX = 0 To UBound($aiRandomStuff) -1
    For $iY = 0 To Random(1, 4)
        $aiRandomStuff[$iX] &= Random(0, 9, 1)
    Next
Next

$hGUI = GUICreate(StringTrimRight(@ScriptName, 3), 480, 640, 0, 0)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Quit")

$cIdInput = GUICtrlCreateInput('Live search', 0, 0, 480, 30)

$hListview = _GUICtrlListView_Create($hGUI, "", 0, 30, 480, 610, BitOR($LVS_REPORT, $LVS_SINGLESEL, $LVS_SHOWSELALWAYS))
_GUICtrlListView_SetExtendedListViewStyle($hListview, $LVS_EX_FULLROWSELECT)
_GUICtrlListView_AddColumn($hListview, "Random number", 250)

For $iX = 0 To UBound($aiRandomStuff) -1
    _GUICtrlListView_AddItem($hListview, $aiRandomStuff[$iX])
Next

GUISetState()
GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

While True
    Sleep(10)
    If $sShowList <> $sDisableSearch Then _ListviewFilter($sShowList)
WEnd

Func _ListviewFilter($sCurrent)
    Local $iTimer = TimerInit()

    _GUICtrlListView_DeleteAllItems($hListview)

    For $iX = 0 To UBound($aiRandomStuff) -1
        If $sCurrent <> $sShowList Then Return ConsoleWrite("Interrupted filtering process" & @CRLF)

        If $sCurrent <> "" And StringInStr($aiRandomStuff[$iX], $sCurrent, 0) = 0 Then ContinueLoop

        _GUICtrlListView_AddItem($hListview, $aiRandomStuff[$iX])
    Next
    $sShowList = $sDisableSearch

    ConsoleWrite("Filtering took " & Round(TimerDiff($iTimer)) & " ms" & @CRLF)
EndFunc

Func _WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg, $lParam
    Local $cId

    $cId = BitAND($wParam, 0xFFFF)   ;ControlId

    Switch BitShift($wParam, 16)   ;"Notification code"
        Case $EN_CHANGE
            If $cId = $cIdInput Then
                $sShowList = GUICtrlRead($cId)
            EndIf
    EndSwitch
EndFunc

Func _Quit()
    Exit
EndFunc

(lower the 1 million if you don't have 4 minutes to wait)

There was originally a wait (AdlibRegister) for the user to "finish" writing, but that was removed as the 1-200 items CodecControl handles is too little to care about.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...