Seite 1 von 2

Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 12:27
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.

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 13:24
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?

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 13:44
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.

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 14:17
von Vera
[ot]
geklärt
[/ot]

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 14:21
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.

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 14:31
von Tommy
Im Code war ein Bug. Behoben:

Code: Alles auswählen

;siehe oben

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 17:35
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?

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 17:52
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.

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 17:56
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. ;)

Re: Gadgeterstellung und Resize vereinfachen

Verfasst: 20.01.2015 18:07
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