Sans ExamineMouse() ni ExamineKeyboard() qui plantent selon les OS.
Contient l'interface semblable à celle pour OpenGLGadget(), donc accès multi-écran, multi-fenêtres.
Merci à Christophe d'avoir eu l'idée : ne pas hésiter à apporter un retour si petite config pour optimisation.
Code : Tout sélectionner
;****************************************************************************************************************************************************************************************************************
Structure WinScrDims
realW.I ; Largeur (zone réelle)
realH.I ; Hauteur
ViewX.I ; X (Coordonnées de la visu dans l'écran)
ViewY.I ; Y
ViewW.I ; Largeur
ViewH.I ; Hauteur
OffsetX.I ; X (Coordonnées de la visu dans la zone réelle)
OffsetY.I ; Y
OffMaxX.I
OffMaxY.I
OffX.I
OffY.I
hScale.D
vScale.D
Partial.I ; Drapeau d'états partiels des dimensions. Bit 0 = état partiel horizontal. Bit 1 = état partiel vertical.
BarThickness.I ; Epaisseur des bordures de scrolling
hSlideX.I
hSlideY.I
hSlideW.I ; Largeur de la zone de glissement de la barre horizontale de scrolling
hSlideH.I
vSlideX.I
vSlideY.I
vSlideH.I ; Hauteur de la zone de glissement de la barre verticale de scrolling
vSlideW.I
hBarX.I
hBarY.I
hBarW.I ; Largeur de la barre horizontale de scrolling
hBarH.I
vBarX.I
vBarY.I
vBarW.I
vBarH.I ; Hauteur de la barre verticale de scrolling
EndStructure
Structure WinScr
SubSys.I ; Handle sous-système
Win.I ; Numéro de fenêtre de visu
WinFlags.I ; Configuration de la fenêtre de visu
Img.I ; Numéro d'image de visu
Ggt.I ; Numéro de gadget (ImageGadget) de visu
Scr.I ; Numéro/handle d'écran / de visu
cWin.I ; Numéro de fenêtre (canvas)
cGgt.I ; Numéro de gadget (canvas)
inKey.S ; Touche clavier (local)
inText.S ; Texte clavier
Array CharKey.I(255) ; Tableau des appuis direct de touche
Ev.I ; Evènement GUI OS
EvWin.I ; Fenêtre concernée par un évènement
EvType.I ; Type d'évènement
msBts.I ; Etat des boutons de la souris
msWheelD.I ; Etat de l'évolution de la molette de la souris
msWheel.I ; Etat de la molette de la souris
msDeskX.I ; X (coordonnées de la souris dans le bureau)
msDeskY.I ; Y
msOn.I ; Etat de présence de la souris au-dessus de la visu
msOn0.I ; Ancien état de présence de la souris au-dessus de la visu
msOnExtra.I ; Etat des boutons de la souris quand celle-ci a quitté la visu malgré le maintien appuyé
msX.I ; X (coordonnées de la souris dans la vue graphique
msY.I ; Y
msDrag.I
msDragX.I
msDragY.I
Array LineSp.I(7) ; N° des sprites pour le tracé des lignes (8 couleurs)
Dims.WinScrDims
EndStructure
Declare WinScrDims(*WS.WinScr)
Procedure Extrema(*a.Integer, min, max)
If *a\I < Min
*a\I = Min
EndIf
If *a\I > Max
*a\I = Max
EndIf
;
EndProcedure
Procedure WinScrOpen(WinX.I = 100, WinY.I = 100, WinW.I = 400, WinH.I = 300, WinT.S = "", WinF.I = 0)
Define *WS.WinScr = AllocateStructure(WinScr)
*WS\SubSys = InitSprite()
*WS\WinFlags = WinF
*WS\WinFlags | #PB_Window_SystemMenu
*WS\WinFlags | #PB_Window_SizeGadget
*WS\WinFlags | #PB_Window_MaximizeGadget
*WS\WinFlags | #PB_Window_MinimizeGadget
*WS\Win = OpenWindow(#PB_Any, WinX, WinY, WinW, WinH, WinT, *WS\WinFlags)
ExamineDesktops()
*WS\Dims\RealW = DesktopWidth(0)
*WS\Dims\RealH = DesktopHeight(0)
*WS\Img = CreateImage(#PB_Any, *WS\Dims\RealW, *WS\Dims\RealH, DesktopDepth(0), RGBA(0, 0, 0, 0) )
*WS\Ggt = ImageGadget(#PB_Any, 0, 0, 1, 1, ImageID(*WS\Img) )
*WS\Scr = OpenWindowedScreen(GadgetID(*WS\Ggt), 0, 0, *WS\Dims\RealW, *WS\Dims\RealH)
StickyWindow(*WS\Win, #True)
*WS\cWin = OpenWindow(#PB_Any, 0, 0, 1, 1, "", #PB_Window_BorderLess, WindowID(*WS\Win) )
*WS\cGgt = CanvasGadget(#PB_Any, 0, 0, 1, 1, #PB_Canvas_Keyboard)
StickyWindow(*WS\cWin, #True)
*WS\Dims\BarThickness = 24
ProcedureReturn *WS
EndProcedure
Procedure In(x0, y0, x, y, w, h)
If x0 => x
If y0 => y
If x0 < x + w
If y0 < y + h
ProcedureReturn 1
EndIf
EndIf
EndIf
EndIf
EndProcedure
Procedure WinScrGetEvent(*WS.WinScr)
Repeat
*WS\Ev = WindowEvent()
*WS\EvWin = EventWindow()
*WS\EvType = 0
Select *WS\EvWin
Case *WS\Win
Select *WS\Ev
Case #PB_Event_CloseWindow
End
Case #PB_Event_SizeWindow, #PB_Event_MoveWindow, #PB_Event_Repaint
*WS\Dims\ViewX = WindowX(*WS\Win, #PB_Window_InnerCoordinate)
*WS\Dims\ViewY = WindowY(*WS\Win, #PB_Window_InnerCoordinate)
*WS\Dims\ViewW = WindowWidth(*WS\Win)
*WS\Dims\ViewH = WindowHeight(*WS\Win)
WinScrDims(*WS)
Extrema(@*WS\Dims\OffsetX, 0, *WS\Dims\OffMaxX)
Extrema(@*WS\Dims\OffsetY, 0, *WS\Dims\OffMaxY)
EndSelect
Case *WS\cWin
Select *WS\Ev
Case #PB_Event_Gadget
*WS\EvType = EventType()
*WS\msBts = GetGadgetAttribute(*WS\cGgt, #PB_Canvas_Buttons)
*WS\msWheelD = GetGadgetAttribute(*WS\cGgt, #PB_Canvas_WheelDelta)
Select *WS\EvType
Case #PB_EventType_MouseWheel
*WS\msWheel + *WS\msWheelD
Case #PB_EventType_Input
*WS\inKey = Chr(GetGadgetAttribute(*WS\cGgt, #PB_Canvas_Input) )
*WS\inText + *WS\inKey
Case #PB_EventType_KeyDown
*WS\CharKey(GetGadgetAttribute(*WS\cGgt, #PB_Canvas_Key) ) = 1
Case #PB_EventType_KeyUp
*WS\CharKey(GetGadgetAttribute(*WS\cGgt, #PB_Canvas_Key) ) = 0
EndSelect
EndSelect
EndSelect
Until *WS\Ev = 0
*WS\msDeskX = DesktopMouseX()
*WS\msDeskY = DesktopMouseY()
*WS\msOn0 = *WS\msOn
*WS\msOn = 0
If *WS\msDeskX => *WS\Dims\ViewX
If *WS\msDeskY => *WS\Dims\ViewY
If *WS\msDeskX < *WS\Dims\ViewX + *WS\Dims\ViewW
If *WS\msDeskY < *WS\Dims\ViewY + *WS\Dims\ViewH
*WS\msOn = 1
EndIf
EndIf
EndIf
EndIf
If (*WS\msOn And Not *WS\msOn0) Or (*WS\msOn And (GetActiveWindow() <> *WS\cWin) )
HideWindow(*WS\cWin, #False)
SetActiveGadget(*WS\cGgt)
EndIf
If Not *WS\msOn And *WS\msOn0
If *WS\msBts
*WS\msOnExtra = *WS\msBts
Else
HideWindow(*WS\cWin, #True)
EndIf
EndIf
If *WS\msOn Or *WS\msOnExtra
ResizeWindow(*WS\cWin, *WS\msDeskX, *WS\msDeskY, #PB_Ignore, #PB_Ignore)
EndIf
*WS\msX = *WS\msDeskX - *WS\Dims\ViewX
*WS\msY = *WS\msDeskY - *WS\Dims\ViewY
If *WS\msBts = 0 And *WS\msOn = 0
*WS\msOnExtra = 0
HideWindow(*WS\cWin, #True)
EndIf
EndProcedure
Structure Graphic
*WS
Array CharFont.I(80)
Array CharS.I(80, 255)
Array CharW.I(80, 255)
Array CharH.I(80, 255)
MouseImage.I
MouseSprite.I
EndStructure
Procedure GraphicCreate(*WS)
Define *This.Graphic = AllocateMemory(SizeOf(Graphic) )
InitializeStructure(*This, Graphic)
*This\WS = *WS
ProcedureReturn *This
EndProcedure
Procedure GraphicInitFont(*This.Graphic, FontName.S, SizeList.S)
Define SizeSize = CountString(SizeList, ";")
Dim Size.I(SizeSize)
For K = 0 To SizeSize
Size(K) = Val(StringField(SizeList, 1 + K, ";") )
Next
For K = 0 To SizeSize
J = Size(K)
*This\CharFont(J) = LoadFont(#PB_Any, FontName, J)
Next
StartDrawing(ScreenOutput() )
For K = 0 To SizeSize
J = Size(K)
DrawingFont(FontID(*This\CharFont(J) ) )
For I = 1 To 255
*This\CharW(J, I) = TextWidth(Chr(I) )
If *This\CharW(J, I) = 0
*This\CharW(J, I) = 1
EndIf
*This\CharH(J, I) = TextHeight(Chr(I) )
Next
Next
StopDrawing()
For K = 0 To SizeSize
J = Size(K)
For I = 1 To 255
*This\CharS(J, I) = CreateSprite(#PB_Any, *This\CharW(J, I), *This\CharH(J, I), #PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(*This\CharS(J, I) ) )
DrawingFont(FontID(*This\CharFont(J) ) )
DrawingMode(#PB_2DDrawing_AllChannels)
DrawText(0, 0, Chr(I), RGBA(0, 0, 0, 255), RGBA(255, 255, 255, 0) )
StopDrawing()
Next
Next
EndProcedure
Procedure GraphicDisplay(*This.Graphic, x, y, A$, Size, ColorAlpha, Angle = 0)
Define *WS.WinScr = *This\WS
Alpha = Alpha(ColorAlpha)
Color = RGB(Red(ColorAlpha), Green(ColorAlpha), Blue(ColorAlpha) )
Define AngleRad.F = Angle * #PI / 180.0
If Angle
For I = 1 To Len(A$)
A = Asc(Mid(A$, I, 1) )
If Angle
RotateSprite(*This\CharS(Size, A), Angle, #PB_Absolute)
EndIf
DisplayTransparentSprite(*This\CharS(Size, A), X - *WS\Dims\OffsetX, Y - *WS\Dims\OffsetY, Alpha, Color)
X + (*This\CharW(Size, A) * Cos(AngleRad) )
Y + (*This\CharW(Size, A) * Sin(AngleRad) )
Next
Else
For I = 1 To Len(A$)
A = Asc(Mid(A$, I, 1) )
RotateSprite(*This\CharS(Size, A), 0, #PB_Absolute)
DisplayTransparentSprite(*This\CharS(Size, A), X - *WS\Dims\OffsetX, Y - *WS\Dims\OffsetY, Alpha, Color)
X + *This\CharW(Size, A)
Next
EndIf
EndProcedure
Procedure LineCreate(*WS.WinScr)
For I = 0 To 7
*WS\LineSp(I) = CreateSprite(#PB_Any, 256, 4, #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(*WS\LineSp(I) ) )
DrawingMode(#PB_2DDrawing_AllChannels)
W = OutputWidth()
H = OutputHeight()
Box(0, 0, W, H, RGBA(0, 0, 0, 0) )
BCr = I >> 2 & 1
BCg = I >> 1 & 1
BCb = I & 1
Cr = 255 * BCr
Cg = 255 * BCg
Cb = 255 * BCb
Box(0, 1, W, 2, RGBA(Cr, Cg, Cb, 255) )
StopDrawing()
EndIf
Next
EndProcedure
Procedure LineDisplay(xa.D, ya.D, xb.D, yb.D, SpriteN)
Define.D Ang, x0, y0, x1, y1, x2, y2, x3, y3, dx, dy
Ang = ATan2(xb - xa, yb - ya)
dx = Cos(Ang + #PI / 2.0) * 1.5
dy = Sin(Ang + #PI / 2.0) * 1.5
x0 = xa + dx
y0 = ya + dy
x1 = xb + dx
y1 = yb + dy
x2 = xb - dx
y2 = yb - dy
x3 = xa - dx
y3 = ya - dy
;TransformSprite(SpriteN, x0, y0, x1, y1, x2, y2, x3, y3)
;DisplayTransparentSprite(SpriteN, 0, 0)
TransformSprite(SpriteN, x3, y3, x2, y2, x1, y1, x0, y0)
DisplayTransparentSprite(SpriteN, 0, 0)
EndProcedure
Procedure CliffDisplay(*WS.WinScr, xa.D, ya.D, xb.D, yb.D)
LineDisplay(xa, ya, xb, ya, *WS\LineSp(7) )
LineDisplay(xa, ya, xa, yb, *WS\LineSp(7) )
LineDisplay(xb, ya, xb, yb, *WS\LineSp(0) )
LineDisplay(xa, yb, xb, yb, *WS\LineSp(0) )
EndProcedure
Procedure CliffDisplayWH(*WS.WinScr, x.D, y.D, w.D, h.D)
CliffDisplay(*WS, x, y, x + w - 1, y + h - 1)
EndProcedure
Procedure WinScrDims(*WS.WinScr)
With *WS\Dims
\Partial = 0
If \ViewW < \RealW
\Partial | 1
EndIf
If \ViewH < \RealH
\Partial | 2
EndIf
If \Partial & 1
If \Partial & 2
Thickness = \BarThickness
Else
Thickness = 0
EndIf
\hSlideX = 0
\hSlideY = \ViewH - \BarThickness
\hSlideW = \ViewW - Thickness
\hSlideH = \BarThickness
\hScale = \hSlideW / \RealW
\hBarX = \OffsetX * \hScale
\hBarY = \hSlideY
\hBarW = \ViewW * \hScale
\hBarH = \hSlideH
CliffDisplayWH(*WS, \hBarX, \hBarY, \hBarW, \hBarH)
Else
\hSlideX = 0
\hSlideY = 0
\hSlideH = 0
\hScale = 1.0
EndIf
If \Partial & 2
\vSlideX = \ViewW - \BarThickness
\vSlideY = 0
\vSlideW = \BarThickness
\vSlideH = \ViewH - \hSlideH
\vScale = \vSlideH / \RealH
\vBarX = \vSlideX
\vBarY = \OffsetY * \vScale
\vBarW = \vSlideW
\vBarH = \ViewH * \vScale
CliffDisplayWH(*WS, \vBarX, \vBarY, \vBarW, \vBarH)
Else
\vSlideX = 0
\vSlideY = 0
\vSlideW = 0
\vScale = 1.0
EndIf
\OffMaxX = (\hSlideW - \hBarW) / \hScale
\OffMaxY = (\vSlideH - \vBarH) / \vScale
If \Partial & 3
CliffDisplayWH(*WS, \vSlideX, \hSlideY, \vSlideW, \hSlideH)
EndIf
If In(*WS\MsX, *WS\MsY, \hBarX, \hBarY, \hBarW, \hBarH)
If *WS\msBts & 1
If *WS\msDrag = 0
*WS\msDrag | 1
*WS\msDragX = *WS\msX
*WS\msDragY = *WS\msY
\OffX = \OffsetX
\OffY = \OffsetY
EndIf
EndIf
EndIf
If *WS\msDrag & 1
If (*WS\msBts & 1) = 0
*WS\msDrag = 0
Else
\OffsetX = \OffX + ((*WS\msX - *WS\msDragX) / \hScale)
Extrema(@\OffsetX, 0, \OffMaxX)
EndIf
EndIf
If In(*WS\MsX, *WS\MsY, \vBarX, \vBarY, \vBarW, \vBarH)
If *WS\msBts & 1
If *WS\msDrag = 0
*WS\msDrag | 2
*WS\msDragX = *WS\msX
*WS\msDragY = *WS\msY
\OffX = \OffsetX
\OffY = \OffsetY
EndIf
EndIf
EndIf
If *WS\msDrag & 2
If (*WS\msBts & 1) = 0
*WS\msDrag = 0
Else
\OffsetY = \OffY + ((*WS\msY - *WS\msDragY) / \vScale)
Extrema(@\OffsetY, 0, \OffMaxY)
EndIf
EndIf
EndWith
EndProcedure
CompilerIf #PB_Compiler_IsMainFile ; Exemple
Define *WS.WinScr = WinScrOpen(100, 100, 276, 350)
Define *GR.Graphic = GraphicCreate(*WS)
GraphicInitFont(*GR, "verdana", "12;20")
Size = 8
CreateSprite(1, Size, Size, #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(1) )
W = OutputWidth()
H = OutputHeight()
W2 = W / 2
W4 = W / 4
W8 = W / 8
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, W, H, RGBA(0, 0, 0, 0) )
Box(W4, W4, W4, W4, RGBA(0, 0, 0, 255) )
Box(W4, W2, W4, W4, RGBA(0, 0, 255, 255) )
Box(W2, W4, W4, W4, RGBA(0, 255, 0, 255) )
Box(W2, W2, W4, W4, RGBA(0, 255, 255, 255) )
StopDrawing()
EndIf
Size = 8
CreateSprite(2, Size, Size, #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(2) )
W = OutputWidth()
H = OutputHeight()
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, W, H, RGBA(0, 0, 0, 0) )
Box(W4, W4, W4, W2, RGBA(0, 0, 0, 255) )
Box(W2, W4, W4, W2, RGBA(0, 0, 0, 255) )
StopDrawing()
EndIf
Size = 8
CreateSprite(3, Size, Size, #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(3) )
W = OutputWidth()
H = OutputHeight()
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, W, H, RGBA(0, 0, 0, 0) )
Box(W4, W4, W4, W2, RGBA(0, 0, 0, 0) )
Box(W2, W4, W4, W2, RGBA(255, 0, 0, 255) )
StopDrawing()
EndIf
Size = 8
CreateSprite(4, Size, Size, #PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(4) )
W = OutputWidth()
H = OutputHeight()
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0, 0, W, H, RGBA(255, 255, 255, 255) )
StopDrawing()
EndIf
LineCreate(*WS)
Repeat
WinScrGetEvent(*WS)
ClearScreen(RGB(0, 0, 0) )
SpriteQuality(#PB_Sprite_NoFiltering)
ClipSprite(1, W2-1, W2-1, 2, 2)
x = *WS\Dims\RealW
y = *WS\Dims\RealH
TransformSprite(1, 0 - *WS\Dims\OffsetX, 0 - *WS\Dims\OffsetY, x - *WS\Dims\OffsetX, 0 - *WS\Dims\OffsetY, x - *WS\Dims\OffsetX, y - *WS\Dims\OffsetY, 0 - *WS\Dims\OffsetX, y - *WS\Dims\OffsetY)
SpriteQuality(#PB_Sprite_BilinearFiltering)
DisplaySprite(1, 0, 0)
GraphicDisplay(*GR, 0, 0, "Théorème multi-plateforme de la Gougoutte de... Canvas", 20, RGBA(63, 127, 255, 255) )
If *WS\msOn Or *WS\msOnExtra
c = RGBA(255, 159, 255, 255)
Else
c = RGBA(63, 91, 191, 255)
EndIf
GraphicDisplay(*GR, 0, 64, "Texte = «" + *WS\inText + "»", 20, c)
For Y = 0 To 15
For X = 0 To 15
GraphicDisplay(*GR, X * 16, Y * 16 + 96, Str(*WS\CharKey(Y * 16 + X) ), 12, c)
Next
Next
GraphicDisplay(*GR, 0, 352, "Boutons souris : " + RSet(Bin(*WS\msBts), 3, "0"), 20, c)
GraphicDisplay(*GR, 0, 384, "Molette souris : " + Str(*WS\msWheel), 20, c)
GraphicDisplay(*GR, 0, 416, "Position souris : " + Str(*WS\msX) + " x " + Str(*WS\msY), 20, c)
GraphicDisplay(*GR, 0, 448, "Horloge : " + Str(ElapsedMilliseconds() ), 20, c)
GraphicDisplay(*GR, 0, 480, Str(*WS\Dims\OffsetX), 20, c)
WinScrDims(*WS)
FlipBuffers()
ForEver
CompilerEndIf