This code provides a resizable GUI, where gadgets (button, editor) are automatically adapted according to the changed window size, including automatic adaption of the used font size.
Have fun with testing!
ButtonGadget_PB_Resizable_Font_and_Window_EX.pb (updated on 6th Dec. 2018)
Code: Select all
; Demo : Automatic resizing PB gadgets and fonts
; === Module DrawText_EX ===
DeclareModule DrawText_EX
Declare DrawText_EX(txt_x, txt_y, txt$, f_col=#White, b_col=#Black, flag=0, mode=0, stretch_x=0, stretch_y=0)
; All OS - Author(C) : Werner Albus - www.nachtoptik.de - www.quick-aes-256.de - Free for using and enhancing
; Flags : Text center=1 - Text right=2 - Text vertical=3
; Modes : Revers text mode=1 - RTL text mode=2 - Give only back the needed width mode=3 , height mode=4
; Mono line output give back the xx output coordinate - Multi line output give back the yy output coordinate
; For stretched text on a textured background often DrawingMode (#PB_2DDrawing_Transparent) is needed
; Create a image from the output, for post processing or using as image, give back a image (ID) - Padding -1 is automatic padding
Declare DrawTextCreateImage_EX(txt$, f_col=#White, b_col=#Black, flag=0, mode=0, font_ID=0, stretch_x=0, stretch_y=0, padding=0)
Declare PresetLineWidth_EX(max_1_) ; Preset the min output length for easy centric or right align outputs - Deactivate = 0
; Important for permanent changed outputs
Declare DrawText_EX_AutoBox(padding_=-1, ; Automatic padding = -1 - Deactivate = -2
box_color_=0,
offset_x_=0,
offset_y_=0,
offset_xx_=0,
offset_yy_=0)
Declare DrawText_EX_Box(activate_=1, box_color_1_=0, offset_x_1=0, offset_y_1_=0, width_=0, height_=0) ; Activate = 1 - Deactivate = 0
EndDeclareModule
Module DrawText_EX
EnableExplicit
Global max_1, padding=-2, box_color, offset_x, offset_y, offset_xx, offset_yy
Global activate, box_color_1, offset_x_1, offset_y_1, width, height, from_image, image_color
Procedure DrawText_EX(txt_x, txt_y, txt$, f_col=#White, b_col=#Black, flag=0, mode=0, stretch_x=0, stretch_y=0)
If txt$="" : ProcedureReturn -1 : EndIf
Protected i1=TextHeight(Space(1))+stretch_y, i2, i3, i4, i5, i6, i7, padding_1
Protected result, max, max_len, max_2, max_3, txt_x_0=txt_x, txt_y_0=txt_y, amount_lines
Protected txt1$, chr$, ln$, ln1$
Protected Dim f1$(0), Dim f2$(0)
txt1$=ReplaceString(ReplaceString(ReplaceString(txt$, #CRLF$, #LF$), #CR$, #LF$), #LFCR$, #LF$)
i7=Len(txt1$)
If flag<>3 And FindString(txt1$, #LF$)
amount_lines=CountString(txt1$, #LF$)+1
txt_y-i1
For result=1 To i7
ln$=StringField(txt1$, result, #LF$)
i4=Len(ln$)
If i4
max_2=TextWidth(ln$)+stretch_x*i4
If max_2>max_3
max_3=max_2
ln1$=ln$
i2+i1
max=TextWidth(ln$)+i4
max_len=i4
EndIf
EndIf
Next
If max_1>0
max=max_1
EndIf
If flag=1 ; Centered
txt_x+max_len*(stretch_x>>1)-max_len>>1
ElseIf flag=2 ; Right
txt_x+max_len*(stretch_x)-max_len
EndIf
EndIf
If mode=3 And flag<>3
If i2
If Not stretch_x
ProcedureReturn TextWidth(ln1$)+2
Else
i6=Len(ln1$)
For i4=1 To i6
i5+TextWidth(Mid(ln1$, i4, 1))
Next
ProcedureReturn i5+stretch_x*i6+stretch_x/12
EndIf
Else
If Not stretch_x
ProcedureReturn TextWidth(txt1$)+2
Else
For i4=1 To i7
i5+TextWidth(Mid(txt1$, i4, 1))
Next
ProcedureReturn i5+stretch_x*Len(txt1$)+stretch_x/12
EndIf
EndIf
EndIf
If mode=4 And flag<>3
If i2
ProcedureReturn amount_lines*(i1+1)-stretch_y
Else
ProcedureReturn i1+1-stretch_y
EndIf
EndIf
Macro first_char_width
i5=0
For i4=1 To i7
i6=TextWidth(Mid(txt1$, i4, 1))
If i6>i5
i5=i6
EndIf
Next
EndMacro
If padding=-1
padding_1=TextWidth(Space(3))
Else
padding_1=padding
EndIf
If mode=3 And flag=3
first_char_width
ProcedureReturn i5
EndIf
If mode=4 And flag=3
ProcedureReturn i1*i7-stretch_y
EndIf
If activate=1
Box(txt_x_0+offset_x_1,
txt_y_0+offset_y_1,
width,
height,
box_color_1)
EndIf
If Not from_image
If padding<>-2
If i2
Box(txt_x_0-padding_1+offset_x,
txt_y_0-padding_1+offset_y,
max+max_len*(stretch_x)-stretch_x-max_len+padding_1<<1+offset_xx,
amount_lines*i1-stretch_y+padding_1<<1+offset_yy,
box_color)
Else
If flag<>3
Box(txt_x_0-padding_1+offset_x,
txt_y_0-padding_1+offset_y,
TextWidth(txt1$)+stretch_x*(i7-1)+padding_1<<1+offset_xx,
i1+padding_1<<1+offset_yy,
box_color)
Else ; Vertical box
first_char_width
Box(txt_x_0-padding_1+offset_x>>1,
txt_y_0-padding_1+offset_y,
i5+padding_1<<1+offset_xx,
i1*i7+padding_1<<1+offset_yy,
box_color)
EndIf
EndIf
EndIf
Else
DrawingMode(#PB_2DDrawing_Transparent)
EndIf
Macro spread_x(txt_x, txt_y, ln)
i6=0
i4=Len(ln)
For i5=1 To Len(ln)
ln1$=Mid(ln, i5, 1)
If flag=1 And i2
DrawText(txt_x+i6-i4*stretch_x>>1, txt_y, ln1$, f_col, b_col)
ElseIf flag=2 And i2
DrawText(txt_x+i6-i4*stretch_x, txt_y, ln1$, f_col, b_col)
Else
DrawText(txt_x+i6, txt_y, ln1$, f_col, b_col)
EndIf
i6+TextWidth(ln1$)+stretch_x
Next
EndMacro
Macro rtl(txt)
i5=0
i3=Len(txt)
For i4=1 To i3
If Mid(txt, i4, 1)=" "
i6+1
EndIf
ln1$=StringField(txt, i4, " ")
If ln1$<>""
ReDim f1$(i5)
ReDim f2$(i5)
f1$(i5)=ln1$
f2$(i5)=ReverseString(ln1$)
i5+1
EndIf
Next
txt=ReverseString(txt)
For i4=0 To i5-1
txt=ReplaceString(txt, f2$(i4), f1$(i4))
Next
i3=0 : i5=0 : i6=0
EndMacro
Macro txt_out
If mode=1
ln$=ReverseString(ln$)
ElseIf mode=2
rtl(ln$)
EndIf
If flag=2 ; Right
If stretch_x
spread_x(txt_x+max-TextWidth(ln$), txt_y+i2, ln$)
Else
DrawText(txt_x+max-TextWidth(ln$), txt_y+i2, ln$, f_col, b_col)
EndIf
ElseIf flag=1 ; Centered
If stretch_x
spread_x(txt_x+max>>1-TextWidth(ln$)>>1, txt_y+i2, ln$)
Else
DrawText(txt_x+max>>1-TextWidth(ln$)>>1, txt_y+i2, ln$, f_col, b_col) : EndIf
Else ; Left
If stretch_x
spread_x(txt_x, txt_y+i2, ln$)
Else
DrawText(txt_x, txt_y+i2, ln$, f_col, b_col)
EndIf
EndIf
EndMacro
If flag=3 And mode=1
rtl(txt1$)
EndIf
If flag=3 ; Vertical
txt1$=ReplaceString(txt1$, #LF$, " ")
If mode
txt1$=ReverseString(txt1$)
EndIf
For result=1 To i7
chr$=Mid(txt1$, result, 1)
first_char_width
DrawText(i5>>1+txt_x-TextWidth(chr$)>>1, txt_y+i3, chr$, f_col, b_col)
i3+i1
Next
ProcedureReturn txt_y+i3
Else ; Horizontal
If i2
i2=0 : ln$=""
For result=1 To i7
chr$=Mid(txt1$, result, 1)
If chr$=#LF$
i2+i1
txt_out
ln$=""
Else
ln$+chr$
EndIf
Next
i2+i1
txt_out
ProcedureReturn txt_y+i2+i1
Else ; One line
If mode=1
txt$=ReverseString(txt$)
ElseIf mode=2
rtl(txt$)
EndIf
If stretch_x
spread_x(txt_x, txt_y, txt$)
Else
DrawText(txt_x, txt_y, txt$, f_col, b_col)
EndIf
EndIf
EndIf
If i6
ProcedureReturn txt_x+i6
Else
ProcedureReturn txt_x+TextWidth(txt$)
EndIf
EndProcedure
Procedure DrawTextCreateImage_EX(txt$, f_col=#White, b_col=#Black, flag=0, mode=0, font_ID=0, stretch_x=0, stretch_y=0, padding=0)
If txt$="" : ProcedureReturn -2 : EndIf
Protected image_ID=CreateImage(#PB_Any, 1, 1)
If Not image_ID : ProcedureReturn -3 : EndIf
If Not StartDrawing(ImageOutput(image_ID)) ; Get the needed width and length for the output
FreeImage(image_ID)
ProcedureReturn -4
EndIf
If IsFont(font_ID) : DrawingFont(FontID(font_ID)) : EndIf
If padding=-1
padding=TextWidth(Space(3))
EndIf
If max_1>0
Protected output_width=max_1 ; Get the needed width
Else
output_width=DrawText_EX(0, 0, txt$, 0, 0, flag, 3, stretch_x, stretch_y)-stretch_x ; Get the needed width
EndIf
Protected output_height=DrawText_EX(0, 0, txt$, 0, 0, flag, 4, stretch_x, stretch_y)-stretch_y ; Get the needed height
StopDrawing()
If mode=3
FreeImage(image_ID)
ProcedureReturn output_width+padding
EndIf
If mode=4
FreeImage(image_ID)
ProcedureReturn output_height+padding
EndIf
If Not ResizeImage(image_ID, output_width+padding<<1, output_height+padding<<1)
FreeImage(image_ID)
ProcedureReturn -5
EndIf
If Not StartDrawing(ImageOutput(image_ID)) ; Draw the text in the image
FreeImage(image_ID)
ProcedureReturn -6
EndIf
Box(0, 0, output_width+padding<<1, output_height+padding<<1, b_col)
If IsFont(font_ID) : DrawingFont(FontID(font_ID)) : EndIf
Protected old_activate=activate
activate=0
from_image=1
image_color=b_col
DrawText_EX(padding, padding, txt$, f_col, 0, flag, mode, stretch_x, stretch_y)
activate=old_activate
from_image=0
StopDrawing()
ProcedureReturn image_ID
EndProcedure
Procedure PresetLineWidth_EX(max_1_)
max_1=max_1_
EndProcedure
Procedure DrawText_EX_AutoBox(padding_=-1,
box_color_=0,
offset_x_=0,
offset_y_=0,
offset_xx_=0,
offset_yy_=0)
padding=padding_
box_color=box_color_
offset_x=offset_x_
offset_y=offset_y_
offset_xx=offset_xx_
offset_yy=offset_yy_
EndProcedure
Procedure DrawText_EX_Box(activate_=1, box_color_1_=0, offset_x_1_=0, offset_y_1_=0, width_=0, height_=0)
activate=activate_
box_color_1=box_color_1_
offset_x_1=offset_x_1_
offset_y_1=offset_y_1_
width=width_
height=height_
EndProcedure
EndModule
UseModule DrawText_EX
Procedure Offset_x_BF(old_window_x_size.f, window_ID, position_x.f)
ProcedureReturn position_x/(old_window_x_size/WindowWidth(window_ID))
EndProcedure
Procedure Offset_y_BF(old_window_y_size.f, window_ID, position_y.f)
ProcedureReturn position_y/(old_window_y_size/WindowHeight(window_ID))
EndProcedure
EnableExplicit
Global window_ID
Global origin_window_width, origin_window_height
Global gadget_1_ID, text_1$, x_pos_gadget_1, y_pos_gadget_1, button_width_gadget_1, button_height_gadget_1
Global gadget_2_ID, text_2$, x_pos_gadget_2, y_pos_gadget_2, button_width_gadget_2, button_height_gadget_2
Global gadget_3_ID, text_3$, x_pos_gadget_3, y_pos_gadget_3, button_width_gadget_3, button_height_gadget_3
Global gadget_4_ID, text_4$, x_pos_gadget_4, y_pos_gadget_4, button_width_gadget_4, button_height_gadget_4
Global max_font_size=99 ; This is the maximum font size to be output - between 40 and 60 should usually be enough
Global padding_x=25
CompilerIf #PB_Compiler_OS=#PB_OS_Linux
Global padding_y=11
CompilerElse
Global padding_y=5
CompilerEndIf
Global Dim font(max_font_size)
Global resulted_needed_font_size
Define needed_font_size
Procedure Needed_Button_Font_Size(window_ID,
text$,
origin_window_width,
origin_window_height,
x_pos_gadget,
y_pos_gadget,
button_width,
button_height,
padding_x,
padding_y)
Protected needed_font_size=max_font_size
If text$="" : ProcedureReturn 0 : EndIf
While needed_font_size>1
If DrawTextCreateImage_EX(text$, 0, 0, 0, 3, font(needed_font_size), 0, 0, padding_x)=<Offset_x_BF(origin_window_width, window_ID, button_width) And
DrawTextCreateImage_EX(text$, 0, 0, 0, 4, font(needed_font_size), 0, 0, padding_y)=<Offset_y_BF(origin_window_height, window_ID, button_height)
Break
EndIf
needed_font_size-1
Wend
ProcedureReturn needed_font_size
EndProcedure
Procedure SetGadgetStates(window_ID,
gadget_ID,
text$,
origin_window_width,
origin_window_height,
x_pos_gadget,
y_pos_gadget,
origin_button_width,
origin_button_height,
padding_x,
padding_y)
Protected resulted_needed_font_size=Needed_Button_Font_Size(window_ID,
text$,
origin_window_width,
origin_window_height,
x_pos_gadget,
y_pos_gadget,
origin_button_width,
origin_button_height,
padding_x,
padding_y)
SetGadgetFont(gadget_ID, FontID(font(resulted_needed_font_size)))
ResizeGadget(gadget_ID,
Offset_x_BF(origin_window_width, window_ID, x_pos_gadget),
Offset_y_BF(origin_window_height, window_ID, y_pos_gadget),
Offset_x_BF(origin_window_width, window_ID, origin_button_width),
Offset_y_BF(origin_window_height, window_ID, origin_button_height))
ProcedureReturn resulted_needed_font_size
EndProcedure
Procedure WindowResizing_BindEvent()
Protected resulted_needed_font_size=SetGadgetStates(window_ID,
gadget_1_ID,
text_1$,
origin_window_width,
origin_window_height,
x_pos_gadget_1,
y_pos_gadget_1,
button_width_gadget_1,
button_height_gadget_1,
padding_x,
padding_y)
; The font size can also be easily inherited - Samples for simple add any gadgets with inheritance
Protected editor_font_size=resulted_needed_font_size/1.8 : If editor_font_size<1 : editor_font_size=1 : EndIf
SetGadgetFont(gadget_2_ID, FontID(font(Int(editor_font_size)))) ; You can get simple a dynamic font size from any gadget for the text output
ResizeGadget(gadget_2_ID,
Offset_x_BF(origin_window_width, window_ID, x_pos_gadget_2),
Offset_y_BF(origin_window_height, window_ID, y_pos_gadget_2),
Offset_x_BF(origin_window_width, window_ID, button_width_gadget_2),
Offset_y_BF(origin_window_height, window_ID, button_height_gadget_2))
editor_font_size=resulted_needed_font_size/1.8 : If editor_font_size<1 : editor_font_size=1 : EndIf
SetGadgetFont(gadget_3_ID, FontID(font(Int(editor_font_size)))) ; You can get simple a dynamic font size from any gadget for the text output
ResizeGadget(gadget_3_ID,
Offset_x_BF(origin_window_width, window_ID, x_pos_gadget_3),
Offset_y_BF(origin_window_height, window_ID, y_pos_gadget_3),
Offset_x_BF(origin_window_width, window_ID, button_width_gadget_3),
Offset_y_BF(origin_window_height, window_ID, button_height_gadget_3))
editor_font_size=resulted_needed_font_size/4 : If editor_font_size<1 : editor_font_size=1 : EndIf
SetGadgetFont(gadget_4_ID, FontID(font(Int(editor_font_size)))) ; You can get simple a dynamic font size from any gadget for the text output
ResizeGadget(gadget_4_ID,
Offset_x_BF(origin_window_width, window_ID, x_pos_gadget_4),
Offset_y_BF(origin_window_height, window_ID, y_pos_gadget_4),
Offset_x_BF(origin_window_width, window_ID, button_width_gadget_4),
Offset_y_BF(origin_window_height, window_ID, button_height_gadget_4))
EndProcedure
window_ID=OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore , 1000, 580, "GFX_Wizzard_BF",
#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_Invisible | #PB_Window_SizeGadget)
SetWindowColor(window_ID, $FF0000)
WindowBounds(window_ID, 170, 120, 1800, 1000)
For needed_font_size=1 To max_font_size ; Get the fonts
font(needed_font_size)=LoadFont(#PB_Any, "", needed_font_size, #PB_Font_Bold)
Next needed_font_size
origin_window_width=WindowWidth(window_ID)
origin_window_height=WindowHeight(window_ID)
; ==================== Button 1 =====================
text_1$="It's magic"+#LF$+
"This is a large PB Button"+#LF$+
"Resize the Window"
button_width_gadget_1=600
button_height_gadget_1=200
x_pos_gadget_1=30
y_pos_gadget_1=WindowHeight(window_ID)/2-button_height_gadget_1/2
gadget_1_ID=ButtonGadget(#PB_Any,
x_pos_gadget_1,
y_pos_gadget_1,
button_width_gadget_1,
button_height_gadget_1,
text_1$,
#PB_Button_MultiLine)
; ==================== Button 2 =====================
text_2$="Bye"
button_width_gadget_2=160
button_height_gadget_2=60
x_pos_gadget_2=WindowWidth(window_ID)/2-button_width_gadget_2/2
y_pos_gadget_2=WindowHeight(window_ID)-button_height_gadget_2-30
gadget_2_ID=ButtonGadget(#PB_Any,
x_pos_gadget_2,
y_pos_gadget_2,
button_width_gadget_2,
button_height_gadget_2,
text_2$,
#PB_Button_MultiLine)
; ==================== Button 3 =====================
text_3$="GFX_Wizzard_BF"+#LF$+
"Simple a little more"
button_width_gadget_3=350
button_height_gadget_3=90
x_pos_gadget_3=WindowWidth(window_ID)/2-button_width_gadget_3/2
y_pos_gadget_3=30
gadget_3_ID=ButtonGadget(#PB_Any,
x_pos_gadget_3,
y_pos_gadget_3,
button_width_gadget_3,
button_height_gadget_3,
text_3$,
#PB_Button_MultiLine)
; ==================== Editor 1 =====================
; Sample for simple add any gadgets
text_4$="This is a Editor Gadget"+#LF$+
"The function is also included in GFX_Wizzard_BF,"+#LF$+
"with more special functions and BF enhanced gadgets"+#LF$+
"It is possible with all available gadgets,"+#LF$+
"to create with this base code quickly a dynamic GUI"+#LF$+
"There are as sample, ColorButton_BF, TextGadget_BF, ImageGadget_BF, ButtonImage"+#LF$+
"Images and texts are fitted dynamically and precisely, without any distortion"+#LF$+
"MessageRequester_BF automatically supports all of the above functions"+#LF$+
"Amazing demo codes are available in the GFX_Wizzard_BF"+#LF$+
"Download package included"
button_width_gadget_4=320
button_height_gadget_4=200
x_pos_gadget_4=WindowWidth(window_ID)-button_width_gadget_4-30
y_pos_gadget_4=WindowHeight(window_ID)/2-button_height_gadget_4/2
gadget_4_ID=EditorGadget(#PB_Any,
x_pos_gadget_4,
y_pos_gadget_4,
button_width_gadget_4,
button_height_gadget_4)
Define editor_font_size=resulted_needed_font_size/2.5 : If editor_font_size<1 : editor_font_size=1 : EndIf
SetGadgetFont(gadget_4_ID, FontID(font(Int(editor_font_size))))
SetGadgetText(gadget_4_ID, text_4$)
; =============== Get the result ===================
HideWindow(window_ID, 0)
WindowResizing_BindEvent() ; Init
BindEvent(#PB_Event_SizeWindow, @WindowResizing_BindEvent())
; TODO - After developing you can so preset simple the first or needed output size you want
; Change the user the window size, you can restart the GUI with this user defined size
; ResizeWindow(window_ID, #PB_Ignore, #PB_Ignore, 900, 600)
Repeat
Define win_event=WaitWindowEvent()
If win_event=#PB_Event_CloseWindow
Break
ElseIf win_event And EventGadget()=gadget_2_ID
Break
EndIf
ForEver