Gadgeterstellung und Resize vereinfachen

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
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

Gadgeterstellung und Resize vereinfachen

Beitrag von Tommy »

Hallöchen an Alle
Was mich immer stört ist immer die doppelte Schreibarbeit beim erstellen des Gadgetcode
und beim ResizeGadget. Man erstellt ein Gadget und wenn es an Fenstergröß angepasst werden soll
muss man wieder eine weitere Zeile schreiben.

Code: Alles auswählen

Define e
OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
EditorGadget(0, 5, 5, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 5, 0)
EditorGadget(1, 5, (WindowHeight(0) / 2) + 5, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 10, 0)
Repeat
  e = WaitWindowEvent()
  If e = #PB_Event_SizeWindow
    ResizeGadget(0, 5, 5, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 5)
    ResizeGadget(1, 5, (WindowHeight(0) / 2) + 5, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 10)
  EndIf
Until e = #PB_Event_CloseWindow
Man sieht sowohl den Create als auch den Resize Code aber schön ist was anderes weil doppelte Schreibarbeit.
Warum fasst man es nicht zusammen und sagt ich will ein Gadget und soll an der Größe angepasst werden ohne zwei Zeilen schreiben zu müssen?
Müsste irgendwie gehen. Habs versucht und habs geschaft. Ich finde es so viel einfacher und spart zukünftig Schreibarbeit.

Code: Alles auswählen

EnableExplicit
Define Event
Define Editor3

Procedure _CreateResizeGadget(Type$, Gadget, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P1$, P2$, P3$, P4$, P5$)
  Protected GadgetNr, GadgetAnyNr, IsGadgetNr
  
  If Gadget > 100000
    GadgetNr = #PB_Any
    GadgetAnyNr = PeekI(Gadget)
    IsGadgetNr = PeekI(Gadget)
  Else
    GadgetNr = Gadget
    IsGadgetNr = Gadget
  EndIf
  If IsGadget(IsGadgetNr)=0
    Select Type$
      Case "ButtonGadget" : GadgetAnyNr = ButtonGadget (GadgetNr, P1, P2, P3, P4, P1$, P6)
      Case "CanvasGadget" : GadgetAnyNr = CanvasGadget (GadgetNr, P1, P2, P3, P4, P6)
      Case "ContainerGadget" : GadgetAnyNr = ContainerGadget (GadgetNr, P1, P2, P3, P4, P6)
      Case "ExplorerComboGadget" : GadgetAnyNr = ExplorerComboGadget(GadgetNr, P1, P2, P3, P4, P1$, P6)
      Case "FrameGadget" : GadgetAnyNr = FrameGadget (GadgetNr, P1, P2, P3, P4, P1$, P6)
      Case "ImageGadget" : GadgetAnyNr = ImageGadget (GadgetNr, P1, P2, P3, P4, P5, P6)
      Case "MDIGadget" : GadgetAnyNr = MDIGadget (GadgetNr, P1, P2, P3, P4, P5, P6, P7)
      Case "PanelGadget" : GadgetAnyNr = PanelGadget (GadgetNr, P1, P2, P3, P4)
      Case "ScrollBarGadget" : GadgetAnyNr = ScrollBarGadget (GadgetNr, P1, P2, P3, P4, P5, P6, P7, P8)
      Case "SplitterGadget" : GadgetAnyNr = SplitterGadget (GadgetNr, P1, P2, P3, P4, P5, P6, P7)
      Case "TrackBarGadget" : GadgetAnyNr = TrackBarGadget (GadgetNr, P1, P2, P3, P4, P5, P6, P7)
      Case "ButtonImageGadget" : GadgetAnyNr = ButtonImageGadget (GadgetNr, P1, P2, P3, P4, P5, P6)
      Case "CheckBoxGadget" : GadgetAnyNr = CheckBoxGadget (GadgetNr, P1, P2, P3, P4, P1$, P5)
      Case "DateGadget" : GadgetAnyNr = DateGadget (GadgetNr, P1, P2, P3, P4, P1$, P5, P6)
        ;... soon
      Case "EditorGadget" : GadgetAnyNr = EditorGadget (GadgetNr, P1, P2, P3, P4, P6)
    EndSelect
  EndIf
  If Gadget > 100000
    PokeI(Gadget, GadgetAnyNr)
    ResizeGadget(PeekI(Gadget), P1, P2, P3, P4)
  Else
    ResizeGadget(Gadget, P1, P2, P3, P4)
  EndIf
EndProcedure

Define _, _G, _X, _Y, _W, _H, _T, _F

Macro ButtonGadget(_G, _X, _Y, _W, _H, _T, _F=0) : _CreateResizeGadget("ButtonGadget", _G, _X, _Y, _W, _H, _F, 0, 0, 0, 0, 0, _T, "", "", "", "") : EndMacro
Macro CanvasGadget(_G, _X, _Y, _W, _H, _F=0) : _CreateResizeGadget("CanvasGadget", _G, _X, _Y, _W, _H, _F, 0, 0, 0, 0, 0, "", "", "", "", "") : EndMacro
;... soon
Macro EditorGadget(_G, _X, _Y, _W, _H, _F=0) : _CreateResizeGadget("EditorGadget", _G, _X, _Y, _W, _H, _F, 0, 0, 0, 0, 0, "", "", "", "", "") : EndMacro

OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_Repaint Or Event = #PB_Event_SizeWindow
    EditorGadget(25, 5, 5, WindowWidth(0) - 10, WindowHeight(0) / 2, 0)
    EditorGadget(50, 5, (WindowHeight(0) / 2) + 10, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 35, 0)
    ButtonGadget(@Editor3, WindowWidth(0) - 100, WindowHeight(0) - 20, 95, 15, "MyButton", 0)
  EndIf
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case Editor3
        Debug "Es geht"
    EndSelect
  EndIf
Until Event = #PB_Event_CloseWindow
Wie man gut sehen kann schreibt man nur eine Zeile für beide Varianten sowohl Create als auch Resize.
Diese Lösung finde ich echt super gut und möchte es mit euch teilen.
Zuletzt geändert von Tommy am 27.01.2015 12:30, insgesamt 9-mal geändert.
PB 5.41 x64
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: Gadgeterstellung und Resize vereinfachen

Beitrag von NicTheQuick »

Das ist eine super Idee. Ich habe mich auch schon öfter daran gestört, dass man das ganze zweimal schreiben muss.
Deswegen hatte ich bisher einfach beim Initialisieren den Gadgets die Koordinaten 0, 0 und Größe 1, 1 gegeben. Und danach eben die ResizeProcedure angestoßen. Angelehnt an dein Beispiel sah es bei mir also so aus:

Code: Alles auswählen

Define e

Procedure ResizeGadgets()
	ResizeGadget(0, 5, 5, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 5)
	ResizeGadget(1, 5, (WindowHeight(0) / 2) + 5, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 10)
EndProcedure

OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)

EditorGadget(0, 0, 0, 1, 1, 0)
EditorGadget(1, 0, 0, 1, 1, 0)
; keine Gadgetliste erforderlich

Repeat
	e = WaitWindowEvent()
	If e = #PB_Event_SizeWindow Or e = #PB_Event_Repaint
		; wird nur einmal geschrieben
		ResizeGadgets()
	EndIf
Until e = #PB_Event_CloseWindow
Jetzt kann man sich wahrscheinlich darüber streiten, was schlauer ist. Mir persönlich gefällt deine Variante gerade besser, aber sie hat für mich noch einen Nachteil. Vielleicht kannst du den noch ausbessern. Und zwar kann man nicht so einfach mit #PB_Any arbeiten. Hast du schon eine Idee, wie du das einbauen könntest?
Bild
Andesdaf
Moderator
Beiträge: 2660
Registriert: 15.06.2008 18:22
Wohnort: Dresden

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von Andesdaf »

Wer komplexere Oberflächen hat und sich das Berechnen von Koordinaten, Breiten und Höhen
ersparen möchte, dem kann ich die Funktionen der Dialog-Log von PureBasic empfehlen,
insbesondere CreateXMLDialog: http://www.purebasic.com/german/documen ... ialog.html

Ist zwar erst einmal gewöhnungsbedürftig (man muss Runtime nutzen, nicht alle Gadget-Flags werden unterstützt),
dafür geht das Schreiben einer Oberfläche sehr schnell von der Hand, wenn man einmal sein System gefunden hat.
Resizing geht ganz automatisch, beim nachträglichen Hinzufügen von Gadgets wird die Anordnung von allein zurechtgerückt
und man erledigt Definition und Positionierung in einem Rutsch.

Ich nutze die Dialog-Funktionen selbst bei einem sehr oberflächenintensiven Programm und bin sehr zufrieden hinsichtlich
des Wartungsaufwandes, der früher immer Stunden verschlugen hat.
Win11 x64 | PB 6.00 (x64)
Benutzeravatar
Vera
Beiträge: 928
Registriert: 18.03.2009 14:47
Computerausstattung: Win XP SP2, Suse 11.1
Wohnort: Essen

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von Vera »

[ot]
geklärt
[/ot]
Zuletzt geändert von Vera am 20.01.2015 18:50, insgesamt 2-mal geändert.
°
<°)))o><
~~~~~~~~~
echo "Don't worry"
echo "Keep quiet"
@echo off
format forum:\
Benutzeravatar
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von Tommy »

@NicTheQuick
Vielen Dank, freut mich dass es dir auch gefällt. Endlich mach ich was richtig. :D
Den Ausschlusstext für walbus habe ich entfernt.
Ich habe eine Version mit #PB_Any erstellt:

Code: Alles auswählen

Define e
Define Editor3

Procedure EditorGadget2(Gadget, x, y, Width, Height, Flags)
  ProcedureReturn EditorGadget(Gadget, x, y, Width, Height, Flags)
EndProcedure

Macro EditorGadget(Gadget, x, y, Width, Height, Flags = 0, IsResizable = 0)
  If IsGadget(Gadget) = 0
    If Gadget > 100000
      PokeI(Gadget, EditorGadget2(#PB_Any, x, y, Width, Height, Flags))
    Else
      EditorGadget2(Gadget, x, y, Width, Height, Flags)
    EndIf
  EndIf
  If IsResizable
    If Gadget > 100000
      ResizeGadget(PeekI(Gadget), x, y, Width, Height)
    Else
      ResizeGadget(Gadget, x, y, Width, Height)
    EndIf
  EndIf
EndMacro

OpenWindow(0, 0, 0, 800, 600, "", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
Repeat
  e = WaitWindowEvent()
  If e = #PB_Event_SizeWindow Or e = #PB_Event_Repaint
    ; wird nur einmal geschrieben
    EditorGadget(25, 5, 5, WindowWidth(0) - 10, WindowHeight(0) / 2, 0, 1)
    EditorGadget(50, 5, (WindowHeight(0) / 2) + 10, WindowWidth(0) - 10, (WindowHeight(0) / 2) - 35, 0, 1)
    EditorGadget(@Editor3, WindowWidth(0) - 100, WindowHeight(0) - 20, 95, 15, 0, 1)
  EndIf
  If e = #PB_Event_Gadget
    Select EventGadget()
      Case Editor3
        Debug "Es geht"
    EndSelect
  EndIf
Until e = #PB_Event_CloseWindow
Zwei Sachen von mir finde ich schrecklich gelöst:
1. If Gadget > 100000
Das mache ich nur um festzustellen ob es eine Nummer oder eine Speicheraddresse is. Wie kann man besser prüfen?
2. Aktuell kann man nur Editorgadget veränderbar erstellen. Ich müsste so umbauen das es automatisch mit allen Gadgets geht.
Zuletzt geändert von Tommy am 27.01.2015 12:28, insgesamt 2-mal geändert.
PB 5.41 x64
Benutzeravatar
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von Tommy »

Im Code war ein Bug. Behoben:

Code: Alles auswählen

;siehe oben
Zuletzt geändert von Tommy am 27.01.2015 12:27, insgesamt 3-mal geändert.
PB 5.41 x64
Benutzeravatar
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von Tommy »

Ich habe mein Code komplet überarbeitet und ist jetzt viel besser strukturiert und einheitlicher:

Code: Alles auswählen

;siehe oben
Wie findet ihr den Code? Könt ihr schauen ob es okay is?
Zuletzt geändert von Tommy am 27.01.2015 12:26, insgesamt 3-mal geändert.
PB 5.41 x64
GronkhLP
Beiträge: 72
Registriert: 14.11.2013 22:43
Wohnort: Köln
Kontaktdaten:

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von GronkhLP »

Danke fürs Teilen :)
Der von dir geschriebene Quellcode sieht übersichtlich aus und beim kurzen Testen funktioniert es ganz gut. ;) Ich finde deine Idee auch hervorragend und den Code würde ich sogar zukünftig in meinen Projekten mit größenveränderbaren Fenstern verwenden.
Ich versuche in meinen Projekten auch, Teile des Codes zu automatisieren. Es müssen nur noch die restlichen Controls hinzugefügt werden, damit man diese ebenfalls ansprechen kann wie es beim EditorGadget und ButtonGadget der Fall ist. ;)
Noch ein Tipp: Aktualisiere den Code im ersten Beitrag von dir, damit die Leute nicht runterscrollen müssen, um den Code zu entnehmen.
Bild
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: Gadgeterstellung und Resize vereinfachen

Beitrag von NicTheQuick »

:allright:

Trotzdem noch zwei Dinge:
- Das MDIGadget gibt es unter Linux nicht. Das müsstest du also mit einem CompilerIf ausklammern.
- Statt der Strings würde ich eher auf eine Enumeration setzen oder falls dir das zu global ist, einfach hartkodierte Zahlen nutzen. Es ist immer von Vorteil, wenn man Strings nicht nutzen muss. Die sind nämlich langsam. ;)
Bild
Benutzeravatar
Tommy
Spassvogel
Beiträge: 319
Registriert: 17.10.2013 14:36

Re: Gadgeterstellung und Resize vereinfachen

Beitrag von Tommy »

Freut mich zu hören
@NicTheQuick
MDI klammere ich später aus.
Und die Strings hm ich habe eine einheitliche Prozedur geschrieben für alle Übergabeparameter, 10x Ganzzahlen-Parameter und 5x String-Parameter
Bei ButtonGadget gibt es 6x Zahlparameter und 1x Textparameter. Die anderen sind Platzhalter für andere Gadgets. Weißt du was ich meine?
Ich könnte oben in der Prozedur P1$ = "" machen dann muss man unten im Macro kein "" angeben also so ungefähr:

Code: Alles auswählen

Procedure _CreateResizeGadget(Type$, Gadget, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P1$="", P2$="", P3$="", P4$="", P5$="")
;...
EndProcedure
;...
Macro ButtonGadget(_G, _X, _Y, _W, _H, _T, _F=0) : _CreateResizeGadget("ButtonGadget", _G, _X, _Y, _W, _H, _F, 0, 0, 0, 0, 0, _T) : EndMacro
Macro CanvasGadget(_G, _X, _Y, _W, _H, _F=0) : _CreateResizeGadget("CanvasGadget", _G, _X, _Y, _W, _H, _F, 0, 0, 0, 0, 0) : EndMacro
Zuletzt geändert von Tommy am 27.01.2015 12:26, insgesamt 2-mal geändert.
PB 5.41 x64
Antworten