TabBarGadget - Tabs wie im Browser

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: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: TabBarGadget - Tabs wie im Browser

Beitrag von STARGÅTE »

NicTheQuick hat geschrieben:Erstens mal, dass man das ganze Teil als Modul nutzen kann.
Hm, bei der größe des Includes wäre es schon angemessen, aber bislang habe ich noch wenig mit Modulen gemacht ...
NicTheQuick hat geschrieben:Und dann wäre es toll, wenn es unabhängig von der WindowID wäre.
Aus vergangenen Version weißt du vllt, dass die WindowID früher nicht nötig war.
Allerdings brauche ich es nun für PostEvent(), das aktuelle leider noch kein #PB_Any bei Window akzeptiert.
Dieses PostEvent ist jedoch erforderlicht, um Updates nur einmal durchzuführen (und nicht bei jedem Set/Add).
Was du an dieser Stelle mit Callbacks meinst muss du noch mal erklären...

Solangsam bekomme ich auch immer mehr Versionen-Konflikte hinein.
Wenn ich jetzt alles auf Module umstelle,
also von "AddTabBarGadgetItem" nach "TabBarGadget::AddItem"
gibts das nächste Geschrei ^^

Damit du eine Zeitangabe von mir hast:
Ich werden in den nächsten Wochen keine Updates an diesem Include vornehmen können.Es wäre also aktuell für dich vllt besser selbst Änderungen durchzuführen, die du mir (wenn sie nicht sehr individuell sind) gern zukommen lassen kannst.
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
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: TabBarGadget - Tabs wie im Browser

Beitrag von NicTheQuick »

Du könntest auf jeden Fall schon mal die privaten Procedures einkapseln, sodass sie wirklich niemand aufrufen kann. Die restlichen können ihren Namen ja behalten. Dann muss man nur am Anfang des Codes "UseModule TabBarGadget" machen und alles geht wie zuvor, nur dass eben niemand mehr in deinen private Procedures herum pfuschen kann.
Ich kann dir das gerne machen und z.B. meine Änderungen per DropBox zur Verfügung stellen. Falls die "1.5 Beta 1 (2013-10-19)" nicht die aktuellste Version sein sollte, müsstest du mir eben eine aktuelle zuschicken. Oder wir können uns gleich einen Dropbox-Ordner teilen.
Bild
Benutzeravatar
Bisonte
Beiträge: 2430
Registriert: 01.04.2007 20:18

Re: TabBarGadget - Tabs wie im Browser

Beitrag von Bisonte »

NicTheQuick hat geschrieben:Du könntest auf jeden Fall schon mal die privaten Procedures einkapseln, sodass sie wirklich niemand aufrufen kann. Die restlichen können ihren Namen ja behalten. Dann muss man nur am Anfang des Codes "UseModule TabBarGadget" machen und alles geht wie zuvor, nur dass eben niemand mehr in deinen private Procedures herum pfuschen kann.
Sowas hab ich schonmal vorbereitet, kannst ja mal drübersehen, ob das alles so hinkommt. (Also die Beispiele funktionieren...)

Modulversion von B1
PureBasic 6.10 LTS (Windows x86/x64) | Windows10 Pro x64 | Asus TUF X570 Gaming Plus | R9 5900X | 64GB RAM | GeForce RTX 3080 TI iChill X4 | HAF XF Evo | build by vannicom​​
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: TabBarGadget - Tabs wie im Browser

Beitrag von NicTheQuick »

Irgendwie funktioniert das mit 'BindGadgetEvent()' noch nicht so korrekt. Zuerst habe ich festgestellt, dass wenn man selbst 'BindGadgetEvent()' nutzt, der Callback davon vor dem des TabBarGadget-internen Callbacks aufgerufen wird. Deswegen habe ich eine neue Procedure dazu gebastelt, die den internen Callback immer zuerst aufruft. Die heißt jetzt 'BindTabBarGadgetEvent()'. Trotzdem bekomme ich im 'callback()' immer das Gadget, das zuletzt ausgewählt war (CHANGED2 im Debugfenster) und nicht das, was ich gerade bei diesem Event angeklickt habe (CHANGED3 im Debugfenster). Ich habe noch nicht ganz raus wie ich das ändern kann. Weil das brauche ich unbedingt.

Außerdem würde ich gerne wissen, was 'GetTabBarGadgetItemPosition()' genau tut. Gibt nicht 'GetTabBarGadgetState()' schon die aktuell ausgewählte Position zurück?

Code: Alles auswählen

Procedure BindTabBarGadgetEvent(Gadget.i, *Callback, EventType.i = #PB_All)
	UnbindGadgetEvent(Gadget, @TabBarGadget_Callback())
	BindGadgetEvent(Gadget, *Callback, EventType)
	BindGadgetEvent(Gadget, @TabBarGadget_Callback())
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
	
	Enumeration
		#Window
		#Gadget
	EndEnumeration
	
	UsePNGImageDecoder()
	
	OpenWindow(#Window, 0, 0, 400, 200, "TabBarGadget", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
	TabBarGadget(#Gadget, 10, 10, WindowWidth(#Window)-20, #TabBarGadget_DefaultHeight, #TabBarGadget_CloseButton, #Window)
	AddTabBarGadgetItem(#Gadget, #PB_Default, "Any tab "+Str(Random(999)))
	AddTabBarGadgetItem(#Gadget, #PB_Default, "Any tab "+Str(Random(999)))
	AddTabBarGadgetItem(#Gadget, #PB_Default, "Any tab "+Str(Random(999)))
	AddTabBarGadgetItem(#Gadget, #TabBarGadgetItem_NewTab, "", ImageID(CatchImage(#PB_Any, ?Icon)))
	
	SetTabBarGadgetState(#Gadget, 1)
	
	Procedure callback()
		If (EventType() = #TabBarGadget_EventType_Change)
			Debug "CHANGED2: " + GetTabBarGadgetState(#Gadget)
		EndIf
	EndProcedure
	
	BindTabBarGadgetEvent(#Gadget, @callback())
	
	Define Position.i
	
	Repeat
		
		Select WaitWindowEvent()
				
			Case #PB_Event_CloseWindow
				End
				
			Case #PB_Event_Gadget
				Select EventGadget()
					Case #Gadget
						Select EventType()
							Case #TabBarGadget_EventType_NewItem
								Position = AddTabBarGadgetItem(#Gadget, #PB_Default, "New tab "+Str(Random(999)))
								SetTabBarGadgetState(#Gadget, Position)
							Case #TabBarGadget_EventType_CloseItem
								RemoveTabBarGadgetItem(#Gadget, #TabBarGadgetItem_Event)
							Case #TabBarGadget_EventType_Change
								Debug "CHANGED3: " + GetTabBarGadgetState(#Gadget)
						EndSelect
				EndSelect
				
		EndSelect
		
	ForEver
	
	DataSection
		Icon:
		Data.q $0A1A0A0D474E5089,$524448490D000000,$1000000010000000,$FFF31F0000000608,$5845741900000061
		Data.q $72617774666F5374,$2065626F64410065,$6165526567616D49,$00003C65C9717964,$DA78544144495C02
		Data.q $3D105153684B53A4,$4B1A4987926D36F7,$B65D8DC160B44B69,$5742911161FC1115,$EC4445828A082775
		Data.q $175A845C2E170B22,$A576764A0A17155A,$B48685C42E94DC14,$098D20B442C54A90,$9D3EFBE6D24D34F9
		Data.q $7985E1705315F979,$E6733339CEE777DC,$1FC2CB3FF030C30A,$54860CD2E0E34421,$47B34328C75D3E0D
		Data.q $7F3BCC81624DA04A,$4FCC2E4CBBF54B0F,$380FBB9E34E2E00D,$07FAC70373395D6F,$C89147CAD8735651
		Data.q $8ABC30421EB4206C,$16E5C29F9B9B4572,$F137D839E77E0A00,$5E58B7912B1F9AEC,$F295807672A4A3F7
		Data.q $31617453B0063A54,$4C99417B594282B4,$4D87218B1EC60036,$498FE2C7EEB93E09,$A9CEE0755063B6A4
		Data.q $8811B0167E9E7F6A,$2D75F0BBA648ED14,$92C6BB87F0C74D06,$C646C68F15150BE4,$2A310AA42BCFEDF1
		Data.q $FF46C6816D9BD018,$6EBD136576055B46,$39DDAC9F61986BF2,$268FC9C230E7A477,$F780137A4A229973
		Data.q $38652BB24B872A45,$A2702A1B67BBB315,$91CDC4ECEA8B6D25,$5FA94DD3DE548B74,$2AB2FABA95530B2E
		Data.q $BFE4584049D99023,$54802481CCFB9785,$E0625989B1D50A36,$EF8D2A89EF5D3832,$0958DEA76895308B
		Data.q $B4F131D1F5046680,$3745182FE8E10212,$64D1DACC93AA566C,$72019B2FB19F3DE1,$7E4800D022292279
		Data.q $C3A13247122D6F87,$F0026966CC2C25D0,$88171E2ACA34CF9E,$36BF2CC629C40DA6,$C6EAE378FBF9CA48
		Data.q $470E8F77448F51C4,$6299009AF5B2E017,$467E04C70514B90C,$AB88785B98E2640D,$1E17FDCA3BDF9B14
		Data.q $80B73ED189D2B5E0,$0AE78EE4EA346EC3,$C7453C19A4EDE655,$71C181AD02DE5BBF,$8E3B16DB8C343C9C
		Data.q $2360405AB762A5D7,$FBC1C4F8F7D5D988,$3990F131E2DAA63E,$EFCB21164B3012FF,$4CDC000C02BB8D7D
		Data.q $0000B1AFD4924B07,$42AE444E45490000,$0000000000008260
	EndDataSection
CompilerEndIf
Edit:
Okay, ich habe gerade gemerkt, dass ich es mit 'EventData()' machen kann. Hat sich also erst mal geklärt. Trotzdem komisch?
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: TabBarGadget - Tabs wie im Browser

Beitrag von STARGÅTE »

GetTabBarGadgetState() gibt den aktuellen Status des Gadgets zurück, also welcher Tab gerade der aktuelle (ausgewählte ist)
GetTabBarGadgetItemPosition() gibt die Position des übergebenen Tabs zurück.
Indizes geben natürlich sich selbst zurück, aber die Procedure ist zB für TabIDs um zu bestimmen welche Position sie haben (zB wenn ein Tab verschoben wurde) oder für #TabBarGadgetItem_Event, wenn ich Wissen will, über welchem Tab das letzte Event war (Hovereffekt, rechet Maustaste für eigenes Popup)

Intern gibt GetTabBarGadgetItemPosition() bei #TabBarGadgetItem_Event den Eintrag von \EventTab zurück, was bei einem PostEvent() der Wert für EventData() ist.
Gebraucht wird das zB bei der Edit-Funktion für Tabs. Wenn ich ein Tab editiere und dann auf einen anderen Tab klicke, bekomme ich (eigentlich) nur das Event, des neuen Tabs, mit PostEvent() sende ich ein zusätzliches Event, was den alten (editierten) Tab zurück gibt.

Edit bei mir bekomme ich mit deinem Code:
CHANGED2: 0
CHANGED3: 0
CHANGED2: 1
CHANGED3: 1
CHANGED2: 2
CHANGED3: 2
CHANGED2: 1
CHANGED3: 1
Linux Problem?
Unter Windows laufen die Callbacks von BindGadgetEvent() nacheinander, unter Linux vllt parallel?
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
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: TabBarGadget - Tabs wie im Browser

Beitrag von NicTheQuick »

Komisch, bei mir sieht das so aus, wenn ich Tabs der Reihe nach anklicke:
Debugger hat geschrieben:CHANGED2: 1
CHANGED3: 0
CHANGED2: 0
CHANGED3: 1
CHANGED2: 1
CHANGED3: 2
Und parallel wird das hier aber anscheinend nicht abgearbeitet. Das habe ich damit getestet:

Code: Alles auswählen

Procedure ButtonHandlerA()
	Debug "A1 #" + EventGadget()
	Delay(500)
	Debug "A2 #" + EventGadget()
EndProcedure

Procedure ButtonHandlerB()
	Debug "B1 #" + EventGadget()
	Delay(500)
	Debug "B2 #" + EventGadget()
EndProcedure

OpenWindow(0, 100, 100, 200, 50, "Click test", #PB_Window_SystemMenu)

ButtonGadget(0, 10, 10, 180, 30, "Click me")

BindGadgetEvent(0, @ButtonHandlerA())
BindGadgetEvent(0, @ButtonHandlerB())

Repeat
	Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
Deutliches Ergebnis:
Debugger hat geschrieben:B1 #0
B2 #0
A1 #0
A2 #0
Es passieren manchmal auch noch andere komische Dinge, die ich nicht zuverlässig reproduzieren kann und es würde auch eine Weile dauern das aus meinem bisherigen Code zu extrahieren, weil der sehr verschachtelt und "verInterfaced" ist. Und zwar passiert es z.B. bei einem MultiLine-TabBarGadget in einer bestimmten Situation und wenn man es resized und nur manchmal, dass an folgender Stelle innerhalb der Procedure 'TabBarGadget_Update()' anscheinend kein aktuelles Element da ist und das Programm dann abstürzt. Ich hab es mit "FIXME" markiert und mehr oder weniger korrigiert.

Code: Alles auswählen

			; Positionen errechnen
			Length = TabBarGadgetInclude\Margin
			Row = 0
			ForEach \Item()
				If Row <> \Item()\Row
					Row + 1
					Length = TabBarGadgetInclude\Margin
				EndIf
				\Item()\Position = Length
				Length + \Item()\Length - 1
			Next
			If Row(Rows-1)\Length > TabBarGadget_MaxLength(*TabBarGadget)
				;FIXME
				If LastElement(\Item())
					\Item()\Length = TabBarGadget_MaxLength(*TabBarGadget, #False)
					Rows + 1
					\NewTabItem\Row = Rows-1
					\NewTabItem\Position = TabBarGadgetInclude\Margin
				EndIf
			Else
				\NewTabItem\Row = Rows-1
				\NewTabItem\Position = TabBarGadgetInclude\Margin+Row(\NewTabItem\Row)\Length - 1
			EndIf
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: TabBarGadget - Tabs wie im Browser

Beitrag von STARGÅTE »

und hier:
(nichts drücken, das Post macht er automatisch)

Code: Alles auswählen

Global Offset = ElapsedMilliseconds()

Procedure ButtonHandlerA()
	Debug "A1 #" + EventGadget() + "   @ "+Str(ElapsedMilliseconds()-Offset)
	Delay(500)
	Debug "A2 #" + EventGadget() + "   @ "+Str(ElapsedMilliseconds()-Offset)
EndProcedure

Procedure ButtonHandlerB()
	Debug "B1 #" + EventGadget() + "   @ "+Str(ElapsedMilliseconds()-Offset)
	Delay(500)
	Debug "B2 #" + EventGadget() + "   @ "+Str(ElapsedMilliseconds()-Offset)
EndProcedure

OpenWindow(0, 100, 100, 200, 50, "Click test", #PB_Window_SystemMenu)

ButtonGadget(0, 10, 10, 180, 30, "Click me")

BindGadgetEvent(0, @ButtonHandlerA())
BindGadgetEvent(0, @ButtonHandlerB())

PostEvent(#PB_Event_Gadget, 0, 0)

Repeat
	Event = WaitWindowEvent()
	If Event = #PB_Event_Gadget
		Debug "C1 #" + EventGadget() + "   @ "+Str(ElapsedMilliseconds()-Offset)
		Delay(500)
		Debug "C2 #" + EventGadget() + "   @ "+Str(ElapsedMilliseconds()-Offset)
	EndIf
Until Event = #PB_Event_CloseWindow
B1 #0 @ 7
B2 #0 @ 507
A1 #0 @ 507
A2 #0 @ 1007
C1 #0 @ 1007
C2 #0 @ 1507
Der Fehler bedeutet, dass du ein leeres TabBarGadget hast, und die Breite der Bar 0px hat.
Konnte den Fehler bestätigen. und habe ihn Markiert.
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
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: TabBarGadget - Tabs wie im Browser

Beitrag von NicTheQuick »

STARGÅTE hat geschrieben:und hier:
(nichts drücken, das Post macht er automatisch)
Bei mir:
B1 #0 @ 63
B2 #0 @ 563
A1 #0 @ 563
A2 #0 @ 1063
C1 #0 @ 1063
C2 #0 @ 1564
STARGÅTE hat geschrieben:Der Fehler bedeutet, dass du ein leeres TabBarGadget hast, und die Breite der Bar 0px hat.
Konnte den Fehler bestätigen. und habe ihn Markiert.
Nein, es waren 3 Tabs drin und dann habe ich es versucht auf 0 Pixel Breite zu schieben. Ich wollte nur das MultiLine testen und habe halt rum geschoben. Dann kam man natürlich auch mal auf 0 Pixel. Wobei ich glaube, dass es sogar schon passiert ist bevor ich auf 0 Pixel Breite gegangen bin. Notfalls versuche ich nochmal es irgendwie zu reproduzieren.
Bild
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: TabBarGadget - Tabs wie im Browser

Beitrag von mk-soft »

Purebasic verwendet ja Dein TabbarGadget.
Habe aber mit der PB-IDE unter Mac OS X folgendes Problem.

Irgendwann fängt das Gadget an beim wechseln der Tabs in den Verschiebemodus zu gehen. Wenn die Maus dann wieder über den Gadget steht wandert das zuletzt angewählte Tab in der Leiste. Sporadisch stimmt dann auch nicht der angewählte Tab mit den Inhalt des Arbeitsfenster.

Da mein Englisch nicht ganz so gut ist, habe ich den Fehler hier beschrieben und nicht im Bug Forum für den PB Editor.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: TabBarGadget - Tabs wie im Browser

Beitrag von STARGÅTE »

Hm, leider kann ich mir dieser Fehlerbeschreibung nicht viel anfangen.
Der VerschiebeModus wird eigentlich nur aktiv, wenn die Maus gedrückt bleibt.

Vielleicht kannst du ja mal ein kleines Video drehen, am besten, mit einem Programm was auch die Maus und Tastatur-Events anzeigt.
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
Antworten