It is currently Tue Jul 23, 2019 12:39 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: Dynamic Gadgets with automatic Font size adaption
PostPosted: Thu Dec 06, 2018 11:29 pm 
Offline
PureBasic Team
PureBasic Team
User avatar

Joined: Fri Apr 25, 2003 6:14 pm
Posts: 1695
Location: Germany (Saxony, Deutscheinsiedel)
Another new and standalone code, by Werner Albus, which is also part of actually updated GFX_Wizzard_BF package.

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! :D

ButtonGadget_PB_Resizable_Font_and_Window_EX.pb (updated on 6th Dec. 2018)
Code:
; 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

_________________
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye