Page 1 of 1

Wait for input

Posted: Mon Jul 12, 2021 9:53 am
by CoopsOz
Hi all,

I'm looking for a way to pause a program and monitor the keyboard or mouse.

The program I have kludged up allows me to select a directory of images and display the Landscape pictures on my 2560 x 1440 display, and the Portrait pictures on my second 1440 x 2560 display.
The only way I can find to pause the execution is using MessageRequester, which appears in the middle of the display- on top of the image.

I'm hoping that the experienced PB people can assist me, as I haven't written programs since my Apple ][ days.

I'd prefer as OS agnostic solution, as I'd like to run it on my Mac or my PC.

Thanks in advance.

Code: Select all

Declare loopdiraf(path.s)

UseJPEGImageDecoder()
UseTGAImageDecoder()
UsePNGImageDecoder()
UseTIFFImageDecoder()
UseGIFImageDecoder()
Monitor0Width.i=1440
Monitor0Height.i=2560
Monitor1Width.i=2560
Monitor1Height.i=1440
MonitorPad = 0

Procedure MoveWindowToDesktop(Window.i, Desktop.i, x.i, y.i, Flags.i=0)
  
  If IsWindow(Window)
  
    If ExamineDesktops() > Desktop
      
      If Flags = #PB_Window_ScreenCentered
        x = (DesktopWidth(Desktop) - WindowWidth(Window)) / 2
        y = (DesktopHeight(Desktop) - WindowHeight(Window)) / 2
      EndIf
      
      ResizeWindow(Window, DesktopX(Desktop) + x, DesktopY(Desktop) + y, #PB_Ignore, #PB_Ignore)
      
    EndIf
    EndIf

  
EndProcedure
 
InitPath$ = "minim1"   ; here change to your Root Lan machine name
  Path$ = PathRequester("Choose a directory", InitPath$)
  If Path$
    ;MessageRequester("Information", "You choose  :"+Chr(10)+Path$, 0)
  Else
    MessageRequester("Information", "Canceled.", 0)
  EndIf
  Global Directory$ = Path$  
; MAINPROGRAM
;=================
  Global  n
  MaxPix = 150
  Global Dim FileNames$(MaxPix)
loopdiraf(Directory$)

SortArray(FileNames$(),#PB_Sort_Ascending )

For n=0 To MaxPix
  If FileNames$(n) <> ""
    
    LoadImage(0, FileNames$(n))
    imgW.f = ImageWidth(0)
    imgH.f = ImageHeight(0)
    imagsize$= "W "+StrF(imgW) + " H "+ StrF(imgH)
    
  If imgW > imgH
    ;LANDSCAPE
    INewWidth.f = imgW / (imgH/Monitor1Height )
    INewHeight.f = Monitor1Height
    ResizeImage(0, INewWidth, INewHeight)
    Result$ = StrF(INewWidth)+" "+StrF(INewHeight)
    OpenWindow(0, 0, 0, INewWidth, INewHeight, Result$,  #PB_Window_BorderLess )
    MoveWindowToDesktop(0, 1, 0, 0)    
    ImageGadget(#PB_Any,   0,    0,  INewWidth, INewWidth, ImageID(0), #PB_Window_BorderLess ) 
    
  Else
    ;PORTRAIT
    
    INewWidth.f = Monitor0Width
    INewHeight.f = (ImgH- MonitorPad) / (imgW/Monitor0Width) 
    ResizeImage(0, INewWidth, INewHeight)
    Result$ = StrF(INewWidth)+" "+StrF(INewHeight)
    OpenWindow(0, 0, 0, INewWidth, INewHeight, Result$,  #PB_Window_BorderLess )
    MoveWindowToDesktop(0, 0, 0, 0)
    ImageGadget(#PB_Any,   0,    0, INewWidth, INewHeight, ImageID(0), #PB_Window_BorderLess ) 
  EndIf
  ;
  Result = MessageRequester("Title", "Please make your input:", #PB_MessageRequester_YesNo)
  a$ = "Result of the requester was: "
  If Result = #PB_MessageRequester_Yes    ; pressed Yes button
    a$ + "Yes"
  Else                                    ; pressed No button
    a$ + "No"
    End
   
  EndIf
 
EndIf
    
Next

End

Procedure loopdiraf(path.s)   ; this must be a recursive routine
  
  Define.i Id

  Id = ExamineDirectory(#PB_Any, path, "*.*")
  n=0
  If Id
    While NextDirectoryEntry(Id)
    
      If DirectoryEntryName(Id) = "."  : Continue : EndIf
      If DirectoryEntryName(Id) = ".." : Continue : EndIf
      
      If DirectoryEntryType(Id) = #PB_DirectoryEntry_File
       
        ;Type$ = " [File] "
        ;Debug path + "\" + DirectoryEntryName(Id) + Type$ + "   " + Str(DirectoryEntrySize(Id))
      ;Else
       ; Type$ = " [Sub-Dir] "
        ;Debug path + "\" + DirectoryEntryName(Id) + Type$ +Str(n)
        ;FileNames$(n)= path + "/" + DirectoryEntryName(Id) ; extra /  ...?
        FileNames$(n)= path + DirectoryEntryName(Id)
        ; Debug FileNames$(n)
        ; loopdiNextaf(path + "\" + DirectoryEntryName(Id))
        n  =n + 1
      EndIf
     
    Wend
    FinishDirectory(Id)
  EndIf

EndProcedure

Re: Wait for input

Posted: Mon Jul 12, 2021 3:30 pm
by infratec
Since no one answered:

Code: Select all

For n=0 To MaxPix
  If FileNames$(n) <> ""
    
    LoadImage(0, FileNames$(n))
    imgW.f = ImageWidth(0)
    imgH.f = ImageHeight(0)
    imagsize$= "W "+StrF(imgW) + " H "+ StrF(imgH)
    
    If imgW > imgH
      ;LANDSCAPE
      INewWidth.f = imgW / (imgH/Monitor1Height )
      INewHeight.f = Monitor1Height
      ResizeImage(0, INewWidth, INewHeight)
      Result$ = StrF(INewWidth)+" "+StrF(INewHeight)
      OpenWindow(0, 0, 0, INewWidth, INewHeight, Result$,  #PB_Window_BorderLess )
      MoveWindowToDesktop(0, 1, 0, 0)    
      ImageGadget(#PB_Any,   0,    0,  INewWidth, INewWidth, ImageID(0), #PB_Window_BorderLess ) 
      
    Else
      ;PORTRAIT
      
      INewWidth.f = Monitor0Width
      INewHeight.f = (ImgH- MonitorPad) / (imgW/Monitor0Width) 
      ResizeImage(0, INewWidth, INewHeight)
      Result$ = StrF(INewWidth)+" "+StrF(INewHeight)
      OpenWindow(0, 0, 0, INewWidth, INewHeight, Result$,  #PB_Window_BorderLess )
      MoveWindowToDesktop(0, 0, 0, 0)
      ImageGadget(#PB_Any,   0,    0, INewWidth, INewHeight, ImageID(0), #PB_Window_BorderLess ) 
    EndIf
    ;
    AddKeyboardShortcut(0, #PB_Shortcut_Escape, 1)
    
    Exit = #False
    Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_Menu
        If EventMenu() = 1
          Exit = #True
        EndIf
      EndIf
    Until Exit
    
    RemoveKeyboardShortcut(0, #PB_Shortcut_Escape)
    
    CloseWindow(0)
    
  EndIf
  
Next
Should work, but not tested.

Re: Wait for input

Posted: Mon Jul 12, 2021 11:39 pm
by eck49
Hi CoopsOz

1. Welcome. Just some general points to supplement what infratec has contributed.

2. I would encourage using

Code: Select all

EnableExplicit
to catch typos and force variables to be defined.

3. Personally, I prefer window/gadget identifying numbers to stand out, so I use variables or explicit constants (eg #WinMain, #Gad_Str) for them. It helps to distinguish windows and gadgets from 0s, 1s etc which are just numbers. Very much personal taste!

4. The usual approach to retain the opened window on the screen while you wait for some user action seems to be

Code: Select all

Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow

5. Instead of MessageRequester, did you think of creating your own second window which you can put anywhere you like and any size you like?

6. Look at BindEvent to capture Mouse and Keyboard events immediately as an alternative to catching them in the Repeat loop of my point 4. Indeed this may be what you are looking for to solve your problem. There is usually more than one way of tackling an issue.

I don't count myself as 'experienced' but am picking things up slowly, very slowly.

I hope this is helpful.

Re: Wait for input

Posted: Mon Jul 12, 2021 11:58 pm
by CoopsOz
Thanks to both people who responded, I will test and advise.

Re: Wait for input

Posted: Wed Jul 14, 2021 2:24 am
by CoopsOz
Many thanks infratec, that set me on the right path. As I needed to have an option to exit the program I ended up with the following code. It took a few tries to avoid end condition errors as I didn't twig that there are nested Selects, so that 2 EndSelects are needed.
Case seemed the best option, as my attempts to add another If statement were beset with many end condition errors.

Thanks again

Code: Select all

  AddKeyboardShortcut(0, #PB_Shortcut_Space, 1)
  AddKeyboardShortcut(0, #PB_Shortcut_Escape, 2) 
  Exit = #False
  Endit = #False
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            Exit = #True
          Case 2
            Exit = #True
            Endit = #True
        EndSelect      
        
    EndSelect
  Until Exit = #True
  
EndIf