Seite 1 von 1

Modul: Scaling Window

Verfasst: 14.04.2014 15:27
von mk-soft
Nach dem guten Modul "ResizeWindowModul" von Thorsten wollte ich es mir noch etwas einfacher machen.

Das Modul skalliert automisch alle Gadget die zum Fenster gehören.

Folgende Funktionen sind vorhanden.
- AddScaleWindow(id) - Analysiert das Fenster und speichert die zugehörigen Gadgets ab
- UpdateScaleImages() - Aktuallisiert die gespeicherten Handles von den Images
- ScaleWindow(id) - Aufruf bei Event #PB_Event_SizeWindow
- RestoreWindow(id, position) - Stellt die orginale Fenstergrösse wieder her. Optional auch die Position des Fensters

Code: Alles auswählen

;-TOP
; Kommentar     : Modul Scaling 
; Author        : mk-soft
; Second Author : 
; Datei         : ScaleWindow.pb
; Version       : 1.04
; Erstellt      : 14.04.2014
; Geändert      : 22.04.2014
; 
; Compilermode  : ASCII, Unicode
; OS            : Windows, Linux
;
; ***************************************************************************************

;- Modul Public
DeclareModule ScalingWindow
  
  Declare AddScaleWindow(id)
  Declare UpdateScaleImages()
  Declare ScaleWindow(id)
  Declare RestoreWindow(id, position = 0)
  
EndDeclareModule

;- Modul Private
Module ScalingWindow
  
  EnableExplicit

  ; ***************************************************************************************
  
  ;- PB Interne System Funktionen
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Import ""
      PB_Object_EnumerateAll(obj,cb,uData)
      PB_Gadget_Objects.l
    EndImport
  CompilerElse
    ImportC ""
      PB_Object_EnumerateAll(obj,cb,uData)
      PB_Gadget_Objects.l
      gdk_pixbuf_unref (*pixbuf)
      gdk_pixbuf_scale_simple (*src, dest_width, dest_height, interp_type)
      gdk_pixbuf_get_width(*pixbuf)
      gdk_pixbuf_get_height(*pixbuf)
    EndImport
    #GDK_INTERP_NEAREST  = 0
    #GDK_INTERP_BILINEAR = 2
    #GDK_INTERP_HYPER    = 3
  CompilerEndIf
  
  
  ; ***************************************************************************************
  
  ;- Strukturen
  
  Structure udtGadgetData
    id.i
    x.i
    y.i
    dx.i
    dy.i
    hFont.i
    hImage.i
    hPressedImage.i
    hImageResize.i
    hPressedImageResize.i
    ImageWidth.i
    ImageHeight.i
    PressedImageWidth.i
    PressedImageHeight.i
  EndStructure
  
  Structure udtWindowData
    id.i
    hWnd.i ; Linux Container
    x.i
    y.i
    dx.i
    dy.i
    List gadgets.udtGadgetData()
  EndStructure
  
  Global NewList WindowData.udtWindowData()
  
  ; ***************************************************************************************
  
  ;- Enumeration Callback
  Procedure GadgetEnumerateCB(id,*element,udata)
    
    Protected *parent
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      Protected bitmap.bitmap
    CompilerEndIf
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      *parent = GetAncestor_(GadgetID(id), #GA_ROOT) ; handle
    CompilerElse
      *parent = gtk_widget_get_toplevel_(GadgetID(id)) ; container
    CompilerEndIf
    
    If *parent <> udata
      ProcedureReturn #True
    EndIf
    
    AddElement(WindowData()\gadgets())
    With WindowData()\gadgets()
      \id = id
      \x = GadgetX(id)
      \y = GadgetY(id)
      \dx = GadgetWidth(id)
      \dy = GadgetHeight(id)
      \hFont = GetGadgetFont(id)
      If GadgetType(id) = #PB_GadgetType_Image
        \hImage = GetGadgetState(id)
        If \hImage
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            GetObject_(\hImage, SizeOf(bitmap), @bitmap)
            \ImageWidth = bitmap\bmWidth
            \ImageHeight = bitmap\bmHeight
          CompilerElse
            \ImageWidth = gdk_pixbuf_get_width(\hImage)
            \ImageHeight = gdk_pixbuf_get_height(\hImage)
          CompilerEndIf
        EndIf
      ElseIf GadgetType(id) = #PB_GadgetType_ButtonImage
        \hImage = GetGadgetAttribute(id, #PB_Button_Image)
        If \hImage
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            GetObject_(\hImage, SizeOf(bitmap), @bitmap)
            \ImageWidth = bitmap\bmWidth
            \ImageHeight = bitmap\bmHeight
          CompilerElse
            \ImageWidth = gdk_pixbuf_get_width(\hImage)
            \ImageHeight = gdk_pixbuf_get_height(\hImage)
          CompilerEndIf
        EndIf
        \hPressedImage = GetGadgetAttribute(id, #PB_Button_PressedImage)
        If \hPressedImage
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            GetObject_(\hPressedImage, SizeOf(bitmap), @bitmap)
            \PressedImageWidth = bitmap\bmWidth
            \PressedImageHeight = bitmap\bmHeight
          CompilerElse
            \PressedImageWidth = gdk_pixbuf_get_width(\hPressedImage)
            \PressedImageHeight = gdk_pixbuf_get_height(\hPressedImage)
          CompilerEndIf
        EndIf
      EndIf
    EndWith
    
    ProcedureReturn #True
    
  EndProcedure
  
  ; ***************************************************************************************
  
  Procedure AddScaleWindow(id)
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      Protected *hWnd
    CompilerElse
      Protected *hWnd.GtkWindow
    CompilerEndIf
    
    ; Vorhandene Daten löschen
    ForEach WindowData()
      If WindowData()\id = id
        DeleteElement(WindowData())
        Break
      EndIf
    Next
    
    ; Neu Daten anlegen
    AddElement(WindowData())
    With WindowData()
      \id = id
      \x = WindowX(id)
      \y = WindowY(id)
      \dx = WindowWidth(id)
      \dy = WindowHeight(id)
      *hWnd = WindowID(id)
      CompilerIf #PB_Compiler_OS = #PB_OS_Windows
        \hWnd = *hWnd
      CompilerElse
        \hWnd = *hWnd\bin\container
      CompilerEndIf
      ; Gadgets von Fenster hinzufügen. Kann sich bei einer neuen Version von PB ändern  
      PB_Object_EnumerateAll(PB_Gadget_Objects,@GadgetEnumerateCB(),\hWnd)
      
    EndWith
    
    ProcedureReturn ListSize(WindowData()\gadgets())
    
  EndProcedure
  
  ; ***************************************************************************************
  
  Procedure UpdateScaleImages()
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      Protected bitmap.bitmap
    CompilerEndIf
    
    ForEach WindowData()
      ForEach WindowData()\gadgets()
        With WindowData()\gadgets()
          If GadgetType(\id) = #PB_GadgetType_Image
            \hImage = GetGadgetState(\id)
            If \hImage
              CompilerIf #PB_Compiler_OS = #PB_OS_Windows
                GetObject_(\hImage, SizeOf(bitmap), @bitmap)
                \ImageWidth = bitmap\bmWidth
                \ImageHeight = bitmap\bmHeight
              CompilerElse
                \ImageWidth = gdk_pixbuf_get_width(\hImage)
                \ImageHeight = gdk_pixbuf_get_height(\hImage)
              CompilerEndIf
            EndIf
          ElseIf GadgetType(\id) = #PB_GadgetType_ButtonImage
            \hImage = GetGadgetAttribute(\id, #PB_Button_Image)
            If \hImage
              CompilerIf #PB_Compiler_OS = #PB_OS_Windows
                GetObject_(\hImage, SizeOf(bitmap), @bitmap)
                \ImageWidth = bitmap\bmWidth
                \ImageHeight = bitmap\bmHeight
              CompilerElse
                \ImageWidth = gdk_pixbuf_get_width(\hImage)
                \ImageHeight = gdk_pixbuf_get_height(\hImage)
              CompilerEndIf
            EndIf
            \hPressedImage = GetGadgetAttribute(\id, #PB_Button_PressedImage)
            If \hPressedImage
              CompilerIf #PB_Compiler_OS = #PB_OS_Windows
                GetObject_(\hPressedImage, SizeOf(bitmap), @bitmap)
                \PressedImageWidth = bitmap\bmWidth
                \PressedImageHeight = bitmap\bmHeight
              CompilerElse
                \PressedImageWidth = gdk_pixbuf_get_width(\hPressedImage)
                \PressedImageHeight = gdk_pixbuf_get_height(\hPressedImage)
              CompilerEndIf
            EndIf
          EndIf
        EndWith
      Next
    Next
    
  EndProcedure
  
  ; ***************************************************************************************
  
  Procedure ScaleWindow(id)
    
    Protected org_dx, org_dy, win_dx, win_dy, x, y, dx, dy
    Protected find
    
    ForEach WindowData()
      If id = WindowData()\id
        find = #True
        Break
      EndIf
    Next
    If Not find
      ProcedureReturn 0
    EndIf
    
    With WindowData()
      org_dx = \dx
      org_dy = \dy
    EndWith
    
    win_dx = WindowWidth(id)
    win_dy = WindowHeight(id)
    
    ForEach WindowData()\gadgets()
      With WindowData()\gadgets()
        x = \x * win_dx / org_dx
        y = \y * win_dy / org_dy
        dx = \dx * win_dx / org_dx
        dy = \dy * win_dy / org_dy
        ResizeGadget(\id, x, y, dx, dy)
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          If GadgetType(\id) = #PB_GadgetType_Image
            If \hImageResize
              DeleteObject_(\hImageResize)
            EndIf
            If \hImage
              dx = \ImageWidth * win_dx / org_dx
              dy = \ImageHeight * win_dy / org_dy
              \hImageResize = CopyImage_(\hImage, #IMAGE_BITMAP, dx, dy, 0)
              If \hImageResize
                SetGadgetState(\id, \hImageResize)
              EndIf
            EndIf
          ElseIf GadgetType(\id) = #PB_GadgetType_ButtonImage
            If \hImageResize
              DeleteObject_(\hImageResize)
            EndIf
            If \hPressedImageResize
              DeleteObject_(\hPressedImageResize)
            EndIf
            If \hImage
              dx = \ImageWidth * win_dx / org_dx
              dy = \ImageHeight * win_dy / org_dy
              \hImageResize = CopyImage_(\hImage, #IMAGE_BITMAP, dx, dy, 0)
              If \hImageResize
                SetGadgetAttribute(\id, #PB_Button_Image, \hImageResize)
              EndIf
            EndIf
            If \hPressedImage
              dx = \PressedImageWidth * win_dx / org_dx
              dy = \PressedImageHeight * win_dy / org_dy
              \hPressedImageResize = CopyImage_(\hPressedImage, #IMAGE_BITMAP, dx, dy, 0)
              If \hPressedImageResize
                SetGadgetAttribute(\id, #PB_Button_PressedImage, \hPressedImageResize)
              EndIf
            EndIf
          EndIf
        CompilerElse ; Linux
          If GadgetType(\id) = #PB_GadgetType_Image
            If \hImageResize
              gdk_pixbuf_unref(\hImageResize)
            EndIf
            If \hImage
              dx = \ImageWidth * win_dx / org_dx
              dy = \ImageHeight * win_dy / org_dy
              \hImageResize = gdk_pixbuf_scale_simple(\hImage, dx, dy, #GDK_INTERP_BILINEAR)
              If \hImageResize
                SetGadgetState(\id, \hImageResize)
              EndIf
            EndIf
          ElseIf GadgetType(\id) = #PB_GadgetType_ButtonImage
            If \hImageResize
              gdk_pixbuf_unref(\hImageResize)
            EndIf
            If \hPressedImageResize
              gdk_pixbuf_unref(\hPressedImageResize)
            EndIf
            If \hImage
              dx = \ImageWidth * win_dx / org_dx
              dy = \ImageHeight * win_dy / org_dy
              \hImageResize = gdk_pixbuf_scale_simple(\hImage, dx, dy, #GDK_INTERP_BILINEAR)
              If \hImageResize
                SetGadgetAttribute(\id, #PB_Button_Image, \hImageResize)
              EndIf
            EndIf
            If \hPressedImage
              dx = \PressedImageWidth * win_dx / org_dx
              dy = \PressedImageHeight * win_dy / org_dy
              \hPressedImageResize = gdk_pixbuf_scale_simple(\hPressedImage, dx, dy, #GDK_INTERP_BILINEAR)
              If \hPressedImageResize
                SetGadgetAttribute(\id, #PB_Button_PressedImage, \hPressedImageResize)
              EndIf
            EndIf
          EndIf
        CompilerEndIf
      EndWith
    Next
    
  EndProcedure
  
  ; ***************************************************************************************
  
  Procedure RestoreWindow(id, position = 0)
    
    Protected find
    
    ForEach WindowData()
      If id = WindowData()\id
        find = #True
        Break
      EndIf
    Next
    If Not find
      ProcedureReturn 0
    EndIf
    
    With WindowData()
      If position
        ResizeWindow(id, \x, \y, \dx, \dy)
      Else
        ResizeWindow(id, #PB_Ignore, #PB_Ignore, \dx, \dy)
      EndIf  
    EndWith
    
  EndProcedure
  
EndModule

;- Test

CompilerIf #PB_Compiler_IsMainFile
  
  Procedure Main1()
    
    #WindowWidth  = 450
    #WindowHeight = 305
    
    ; Load our images.. 
    ;
    LoadImage(0, #PB_Compiler_Home + "examples/sources/Data/Drive.bmp")
    LoadImage(1, #PB_Compiler_Home + "examples/sources/Data/File.bmp")
    LoadImage(2, #PB_Compiler_Home + "examples/sources/Data/PureBasic.bmp")
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      ; Only Windows supports .ico file format
      LoadImage(3, #PB_Compiler_Home + "examples/sources/Data/CdPlayer.ico")
    CompilerElse
      LoadImage(3, #PB_Compiler_Home + "examples/sources/Data/Drive.bmp")
    CompilerEndIf
    
    CreatePopupMenu(0)
      MenuItem(0, "Popup !")
      
    style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
    If OpenWindow(1, #PB_Ignore, #PB_Ignore, #WindowWidth, #WindowHeight, "Main 1 - Advanced Gadget Demonstration", style)
    
      ListIconGadget(5, 170, 50, 265, 200, "Column 1", 131)
      AddGadgetColumn(5, 1, "Column 2", 300)
      AddGadgetColumn(5, 2, "Column 3", 80)
      
      TextGadget(4, 10, 16, 180, 24, "Please wait while initializing...")
      
      ProgressBarGadget(3, 10, 260, #WindowWidth-25, 20, 0, 100)
      SetGadgetState(3, 50)
      
      ImageGadget      (0, 200, 5, 0, 0, ImageID(2))
      ButtonImageGadget(1, 384, 5, 50, 36, ImageID(3))
      SetGadgetAttribute(1, #PB_Button_Image, ImageID(0))
      ;SetGadgetAttribute(1, #PB_Button_PressedImage, ImageID(1))
      
      TreeGadget    (2,  10, 50, 150, 200)
      SetGadgetText(4, "Initialize Ok... Welcome !")
      For k=0 To 10
        AddGadgetItem(2, -1, "General "+Str(k), ImageID(1))
        AddGadgetItem(2, -1, "ScreenMode", ImageID(1))
          AddGadgetItem(2, -1, "640*480", ImageID(1), 1)
          AddGadgetItem(2, -1, "800*600", ImageID(3), 1)
          AddGadgetItem(2, -1, "1024*768", ImageID(1), 1)
          AddGadgetItem(2, -1, "1600*1200", ImageID(1), 1)
        AddGadgetItem(2, -1, "Joystick", ImageID(1))
      Next
      
      For k=0 To 100
        AddGadgetItem(5, -1, "Element "+Str(k)+Chr(10)+"C 2"+Chr(10)+"Comment 3", ImageID(3))
      Next
      
      SetGadgetState(5, 8)
      
    EndIf
    
  EndProcedure
  
  Procedure Main2()
    
    style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
    If OpenWindow(2, #PB_Ignore, #PB_Ignore, 322, 220, "Main 2 - PanelGadget", style)
      PanelGadget     (20, 8, 8, 306, 203)
        AddGadgetItem (20, -1, "Panel 1")
          PanelGadget (21, 5, 5, 290, 166)
            AddGadgetItem(21, -1, "Sub-Panel 1")
              ExplorerListGadget(22, 0, 0, 285, 140, "")
            AddGadgetItem(21, -1, "Sub-Panel 2")
            AddGadgetItem(21, -1, "Sub-Panel 3")
          CloseGadgetList()
        AddGadgetItem (20, -1,"Panel 2")
          ButtonGadget(27, 10, 15, 80, 24,"Restore 1")
          ButtonGadget(28, 95, 15, 80, 24,"Restore 2")
      CloseGadgetList()
    EndIf

  EndProcedure
  
  ;- Init
  UseModule ScalingWindow
  
  Main1()
  AddScaleWindow(1)
  
  SetGadgetAttribute(1, #PB_Button_PressedImage, ImageID(1))
  UpdateScaleImages()
  ScaleWindow(1)
  
  Main2()
  AddScaleWindow(2)
  
  ;- Events
  
  Repeat
    Event = WaitWindowEvent()

    If Event = #PB_Event_Gadget
      
      Select EventGadget()
        Case 27
          RestoreWindow(1, #True)
        Case 28
          RestoreWindow(2)
          
     EndSelect
   ElseIf Event = #PB_Event_SizeWindow
     ScaleWindow(EventWindow())
     
   EndIf
    
  Until Event = #PB_Event_CloseWindow
    
CompilerEndIf
FF :wink:

P.S. OS Window, Linux

Update v1.02
- Etwas aufgeräumt

Update v1.03
- Scalliert Images

Re: Modul: Scaling Window

Verfasst: 14.04.2014 16:55
von NicTheQuick
Gibt es eigentlich irgendwo eine Liste dieser ganzen internen PB-Funktionen wie z.B. "PB_Object_EnumerateAll"? Ihr nutzt immer alle irgendwie, aber ich hab bis heute keine Ahnung wie ihr überhaupt auf die gekommen seid.

Re: Modul: Scaling Window

Verfasst: 14.04.2014 17:06
von ts-soft
@NicTheQuick
Befindet sich im SDK (der Windows Version :mrgreen: ). Z. Bleistift: SDK\Object\Object.h
Darf lt. Lizens aber hier nicht veröffentlicht werden, jedenfalls nicht ohne Einwilligung von FS.

Re: Modul: Scaling Window

Verfasst: 14.04.2014 17:09
von mk-soft
Für Linux sieht es schlechter aus. Da habe ich nur noch eine SDK in der Version 4.0x gefunden. :cry:

:allright:

Re: Modul: Scaling Window

Verfasst: 22.04.2014 17:55
von mk-soft
Update v1.03
- Add: Automatische skallierung von Images

FF :wink:

Re: Modul: Scaling Window

Verfasst: 22.04.2014 20:27
von mk-soft
Updade v1.04
-Bufix: Skalliert jetzt die Images in abhängikeit von der Bildgrösse

-Added: UpdateScaleImages(): Aktualliert die gespeicherten Handles von den Images.

FF :wink:

Re: Modul: Scaling Window

Verfasst: 22.04.2014 21:10
von Andesdaf
erstmal danke für's Teilen. :allright:

Schön wäre, wenn man noch Elemente als 'fest' deklarieren könnte
(man will ja nicht unbedingt den Button immer riesiger ziehen) und wenn
der Abstand zwischen den Gadgets nicht größer werden würde.

Re: Modul: Scaling Window

Verfasst: 22.04.2014 22:11
von mk-soft
Danke :wink:

Für fest Elemente gibt´s "ResizeWindowModule.pbi" von Thorsten : http://www.purebasic.fr/german/viewtopi ... =8&t=27664