FixWindow - Fenster an andere "anhängen"

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
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

FixWindow - Fenster an andere "anhängen"

Beitrag von STARGÅTE »

Tachchen,

weil ich es selber gerade brauchte, hier ein kleiner Code der das anhängen und abhängen von Fenstern vereinfachen soll.
FixWindow(Window, ParentWindow)
'Window' wird an das 'ParentWindow' angeheftet.
Bewegt man das 'ParentWindow', bewegt sich das 'Window' mit.
Bewegt man das 'Window', verändert man deren Position.

Man kann auch mehre "Level" beim andocken nutzen.

Was noch nicht geht, ist gegenseitigen Andocken, würde eine Event-Schleife verursachen :|

PB 4.40 Nötig !

Code: Alles auswählen


Structure FixWindow
  Window.i
  ParentWindow.i
  x.i : y.i
EndStructure

Global NewMap FixWindowMap.FixWindow()

Procedure FixWindowCallback(WindowID.i, Message.i, wParam.i, lParam.i)
  Protected Key$ = Hex(WindowID)
  Select Message
    Case #WM_MOVE, #WM_SIZE
      If FindMapElement(FixWindowMap(), Key$)
        With FixWindowMap()
          \x = WindowX(\Window) - WindowX(\ParentWindow)
          \y = WindowY(\Window) - WindowY(\ParentWindow)
        EndWith
      EndIf
      NewList Test.FixWindow()
      ForEach FixWindowMap() : With FixWindowMap()
        If WindowID = WindowID(\ParentWindow)
          AddElement(Test())
          Test()\x = WindowX(\ParentWindow)+\x
          Test()\y = WindowY(\ParentWindow)+\y
          Test()\Window = \Window
        EndIf
      EndWith : Next
      ForEach Test()
        ResizeWindow(Test()\Window, Test()\x, Test()\y, #PB_Ignore, #PB_Ignore)
      Next
  EndSelect
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure


Procedure FixWindow(Window, ParentWindow)
  AddMapElement(FixWindowMap(), Hex(WindowID(Window)))
  With FixWindowMap(Hex(WindowID(Window)))
    \Window = Window
    \ParentWindow = ParentWindow
    \x = WindowX(Window) - WindowX(ParentWindow)
    \y = WindowY(Window) - WindowY(ParentWindow)
  EndWith
EndProcedure


Procedure UnfixWindow(Window)
  DeleteMapElement(FixWindowMap(), Hex(WindowID(Window)))
EndProcedure


Enumeration
  #Window0
  #Window1
  #Window2
  #Window3
  #Window4
  #Window5
  #Gadget
EndEnumeration


SetWindowCallback(@FixWindowCallback())




; Beispiel
;----------



OpenWindow(#Window1, 300, 200, 400, 300, "Main", #PB_Window_MinimizeGadget)

OpenWindow(#Window2, 750, 200, 200, 300, "Child 1", #PB_Window_SystemMenu, WindowID(#Window1))
OpenWindow(#Window3, 50, 200, 200, 300, "Child 2", #PB_Window_SystemMenu|#PB_Window_MinimizeGadget, WindowID(#Window1))
  ButtonGadget(#Gadget, 10, 10, 180, 20, "Ans Main angeheftet", #PB_Button_Toggle)
  SetGadgetState(#Gadget, 1)
  
OpenWindow(#Window4, 50, 550, 200, 100, "SubChild 1.1", #PB_Window_Tool|#PB_Window_SystemMenu, WindowID(#Window3))
OpenWindow(#Window5, 50, 50, 200, 100, "SubChild 1.2", #PB_Window_Tool|#PB_Window_SystemMenu, WindowID(#Window3))


FixWindow(#Window2, #Window1)
FixWindow(#Window3, #Window1)

FixWindow(#Window4, #Window3)
FixWindow(#Window5, #Window3)

Repeat

 Event = WaitWindowEvent()
 
 Select Event
   Case #PB_Event_CloseWindow
     End
   Case #PB_Event_Gadget
     Select EventGadget()
       Case #Gadget
         If GetGadgetState(#Gadget)
           FixWindow(#Window3, #Window1)
         Else
           UnfixWindow(#Window3)
         EndIf
     EndSelect 
 EndSelect

ForEver
Bewegt man das Main, bewegen sich alle Childs mit. Die Position der Child kann aber auch verändert werden.
Die SubChilds sind an Child2 gebunden, werden aber auch durch bewegen des Mains mitgenommen.

Idee für später:
- Intelligentes anheften: Wird ein Fenster rechts angeheftet, und das Main in der größe verändert, soll sich das Fenster auch mit bewegen.
- gegenseitiges Koppeln.
- richtiges Andocken bei weniger als 16px zum Rand.
Zuletzt geändert von STARGÅTE am 30.05.2010 20:21, insgesamt 1-mal geändert.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
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: FixWindow - Fenster an andere "anhängen"

Beitrag von ts-soft »

:allright:
Sehr nützlich
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
NicTheQuick
Ein Admin
Beiträge: 8675
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: FixWindow - Fenster an andere "anhängen"

Beitrag von NicTheQuick »

Wird Zeit, dass ich mich mehr mit der GDK auseinander setze. Dann könnte ich solch nützliche Windows-Codes auch für Linux portieren.

@Stargate:
Kannst du zu deinen Codes auch immer dabei schreiben, mit welcher PB-Version und mit welchem Betriebssystem sie laufen? Das wäre für später interessant, wenn mal jemand deinen Code durch eine Suche findet.
Bild
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: FixWindow - Fenster an andere "anhängen"

Beitrag von Josh »

is ja cool :allright:

aber wäre es nicht sinnvoll, dass das main nicht geschlossen wird, wenn ein child oder subchild zugemacht wird? dann natürlich auch, dass das child bestehen bleibt, wenn das subchild zugemacht wird.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: FixWindow - Fenster an andere "anhängen"

Beitrag von STARGÅTE »

jo klar, das hat aber weniger mit meinem Code zu tun, sonden mehr mit der Eventschleife in der Main.
Dort muss man "halt selber" noch das Window abfragen. das hat aber weniger mit dem Anheften zu tun.

aber du hast recht, ich muss natürlich noch abfragen ob das Fenster überhaupt noch existiert, wenn man es schließt, sonst ist ja der Callback fehlerhaft.

@NicTheQuick
JO wäre cool, leider weiß ich nicht ob #WM_MOVE, #WM_SIZE bei "euch" existieren.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
DarkDragon
Beiträge: 6267
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: FixWindow - Fenster an andere "anhängen"

Beitrag von DarkDragon »

@NicTheQuick:
*Display = XOpenDisplay(0), XMoveResizeWindow(*Display, Window.i, X.i, Y.i, Width.i, Height.i) und gdk_x11_drawable_get_xid(gtk_widget_get_toplevel(WindowID(#Window))) sollte genügen.
Aber Achtung: Nicht alle GtkWidgets sind derart kombinierbar mit GDK. GDK ist eigentlich nur ein Xlib wrapper. Ich hab mich letztens aber damit beschäftigt und das mit gdk_x11_drawable_get_xid(gtk_widget_get_toplevel()) funktionierte recht gut. Nur mit Child-Widgets kannst du damit garnichts anfangen, denn die sind alle "Owner-Drawn" Widgets. Desshalb der Aufruf von gtk_widget_get_toplevel.
Wenn du ganz auf GDK verzichten willst solltest du dir noch xwininfo ansehen.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Andesdaf
Moderator
Beiträge: 2658
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: FixWindow - Fenster an andere "anhängen"

Beitrag von Andesdaf »

Danke! :allright: :allright:
Win11 x64 | PB 6.00 (x64)
Antworten