Advanced: Diesmal: Table-/Gadget-Aligment wie Tabellen

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.
ShadowTurtle
Beiträge: 114
Registriert: 11.09.2004 07:58
Wohnort: Mannheim
Kontaktdaten:

Advanced: Diesmal: Table-/Gadget-Aligment wie Tabellen

Beitrag von ShadowTurtle »

Hallo Ihr da draußen!

Auch diese Woche gibt es wieder eine kleine Library die Ihr benutzen könnt. Allerdings nicht um es mit seinen eigenen Namen auszustellen. Nicht wahr, Hroudtwolf?

Ziel war es eine Library zu entwickeln welches das setzen von Gadgets vereinfacht.

* Diese Library kann mit mehreren Instanzen arbeiten. Es kann also dort fortsetzen wo man irgendwann mal aufgehört hatte. z.B. für eine Realisierung einer "Tabelle" in einer "Tabelle". Oder auch eines Formulars in einem Formular.

* Diese Library gibt nur die Koordinaten zurück. Es ist also nicht auf Gadgets beschränkt. Will man also z.B. ganz schnell einfach eine Highscore-Liste Realisieren, dann ist diese Library dafür gut geeignet.

* Es gibt Vier globale Variablen. AdvAlg_XA , AdvAlg_YA und die selbigen mit einen B am ende ( AdvAlg_XB , AdvAlg_YB ). A = Startkoordinaten , B = Längenkoordinaten.

* Man kann Margin- und Padding- (allerdings nur in der Breite) Werte angeben. Diese wirken sich genau so aus wie in HTML. Nur das bei Padding die Zelle nicht in die länge gezogen wird (wie z.B. bei Firefox/IE7/... ), sondern bleibt gleich. Wobei man mit Margin den Außenrahmen verändern kann ist. Bei beiden gilt: Es wirkt sich nur auf die Breite aus.

* Man kann auch die einzelne Zeile-Höhe einstellen. Dies Funktioniert mit AdvAlign_SetLineHeight(LineHeight.l) . Bitte nicht nicht mit der höhe verwechseln! Dafür gibt es gesonderte Befehle.

* Mit AdvAlign_Height(Height.l) kann man die höhe einstellen welche für die momentane Zeile insgesamt benutzt werden soll.

* In zusammenspiel mit der Rückgaben-Funktion AdvAlign_RestHeight() kann man die Restgröße passend zurückgeben lassen. Warum? So wird es ganz leicht z.B. ein zusätzliches Eingabefeld einzubauen ohne gleich die Koordinaten der weiterfolgenden Gadgets nochmals abändern zu müssen.

Wie Ihr seht, diese Library hält sich an die erste Klassen-Instanz zur Tabellen-Verwaltung des Internet Explorers 7.0.


Es folgt nun (wie immer) zuerst das Beispiel. Danach kommt der Quellcode zur Library. Möchte man in diesen Beispiel nun noch z.B. ein Eingabefeld (ComboBox oder sonst was) hinzubauen, dann muss man nur folgenden Code benutzen:

Code: Alles auswählen

      TextGadget(#PB_Any, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "Stichworte:") : AdvAlign_NextPosition()
      StringGadget(#NodeWordsInput, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "") : AdvAlign_NextPosition()
Wobei AdvAlign_NextPosition() niemals vergessen werden darf, da sonst keine Position weiter "gesprungen" wird. Ich hätte gerne zwar ein einfacheres Beispiel gezeigt, aber dann hätte man nicht die Hauptfunktionalitäten dieser Library zeigen können. Deshalb sollte man also etwas aufpassen wenn man nun noch z.B. ein Eingabefeld (ComboBox oder sonst was) hinzubauen will:

Das letzte Eingabefeld, welches im Beispiel erstellt wird, enthält nach dem Funktionsaufruf von StringGadget( ... ) kein AdvAlign_NextPosition() da diese erst später aufgerufen wird (siehe weiter unten im Quellcode). Deshalb sollte man nicht vergessen hinter dem letzten StringGadget( ... ) noch die Funktion AdvAlign_NextPosition() einzubauen, bevor man ein neues Gadget auf diese weise erstellt.


Dieser Programmierstil der Koordinaten-Verwaltung hilft übrigens auch beim Automatischen Skalieren wenn z.B. die Größe des Fensters verändert wurde: Einfach den Code zur Fenster-Erstellung Kopieren und (in diesem fall) die StringGadgets entsprechend durch ResizeGadget austauschen.

Code: Alles auswählen

; AdvancedAlign_Sample.pb V1.0
; by ShadowTurtle @ Sonntag, 24. Juni 2007
;XIncludeFile("AdvancedAlign.pb")

Enumeration
  #Window
  #Panel
  
  #TitleInput
  #DescriptionInput
  #NodeWordsInput
  #ContentInput
EndEnumeration

#Win_BeginWidth = 300
#Win_BeginHeight = 300

OpenWindow(#Window, 10, 10, #Win_BeginWidth, #Win_BeginHeight, "AdvancedAlign Sample 1", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CreateGadgetList(WindowID(#Window))

PanelGadget(#Panel, 0, 0, #Win_BeginWidth, #Win_BeginHeight)
  AddGadgetItem(#Panel, -1, "Standard")
    *MyAlign = AdvAlign_CreateInstance()
      AdvAlign_Begin(3, 3, 20)
      AdvAlign_AddWidth(100, 0, 2)
      AdvAlign_AddWidth( WindowWidth(#Window) - 108 , 0, 2)
      TextGadget(#PB_Any, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "Titel:") : AdvAlign_NextPosition()
      StringGadget(#TitleInput, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "") : AdvAlign_NextPosition()
      TextGadget(#PB_Any, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "Beschreibung:") : AdvAlign_NextPosition()
      StringGadget(#DescriptionInput, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "") : AdvAlign_NextPosition()
      TextGadget(#PB_Any, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "Stichworte:") : AdvAlign_NextPosition()
      StringGadget(#NodeWordsInput, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB, "")
      AdvAlign_RemoveWidths()
      AdvAlign_AddWidth( WindowWidth(#Window) - 8 , 0, 2)
      AdvAlign_Height( WindowHeight(#Window) - 50 )
      AdvAlign_Height( AdvAlign_RestHeight() )
      AdvAlign_NextPosition()
      EditorGadget(#ContentInput, AdvAlg_XA, AdvAlg_YA, AdvAlg_XB, AdvAlg_YB)
    AdvAlign_RemoveInstance( *MyAlign )
CloseGadgetList()

Repeat
  Event = WaitWindowEvent()
  WindowID = EventWindow()
  GadgetID = EventGadget()
  EventType = EventType()
Until Event = #PB_Event_CloseWindow

Code: Alles auswählen

; AdvancedAlign.pb V1.0
; by ShadowTurtle @ Sonntag, 24. Juni 2007
; 
; * Diese Library kann mit mehreren Instanzen arbeiten. Es kann also dort fortsetzen
; wo man irgendwann mal aufgehört hatte. z.b. für eine Realisierung einer "Tabelle"
; in einer "Tabelle". Oder auch eines Formulars in einem Formular.
; 
; * Diese Library gibt nur die Koordinaten zurück. Es ist also nicht auf Gadgets
; beschränkt. Will man also z.b. ganz schnell einfach eine Highscore-Liste
; Realisieren, dann ist Diese Library dafür gut geeignet.
; 
; * Es gibt Vier globale Variablen. AdvAlg_XA , AdvAlg_YA und die selbigen mit
; einen B am ende ( AdvAlg_XB , AdvAlg_YB ). A = Startkoordinaten , B = Längenkoord-
; inaten.
; 
; * man kann Margin- und Padding- (allerdings nur in der Breite) Werte angeben.
; Diese wirken sich genau so aus wie in HTML. nur das bei Padding die Zelle nicht in
; die Länge gezogen wird (wie z.b. bei Firefox/IE7/... ), sondern bleibt gleich.
; Wobei man mit Margin den Außenrahmen verändern kann ist. bei beiden gilt: Es wirkt
; sich nur auf die Breite aus.
; 
; * man kann auch die einzelne Zeile-Höhe einstellen. Dies Funktioniert mit
; AdvAlign_SetLineHeight(LineHeight.l) . Bitte nicht nicht mit der Höhe
; verwechseln! dafür gibt Es gesonderte Befehle.
; 
; * mit AdvAlign_Height(Height.l) kann man die Höhe einstellen welche für die
; momentane Zeile insgesamt benutzt werden soll.
; 
; * in zusammenspiel mit der rückgaben-Funktion AdvAlign_RestHeight() kann man die
; Restgröße passend zurückgeben lassen. Warum? so wird Es ganz leicht z.b. ein
; zusätzliches Eingabefeld einzubauen ohne gleich die Koordinaten der weiterfolgenden
; Gadgets nochmals abändern zu müssen.

Global AdvAlg_XA
Global AdvAlg_YA
Global AdvAlg_XB
Global AdvAlg_YB

Structure AdvAlign_Instance
  AdvAlign_Top.l
  AdvAlign_Left.l
  AdvAlign_AddedHeights.l
  AdvAlign_LineHeight.l
  AdvAlign_AddLineHeight.l
  AdvAlign_NewLineHeight.l
  AdvAlign_LineSpace.l
  
  AdvAlign_Width.l[21]
  AdvAlign_WidthMargin.l[21]
  AdvAlign_WidthPadding.l[21]
  
  AdvAlign_Height.l
  
  AdvAlign_CountWidths.l
  AdvAlign_WorkWidth.l
  AdvAlign_FirstWidth.l
  
  AdvAlg_XA_.l
  AdvAlg_YA_.l
  AdvAlg_XB_.l
  AdvAlg_YB_.l
  
  AdvAlg_XA.l
  AdvAlg_YA.l
  AdvAlg_XB.l
  AdvAlg_YB.l
EndStructure
Global *AdvAlign_ActInst
*AdvAlign_ActInst = 0

Procedure AdvAlign_CreateInstance()
  *AlIn.AdvAlign_Instance = AllocateMemory(SizeOf(AdvAlign_Instance))
  *AdvAlign_ActInst = *AlIn
  ProcedureReturn( *AlIn )
EndProcedure

Procedure AdvAlign_SetInstance( *AdvAlign_Instance )
  *AdvAlign_ActInst = *AdvAlign_Instance
EndProcedure

Procedure AdvAlign_RemoveInstance( *AdvAlign_Instance )
  FreeMemory( *AdvAlign_Instance )
EndProcedure

Procedure AdvAlign_SetNewPosition()
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst

  MarginRight = *AcIn\AdvAlign_WidthMargin[AdvAlign_WorkWidth];0
  MarginLeft = *AcIn\AdvAlign_WidthMargin[AdvAlign_WorkWidth];0
  
  PaddingLeft = *AcIn\AdvAlign_WidthPadding[AdvAlign_WorkWidth];5
  PaddingRight = *AcIn\AdvAlign_WidthPadding[AdvAlign_WorkWidth];5
  
  *AcIn\AdvAlg_XA = 0
  *AcIn\AdvAlg_YA = 0
  *AcIn\AdvAlg_XB = 0
  *AcIn\AdvAlg_YB = 0

  *AcIn\AdvAlg_XA = *AcIn\AdvAlg_XA + *AcIn\AdvAlg_XA_
  *AcIn\AdvAlg_YA = *AcIn\AdvAlg_YA + *AcIn\AdvAlg_YA_
  *AcIn\AdvAlg_XB = *AcIn\AdvAlg_XB + *AcIn\AdvAlg_XB_
  *AcIn\AdvAlg_YB = *AcIn\AdvAlg_YB + *AcIn\AdvAlg_YB_
  
  *AcIn\AdvAlg_XA = *AcIn\AdvAlg_XA + MarginRight * *AcIn\AdvAlign_WorkWidth + MarginLeft*(*AcIn\AdvAlign_WorkWidth+1)
  *AcIn\AdvAlg_XA = *AcIn\AdvAlg_XA + PaddingLeft
  *AcIn\AdvAlg_XB = *AcIn\AdvAlg_XB - PaddingRight - PaddingLeft
  
  AdvAlg_XA = *AcIn\AdvAlg_XA
  AdvAlg_YA = *AcIn\AdvAlg_YA
  AdvAlg_XB = *AcIn\AdvAlg_XB
  AdvAlg_YB = *AcIn\AdvAlg_YB
EndProcedure

Procedure AdvAlign_Begin(top.l, left.l, LineHeight.l, LineSpace.l = 2)
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst

  *AcIn\AdvAlign_CountWidths = 0
  *AcIn\AdvAlign_Top = top.l
  *AcIn\AdvAlign_Left = left.l
  *AcIn\AdvAlign_AddedHeights = 0
  *AcIn\AdvAlign_LineHeight = LineHeight.l
  *AcIn\AdvAlign_AddLineHeight = LineHeight.l
  *AcIn\AdvAlign_NewLineHeight = -1
  *AcIn\AdvAlign_LineSpace = LineSpace.l
  *AcIn\AdvAlign_FirstWidth = #True
  
  *AcIn\AdvAlg_XA_ = *AcIn\AdvAlign_Top
  *AcIn\AdvAlg_YA_ = *AcIn\AdvAlign_Left
  *AcIn\AdvAlg_YB_ = *AcIn\AdvAlign_LineHeight
  
  *AcIn\AdvAlign_WorkWidth = 0
  
  AdvAlign_SetNewPosition()
EndProcedure

Procedure AdvAlign_RemoveWidths()
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst
  *AcIn\AdvAlign_CountWidths = 0
EndProcedure

Procedure AdvAlign_AddWidth(Width.l, WidthMargin.l = 0, WidthPadding.l = 0)
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst

  *AcIn\AdvAlign_Width[*AcIn\AdvAlign_CountWidths] = Width.l
  *AcIn\AdvAlign_WidthMargin[*AcIn\AdvAlign_CountWidths] = WidthMargin.l
  *AcIn\AdvAlign_WidthPadding[*AcIn\AdvAlign_CountWidths] = WidthPadding.l
  *AcIn\AdvAlign_CountWidths = *AcIn\AdvAlign_CountWidths + 1
  
  ;If *AcIn\AdvAlign_CountWidths = 1
;  If *AcIn\AdvAlign_FirstWidth = #True
;    *AcIn\AdvAlg_XB_ = *AcIn\AdvAlign_Width[*AcIn\AdvAlign_CountWidths - 1]
;    *AcIn\AdvAlign_FirstWidth = #False
;  EndIf
  
  If *AcIn\AdvAlign_CountWidths = 1
    WidthEntr = *AcIn\AdvAlign_CountWidths - 1
    If Not (WidthEntr > -1)
      WidthEntr = 0
    EndIf
    *AcIn\AdvAlg_XB_ = *AcIn\AdvAlign_Width[WidthEntr]
  EndIf
  
  AdvAlign_SetNewPosition()
EndProcedure

Procedure AdvAlign_Height(Height.l)
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst
  *AcIn\AdvAlign_Height = Height
EndProcedure

Procedure AdvAlign_SetLineHeight(LineHeight.l)
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst

  *AcIn\AdvAlign_LineHeight = LineHeight.l
  If LineHeight.l > *AcIn\AdvAlign_AddLineHeight
    *AcIn\AdvAlign_AddLineHeight = LineHeight.l
  EndIf
  *AcIn\AdvAlign_NewLineHeight = LineHeight.l
EndProcedure

Procedure AdvAlign_NewLine()
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst
  
  *AcIn\AdvAlign_WorkWidth = 0

  If *AcIn\AdvAlign_NewLineHeight > -1
    *AcIn\AdvAlign_LineHeight = *AcIn\AdvAlign_NewLineHeight
    *AcIn\AdvAlign_AddLineHeight = *AcIn\AdvAlign_LineHeight
    *AcIn\AdvAlign_NewLineHeight = -1
  Else
    *AcIn\AdvAlign_AddLineHeight = *AcIn\AdvAlign_LineHeight
  EndIf
  
  *AcIn\AdvAlg_YA_ = *AcIn\AdvAlg_YA_ + *AcIn\AdvAlign_AddLineHeight + *AcIn\AdvAlign_LineSpace
  *AcIn\AdvAlg_XA_ = *AcIn\AdvAlign_Left
  *AcIn\AdvAlg_YB_ = *AcIn\AdvAlign_LineHeight + *AcIn\AdvAlign_Height ;(*AcIn\AdvAlign_Height - (*AcIn\AdvAlign_AddLineHeight + *AcIn\AdvAlign_LineSpace))
  *AcIn\AdvAlg_XB_ = *AcIn\AdvAlign_Width[*AcIn\AdvAlign_WorkWidth]; - *AcIn\AdvAlign_WidthMargin[*AcIn\AdvAlign_WorkWidth]
  
  AdvAlign_SetNewPosition()
EndProcedure

Procedure AdvAlign_RestHeight()
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst
  ;ProcedureReturn( *AcIn\AdvAlign_Height - *AcIn\AdvAlign_AddedHeights - *AcIn\AdvAlg_YA_ )
  ProcedureReturn( *AcIn\AdvAlign_Height - *AcIn\AdvAlg_YA - *AcIn\AdvAlg_YB )
EndProcedure

Procedure AdvAlign_NextPosition()
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst
  
  If *AcIn\AdvAlign_WorkWidth = *AcIn\AdvAlign_CountWidths - 1
    AddSpace = 2
  Else
    AddSpace = 2
  EndIf
  
  *AcIn\AdvAlg_XA_ = *AcIn\AdvAlg_XA_ + *AcIn\AdvAlign_Width[*AcIn\AdvAlign_WorkWidth]; + *AcIn\AdvAlign_WidthMargin(*AcIn\AdvAlign_WorkWidth)*2
  *AcIn\AdvAlign_WorkWidth = *AcIn\AdvAlign_WorkWidth + 1
  
  *AcIn\AdvAlg_XB_ = *AcIn\AdvAlign_Width[*AcIn\AdvAlign_WorkWidth]
  *AcIn\AdvAlg_YB_ = *AcIn\AdvAlign_LineHeight
  
  *AcIn\AdvAlign_AddedHeights = *AcIn\AdvAlign_AddedHeights + *AcIn\AdvAlign_Height
  AdvAlign_SetNewPosition()
  
  If *AcIn\AdvAlign_WorkWidth = *AcIn\AdvAlign_CountWidths Or *AcIn\AdvAlign_CountWidths = 1
    AdvAlign_NewLine()
  EndIf
EndProcedure

Procedure AdvAlign_DebugPositions()
  *AcIn.AdvAlign_Instance = *AdvAlign_ActInst
  Debug("AdvAlign_DebugPositions -> AdvAlg_XA_ " + Str(*AcIn\AdvAlg_XA_) )
  Debug("AdvAlign_DebugPositions -> AdvAlg_YA_ " + Str(*AcIn\AdvAlg_YA_) )
  Debug("AdvAlign_DebugPositions -> AdvAlg_XB_ " + Str(*AcIn\AdvAlg_XB_) )
  Debug("AdvAlign_DebugPositions -> AdvAlg_YB_ " + Str(*AcIn\AdvAlg_YB_) )
EndProcedure
Zuletzt geändert von ShadowTurtle am 24.06.2007 12:08, insgesamt 1-mal geändert.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Advanced: Diesmal: Table-/Gadget-Aligment wie Tabellen

Beitrag von Kiffi »

Hallo ShadowTurtle,

hört sich interessant an. Leider ist der Code nicht lauffähig.

Code: Alles auswählen

If WidthEntr <0> *AcIn\AdvAlign_AddLineHeight
und da fehlt noch irgendwo ein EndIf.

Grüße ... Kiffi
a²+b²=mc²
ShadowTurtle
Beiträge: 114
Registriert: 11.09.2004 07:58
Wohnort: Mannheim
Kontaktdaten:

Beitrag von ShadowTurtle »

Es Funktioniert wieder alles, Kiffi. Irgendwie scheint das Forum If WidthEntr < 0 als If WidthEntr <0> umzuwandeln. Hat das Forum intern einen Fehlerhaften Purebasic Interpreter?

Ich habe diese Zeile nun in If Not (WidthEntr > -1) umgeschrieben. Das Forum scheint dies nun nicht mehr falsch umgewandelt zu haben. Getestet habe ich das ganze auch.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

ShadowTurtle hat geschrieben:Es Funktioniert wieder alles, Kiffi.
Sehr schön! Danke für den Code! :allright:

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Hroudtwolf
Beiträge: 1416
Registriert: 30.10.2004 23:33
Kontaktdaten:

Beitrag von Hroudtwolf »

Auch diese Woche gibt es wieder eine kleine Library die Ihr benutzen könnt. Allerdings nicht um es mit seinen eigenen Namen auszustellen. Nicht wahr, Hroudtwolf?
Muss man verstehen was du damit meinst ?
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

Nicht schlecht, könnte richtig nützlich sein für mein aktuelles Project. Danke :allright:
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Solche "Alignments" wie du sie nennst suche ich auch. Doch mir fehlt es eher an "Layouts" wie in Java. Und gerade das automatische vergrößern/verkleinern fehlt mir sehr. Ich habe mich vor kurzem mal damit beschäftigt, doch bei mir hings dann jedoch bei Paddings und Margins. Diese habe ich dann einfach weggelassen, doch das führte dazu, dass sich alle Abstände in prozentualer weise änderten und irgendwann zu klein/groß wurden (Margins und Paddings wären in Pixeln gewesen).
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.
ShadowTurtle
Beiträge: 114
Registriert: 11.09.2004 07:58
Wohnort: Mannheim
Kontaktdaten:

Beitrag von ShadowTurtle »

DarkDragon: Das Prozentuale wäre die zweite/dritte Instanz die zu Realisieren wäre.
Antworten