Modul: Scaling Window

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Modul: Scaling Window

Beitrag 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
Zuletzt geändert von mk-soft am 22.04.2014 20:23, insgesamt 2-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8679
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 32 GB DDR4-3200
Ubuntu 22.04.3 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken
Kontaktdaten:

Re: Modul: Scaling Window

Beitrag 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.
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Modul: Scaling Window

Beitrag 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.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul: Scaling Window

Beitrag 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:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul: Scaling Window

Beitrag von mk-soft »

Update v1.03
- Add: Automatische skallierung von Images

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul: Scaling Window

Beitrag 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:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Andesdaf
Moderator
Beiträge: 2660
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Modul: Scaling Window

Beitrag 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.
Win11 x64 | PB 6.00 (x64)
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul: Scaling Window

Beitrag von mk-soft »

Danke :wink:

Für fest Elemente gibt´s "ResizeWindowModule.pbi" von Thorsten : http://www.purebasic.fr/german/viewtopi ... =8&t=27664
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten