Sources PureBasic
Sources PureBasicConsultez toutes les sources
Nombre d'auteurs : 41, nombre de sources : 88, dernière mise à jour : 13 août 2011
- Comment redimensionner un gadget en fonction de la taille de la police et de l'OS ?
- 5.1. ButtonGadget (1)
- 5.2. CanvasGadget (3)
- 5.3. EditorGadget (1)
- 5.4. ScrollBarGadget (1)
- 5.5. TreeGadget (3)
Ce code permet de redimensionner les gadgets en fonction de la taille de la police utilisée. Cette solution est multi-plateforme, Windows, Linux et Mac OS.
Introduction de Freak :
When developing crossplatform programs, one problem is the difference in font sizes among the OS. But even when developing only for Windows, it is a good practice to not assume a fixed font size as that will look bad for people who use a larger default font as well.
The following procedure is used by the PureBasic IDE to adjust gadget sizes to fit the text they contain. This allows the IDE dialogs to look good with any font size and also allows translated text to fit even if it is longer than the default text.
Of course with this you need a more complex code to arrange/resize the gadgets, but as you can see below when this is done you can even change the font (or gadget content) on the fly and easily resize the gadgets to fit.
;
; Calculates the size required to display a Gadget properly.
;
; Supported Gadgets:
; Button, Checkbox, Option, Text, String, ComboBox, Image
;
; Note:
; For Gadgets with variable content (String, ComboBox), only the returned height
; is useful, as the width will only be an absolute minimum value.
;
; The 'Flags' parameter gives gadget flags to include in the calculation.
; Currently only #PB_Text_Border makes a difference there.
;
CompilerIf Defined(Max, #PB_Procedure) = 0
Procedure
Max(a, b)
If
a >
b
ProcedureReturn
a
Else
ProcedureReturn
b
EndIf
EndProcedure
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Structure
PB_Gadget
*
Gadget.GtkWidget
*
Container.GtkWidget
*
VT
UserData.i
GadgetData.i[4
]
EndStructure
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Structure
OSX_Rect
top.w
left.w
bottom.w
right.w
EndStructure
#noErr
=
0
CompilerEndIf
; Stores the result in *Width\l and *Height\l
;
Procedure
GetRequiredSize(Gadget, *
Width.LONG, *
Height.LONG, Flags =
0
)
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
DC =
GetDC_(GadgetID(Gadget))
oldFont =
SelectObject_(DC, GetGadgetFont(Gadget))
Size.SIZE
Select
GadgetType(Gadget)
Case
#PB_GadgetType_Text
Text$ =
RemoveString(GetGadgetText(Gadget), Chr(10
))
count =
CountString(Text$, Chr(13
)) +
1
empty =
0
maxheight =
0
For
index =
1
To
count
Line$ =
StringField(Text$, index, Chr(13
))
If
Line$ =
""
empty +
1
Else
GetTextExtentPoint32_(DC, @Line$, Len(Line$), @LineSize.SIZE)
Size\cx =
Max(Size\cx, LineSize\cx)
Size\cy +
LineSize\cy
maxheight =
Max(maxheight, LineSize\cy)
EndIf
Next
index
Size\cy +
empty *
maxheight
If
Flags &
#PB_Text_Border
Size\cx +
GetSystemMetrics_(#SM_CXEDGE
) *
2
Size\cy +
GetSystemMetrics_(#SM_CYEDGE
) *
2
Else
Size\cx +
2
Size\cy +
2
EndIf
Case
#PB_GadgetType_CheckBox
, #PB_GadgetType_Option
Text$ =
GetGadgetText(Gadget)
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx +
20
Size\cy =
Max(Size\cy+
2
, 20
)
Case
#PB_GadgetType_Button
Text$ =
GetGadgetText(Gadget)
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx +
GetSystemMetrics_(#SM_CXEDGE
)*
2
Size\cy =
Max(Size\cy+
GetSystemMetrics_(#SM_CYEDGE
)*
2
, 24
)
Size\cx +
10
Case
#PB_GadgetType_String
Text$ =
GetGadgetText(Gadget) +
"Hg"
GetTextExtentPoint32_(DC, @Text$, Len(Text$), @Size.SIZE)
Size\cx =
GetSystemMetrics_(#SM_CXEDGE
)*
2
Size\cy =
Max(Size\cy+
GetSystemMetrics_(#SM_CXEDGE
)*
2
, 20
)
Case
#PB_GadgetType_ComboBox
GetTextExtentPoint32_(DC, @"Hg"
, 2
, @Size.SIZE)
Size\cy =
Max(Size\cy +
8
, 21
)
Size\cx =
Size\cy
Case
#PB_GadgetType_Image
Size\cx =
GadgetWidth(Gadget)
Size\cy =
GadgetHeight(Gadget)
EndSelect
SelectObject_(DC, oldFont)
ReleaseDC_(GadgetID(Gadget), DC)
*
Width\l =
Size\cx
*
Height\l =
Size\cy
CompilerCase #PB_OS_Linux
*
Gadget.PB_Gadget =
IsGadget(Gadget)
If
*
Gadget And
*
Gadget\Container And
GadgetType(Gadget) <>
#PB_GadgetType_ComboBox
gtk_widget_size_request_(*
Gadget\Container, @RealSize.GtkRequisition)
gtk_widget_set_size_request_(*
Gadget\Container, -
1
, -
1
)
gtk_widget_size_request_(*
Gadget\Container, @Size.GtkRequisition)
gtk_widget_set_size_request_(*
Gadget\Container, RealSize\Width, RealSize\Height)
Else
gtk_widget_size_request_(GadgetID(Gadget), @RealSize.GtkRequisition)
gtk_widget_set_size_request_(GadgetID(Gadget), -
1
, -
1
)
gtk_widget_size_request_(GadgetID(Gadget), @Size.GtkRequisition)
gtk_widget_set_size_request_(GadgetID(Gadget), RealSize\Width, RealSize\Height)
EndIf
If
GadgetType(Gadget) =
#PB_GadgetType_ComboBox
Or
GadgetType(Gadget) =
#PB_GadgetType_String
*
Width\l =
20
Else
*
Width\l =
Size\Width
EndIf
*
Height\l =
Size\Height
CompilerCase #PB_OS_MacOS
Type =
GadgetType(Gadget)
If
Type =
#PB_GadgetType_Image
*
Width\l =
GadgetWidth(Gadget)
*
Height\l =
GadgetHeight(Gadget)
ElseIf
Type =
#PB_GadgetType_Text
realwidth =
GadgetWidth(Gadget)
*
Width\l =
40
*
Height\l =
20
ResizeGadget(Gadget, #PB_Ignore
, #PB_Ignore
, 1000
, #PB_Ignore
)
If
GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) =
#noErr
Height =
Rect\bottom -
Rect\top
If
Height >
0
Min =
0
Max =
1000
While
Max >
Min+
2
Mid =
(Min +
Max) /
2
ResizeGadget(Gadget, #PB_Ignore
, #PB_Ignore
, Mid, #PB_Ignore
)
If
GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) <>
#noErr
ProcedureReturn
EndIf
If
Rect\bottom -
Rect\top >
Height
Min =
Mid
Else
Max =
Mid
EndIf
Wend
*
Width\l =
Rect\right -
Rect\left +
2
*
Height\l =
Max(Height, 20
)
EndIf
EndIf
ResizeGadget(Gadget, #PB_Ignore
, #PB_Ignore
, realwidth, #PB_Ignore
)
Else
If
GetBestControlRect_(GadgetID(Gadget), @Rect.OSX_Rect, @BaseLine.w) =
#noErr
*
Width\l =
Rect\right -
Rect\left
*
Height\l =
Max(Rect\bottom -
Rect\top, 20
)
If
Type =
#PB_GadgetType_Button
Or
Type =
#PB_GadgetType_String
*
Height\l =
Max(*
Height\l, 24
)
EndIf
Else
*
Width\l =
40
*
Height\l =
20
EndIf
If
Type =
#PB_GadgetType_String
Or
Type =
#PB_GadgetType_ComboBox
*
Width\l =
30
EndIf
EndIf
CompilerEndSelect
EndProcedure
; convinience wrappers if only one size is needed
;
Procedure
GetRequiredWidth(Gadget, Flags =
0
)
Protected
Width.l, Height.l
GetRequiredSize(Gadget, @Width, @Height, Flags)
ProcedureReturn
Width
EndProcedure
Procedure
GetRequiredHeight(Gadget, Flags =
0
)
Protected
Width.l, Height.l
GetRequiredSize(Gadget, @Width, @Height, Flags)
ProcedureReturn
Height
EndProcedure
Et voici un code pour tester :
Enumeration
#Button_1
#Button_2
#Button_3
#Checkbox_1
#Checkbox_2
#Checkbox_3
#String
#ComboBox
#ChangeFont
EndEnumeration
Procedure
Resize()
GetRequiredSize(#Button_1
, @Button1Width.l, @Button1Height.l)
GetRequiredSize(#Button_2
, @Button2Width.l, @Button2Height.l)
GetRequiredSize(#Button_3
, @Button3Width.l, @Button3Height.l)
Height =
Max(Button1Height, Max(Button2Height, Button3Height))
x =
10
y =
10
ResizeGadget(#Button_1
, x, y, Button1Width, Height): x +
Button1Width +
5
ResizeGadget(#Button_2
, x, y, Button2Width, Height): x +
Button2Width +
5
ResizeGadget(#Button_3
, x, y, Button3Width, Height): x +
Button3Width +
5
y +
Height +
10
WindowWidth =
x
GetRequiredSize(#Checkbox_1
, @Check1Width.l, @Check1Height.l)
GetRequiredSize(#Checkbox_2
, @Check2Width.l, @Check2Height.l)
GetRequiredSize(#Checkbox_3
, @Check3Width.l, @Check3Height.l)
Width =
Max(Check1Width, Max(Check2Width, Check3Width))
ResizeGadget(#Checkbox_1
, 10
, y, Width, Check1Height): y +
Check1Height +
5
ResizeGadget(#Checkbox_2
, 10
, y, Width, Check2Height): y +
Check2Height +
5
ResizeGadget(#Checkbox_3
, 10
, y, Width, Check3Height): y +
Check3Height +
5
y +
5
WindowWidth =
Max(WindowWidth, Width+
20
)
Height =
GetRequiredHeight(#String
)
ResizeGadget(#String
, 10
, y, WindowWidth-
20
, Height)
y +
Height +
5
Height =
GetRequiredHeight(#ComboBox
)
ResizeGadget(#ComboBox
, 10
, y, WindowWidth-
20
, Height)
y +
Height +
10
GetRequiredSize(#ChangeFont
, @ButtonWidth.l, @ButtonHeight.l)
ResizeGadget(#ChangeFont
, (WindowWidth-
ButtonWidth)/
2
, y, ButtonWidth, ButtonHeight)
y +
ButtonHeight +
10
ResizeWindow(0
, #PB_Ignore
, #PB_Ignore
, WindowWidth, y)
EndProcedure
If
OpenWindow(0
, 100
, 100
, 0
, 0
, "Size test"
, #PB_Window_SystemMenu
|
#PB_Window_Invisible
)
ButtonGadget(#Button_1
, 0
, 0
, 0
, 0
, "Short"
)
ButtonGadget(#Button_2
, 0
, 0
, 0
, 0
, "-- Longer --"
)
ButtonGadget(#Button_3
, 0
, 0
, 0
, 0
, "------- Longest ------"
)
CheckBoxGadget(#Checkbox_1
, 0
, 0
, 0
, 0
, "Hello world"
)
CheckBoxGadget(#Checkbox_2
, 0
, 0
, 0
, 0
, "The quick brown fox jumped over the lazy dog."
)
CheckBoxGadget(#Checkbox_3
, 0
, 0
, 0
, 0
, "Whatever"
)
StringGadget(#String
, 0
, 0
, 0
, 0
, "String"
)
ComboBoxGadget(#ComboBox
, 0
, 0
, 0
, 0
)
AddGadgetItem(#ComboBox
, 0
, "ComboBox"
)
SetGadgetState(#ComboBox
, 0
)
ButtonGadget(#ChangeFont
, 0
, 0
, 0
, 0
, "Change font"
)
Resize()
HideWindow(0
, 0
)
Repeat
Event =
WaitWindowEvent()
If
Event =
#PB_Event_Gadget
And
EventGadget() =
#ChangeFont
If
FontRequester("Arial"
, 20
, 0
)
If
LoadFont(0
, SelectedFontName(), SelectedFontSize(), SelectedFontStyle())
For
Gadget =
#Button_1
To
#ChangeFont
SetGadgetFont(Gadget, FontID(0
))
Next
Gadget
Resize()
EndIf
EndIf
EndIf
Until
Event =
#PB_Event_CloseWindow
EndIf