Page 1 of 1

Canvas keydown

Posted: Wed Jul 13, 2011 6:06 pm
by Polo
Hello,

The CanvasGadget won't return the correct character after a keydown, only the key pushed - which is useless imho.
we've got a workaround on windows to return the character, and I'm building one for MacOS.
The code below does what I want (i.e. it accepts capital letters), but doesn't take all characters.
For instance "é" returns -114.
changing to unsigned word in the callback won't return the correct character.

Anybody has an idea?

Code: Select all

ImportC ""
      NewControlUserPaneKeyDownUPP.l(*userRoutine)
      SetControlData ( ControlRef.l, ControlPartCode.l, inTagName.l, inSize.l,*inData)
EndImport

    #kControlEntireControl = 0
    #kControlUserPaneKeyDownProcTag = 1801812324

    ProcedureC MacCanvasCallback(ControlRef.l, key.w, char.w, modifiers.w)
      MessageRequester("",Str(key)+" "+Str(char)+" "+Str(modifiers))
    EndProcedure

    canvascallback.i = NewControlUserPaneKeyDownUPP(@MacCanvasCallback())
    SetControlData(GadgetID(canvas), #kControlEntireControl,#kControlUserPaneKeyDownProcTag,SizeOf(Integer),@canvascallback)

Thanks!
Gaetan

Re: Canvas keydown

Posted: Wed Jul 13, 2011 8:44 pm
by TomS
The character is never returned. Only the key.
This is always the case.
é = 221 + 69
Since ´ is a "dead key" (must always be followed by another key) this is not a problem.

Code: Select all

If OpenWindow(0, 0, 0, 220, 220, "CanvasGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	
	StringGadget(2, 10, 190, 200, 20, "StringGadget")	
	CanvasGadget(1, 10, 10, 200, 170, #PB_Canvas_Keyboard)
	
	
	Repeat
		Event = WaitWindowEvent()
		
		Select Event
			Case #PB_Event_Gadget 
				If EventGadget() = 1 
					If EventType()=#PB_EventType_KeyDown
						
						Select GetGadgetAttribute(1,#PB_Canvas_Key ) 
							Case 221
								apostrophe_right = 1
								
							Case 69	;#PB_Shortcut_E		
								
								If apostrophe_right = 1
									StartDrawing(CanvasOutput(1))
									Box(0,0,200,170,$FFFFFF)
									DrawText(5, 5, "é", 0, $FFFFFF)
									StopDrawing()
									apostrophe_right = 0
								Else 
									StartDrawing(CanvasOutput(1))
									Box(0,0,200,170,$FFFFFF)
									DrawText(5, 5, "e", 0, $FFFFFF)
									StopDrawing()
									apostrophe_right = 0
								EndIf 
								
						EndSelect 
						
						
					EndIf 
				EndIf 
				
				
				
		EndSelect 
		
	Until Event = #PB_Event_CloseWindow
EndIf 

Re: Canvas keydown

Posted: Wed Jul 13, 2011 11:42 pm
by Polo
On a french keyboard, "é" is on the key "2" for instance.
And as you can see in my example, the callback does return the key and the character - only it doesn't work for accents, unfortunately, unlike the workaround with the Windows callback.

Re: Canvas keydown

Posted: Thu Jul 14, 2011 12:15 pm
by TomS
I see.
So on your keyboard my code doesn't work at all.

I can't get your code to work
---------------------------
PureBasic - Linker error
---------------------------
POLINK: error: Unresolved external symbol '_NewControlUserPaneKeyDownUPP'.

POLINK: error: Unresolved external symbol '_SetControlData'.

POLINK: fatal error: 2 unresolved external(s).


---------------------------
OK
---------------------------

Code: Select all

ImportC ""
	NewControlUserPaneKeyDownUPP.l(*userRoutine)
	SetControlData ( ControlRef.l, ControlPartCode.l, inTagName.l, inSize.l,*inData)
EndImport

#kControlEntireControl = 0
#kControlUserPaneKeyDownProcTag = 1801812324

ProcedureC MacCanvasCallback(ControlRef.l, key.w, char.w, modifiers.w)
	MessageRequester("",Str(key)+" "+Str(char)+" "+Str(modifiers))
EndProcedure


canvascallback.i = NewControlUserPaneKeyDownUPP(@MacCanvasCallback())


hWnd = OpenWindow(#PB_Any, 0, 0, 400, 400, "Fenster", #PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
CanvasGadget(0,0,0,400,400,#PB_Canvas_Keyboard)


SetControlData(GadgetID(0), #kControlEntireControl,#kControlUserPaneKeyDownProcTag,SizeOf(Integer),@canvascallback)

Repeat
	event = WaitWindowEvent(20)
	
Until event = #PB_Event_CloseWindow
End

Re: Canvas keydown

Posted: Thu Jul 14, 2011 3:31 pm
by Polo
Doesn't work on MacOS, right?

Try :

Code: Select all

    ImportC "/System/Library/Frameworks/Carbon.framework/Carbon"

Re: Canvas keydown

Posted: Thu Jul 14, 2011 3:55 pm
by TomS
No. Windows 7, 32bit
PB 4.6 b3

Re: Canvas keydown

Posted: Thu Jul 14, 2011 4:04 pm
by STARGÅTE
i use this for get the right character:

Code: Select all

OpenWindow(0, 0, 0, 400, 300, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)

#PB_Event_Character = #WM_CHAR

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			End
		Case #PB_Event_Character
			Debug Chr(EventwParam())
	EndSelect
ForEver

Re: Canvas keydown

Posted: Thu Jul 14, 2011 4:16 pm
by TomS
Awesome, Stargate.

Re: Canvas keydown

Posted: Thu Jul 14, 2011 9:01 pm
by Polo
Great, though my problem is on MacOS only ;)

Re: Canvas keydown

Posted: Fri Jul 15, 2011 6:30 pm
by Shardik
Polo wrote:Hello,

The CanvasGadget won't return the correct character after a keydown, only the key pushed - which is useless imho.
we've got a workaround on windows to return the character, and I'm building one for MacOS.
The code below does what I want (i.e. it accepts capital letters), but doesn't take all characters.
For instance "é" returns -114.
changing to unsigned word in the callback won't return the correct character.

Anybody has an idea?
I have taken TomS' code example and replaced the MacCanvasCallback with this code:

Code: Select all

ProcedureC MacCanvasCallback(ControlRef.l, key.w, char.w, modifiers.w)
  If char & $FF00
    Select char & $FF
      Case $8E
        Debug "é"
      Case $8F
        Debug "è"
      Case $90
        Debug "ê"
    EndSelect
  Else
    Debug Chr(char)
  EndIf
EndProcedure
On my German Mac keyboard the character "é" is displayed without problems.
You simply have to test whether the first byte of the word in char is $FF and in that
case you have to evaluate the second byte and convert it to your wanted character.
Probably my example won't work for you directly on your French keyboard and
you have to find out the correct value of the second byte to translate it to é... :wink:

Re: Canvas keydown

Posted: Fri Jul 15, 2011 11:01 pm
by Polo
Thanks Shardik!
Strange Mac doesn't return the correct characters though, there are many more that shall not work correctly (ù, ç, à, ë, ï, ...) :cry:

Re: Canvas keydown

Posted: Fri Jul 15, 2011 11:31 pm
by Polo
... and this is not just me on the canvas gadget, when i type on the key "^" on my french keyboard, it displays "NUL" in PB IDE - and displays "NUL ê" if i type "^" and then "e".
Weird :)

Re: Canvas keydown

Posted: Mon Jul 18, 2011 8:31 pm
by Shardik
Polo wrote:... and this is not just me on the canvas gadget, when i type on the key "^" on my french keyboard, it displays "NUL" in PB IDE - and displays "NUL ê" if i type "^" and then "e".
Weird :)
If I examine the character code generated for pressing the dead key
accent aigu in a CanvasGadget on my German Mac keyboard, I obtain
the value $00. The PB IDE doesn't catch that dead key and incorrectly
displays NUL before correctly displaying the character é... :wink:

But please try the following example without any API calls. It displays
the following special language characters without any problems on a
German Mac keyboard (although it doesn't work without OS specific
adaptions on Windows or Linux and I doubt that it will work on your
French keyboard without modifications but it might well give you the
idea for a possible alternative solution):

Image

Code: Select all

OpenWindow(0, 100, 100, 400, 100, "Display pressed key")

CanvasGadget(0, 3, 3, WindowWidth(0) - 6, WindowHeight(0) - 46, #PB_Canvas_Keyboard | #PB_Canvas_DrawFocus)
TextGadget(1, 2, WindowHeight(0) - 40, WindowWidth(0) - 4, 38, "", #PB_Text_Border | #PB_Text_Center)
SetGadgetFont(1, LoadFont(0, "Arial", 32))
SetActiveGadget(0)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventType() = #PB_EventType_KeyDown
        ShiftKey = 0
        
        If GetGadgetAttribute(0, #PB_Canvas_Modifiers) & #PB_Canvas_Shift
          ShiftKey = $20
        EndIf
        
        CharCode = GetGadgetAttribute(0, #PB_Canvas_Key)
        
        If CharCode = 0
          If ShiftKey = 0
            AccentGrave = #False
          Else
            AccentGrave = #True
          EndIf
        EndIf
        
        If FindString("Éé", Chr(CharCode))
          If AccentGrave
            CharCode - 1
          EndIf
        EndIf

        If CharCode <> 0
          InputString$ + Chr(CharCode ! ShiftKey)
          SetGadgetText(1, InputString$)
        EndIf
      EndIf
  EndSelect
ForEver

Re: Canvas keydown

Posted: Mon Jul 18, 2011 11:26 pm
by Polo
With your code I get some of the accentued characters (éèçàùê) and some not (ëä...) but cannot get the numbers working then (on a french keyboard you get a number by pressing shift plus the number key).
Unfortunately this workaround won't work on all keyboards :cry: