Seite 1 von 2

Coole Buttons mit Fader

Verfasst: 28.04.2017 12:43
von AnonymousForAll
Hallo Freunde

Wie krieg ich in Windows folgende Buttons hin: https://tympanus.net/Development/CreativeButtons/
Ich finde die CSS3 Buttons mit Fader Effekt sehr hübsch und will das in meiner App auch erstellen aber wie? Es soll bei Mouse Hover ein und ausfaden. Wie geht das?

Danke Freunde

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 13:00
von NicTheQuick
Mit Purebasic kannst du keine speziellen Windows Apps schreiben, nur normale Programme. Und mit CSS3 oder allgemein CSS kommst du leider auch nicht weiter.
Du kannst aber benutzerdefinierte Buttons selbst zeichnen, das ist aber mit viel Arbeit verbunden und man muss die explizit die Windows-API benutzen.

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 13:10
von Bisonte
NicTheQuick hat geschrieben:Du kannst aber benutzerdefinierte Buttons selbst zeichnen, das ist aber mit viel Arbeit verbunden und man muss die explizit die Windows-API benutzen.
Das ist nicht ganz richtig, dank AddWindowTimer() und CanvasGadget() geht das auch auf anderen OS.

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 15:42
von RSBasic
Grundsätzlich ist das mit CanvasGadget möglich, aber ich würde dir empfehlen, keine eigenen Buttons zu erstellen.
1. Weil es eventuell nicht mit dem vom Benutzer eingestellten OS-Design zusammenpasst.
2. Weil diese Buttons nicht von externen Programmen ausgelesen werden können, weil diese inkl. Text gezeichnet sind. D.h. keine Barrierefreiheit

Es wäre zwar möglich, einen normalen ButtonGadget zu modifizieren, aber nur mit der jeweiligen OS-API-Schnittstelle.

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 16:37
von Derren
ich hab absolut keine Erfahrung mit Screenreadern, aber vielleicht könnte man den echten Button einfach hinter das Canvas Gadget legen.
Mit dem letzten Update kann man ja Gadgets auf ein Canvas Gadget legen, bzw ein Canvas als Hintergrund vewenden. Vlt klappt's ja auch andersrum.

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 17:22
von DarkDragon
Derren hat geschrieben:ich hab absolut keine Erfahrung mit Screenreadern, aber vielleicht könnte man den echten Button einfach hinter das Canvas Gadget legen.
Mit dem letzten Update kann man ja Gadgets auf ein Canvas Gadget legen, bzw ein Canvas als Hintergrund vewenden. Vlt klappt's ja auch andersrum.
Das Problem ist dann der Fokus, der entscheidend ist. Der Button müsste sich den Fokus mit dem Canvas teilen. Ist ein Canvas überhaupt fokussierbar?

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 20:38
von STARGÅTE
Habe dir mal hier ein Beispiel geschrieben.
Bitte unbedingt Thread-Safe aktivieren!
Außerdem können diese Gadgets nicht mit FreeGadget freigegeben werden, da sonst die Threads ins leere laufen.
Das müsste man dann ggf. noch erweitern.

Edit: Thread-Safe Meldung und FreeFadingButtonGadget() hinzugefügt

Code: Alles auswählen


CompilerIf Not #PB_Compiler_Thread
	CompilerError "Please enable the thread-safe mode!"
CompilerEndIf


; Memory buffer for the FadingButtonGadget
Structure FadingButtonGadget
	Gadget.i
	Counter.i
	Fade.f
	Hovered.i
	Quit.i
	Text.s
	Thread.i
	Type.i
	FontID.i
	Pushed.i
EndStructure


; Procedure to draw the button
Procedure FadingButtonGadget_Draw(*FadingButtonGadget.FadingButtonGadget)
	
	With *FadingButtonGadget
		If StartDrawing(CanvasOutput(\Gadget))
			DrawingFont(\FontID)
			Select \Type
				Case 0
					Box(0, 0, OutputWidth(), OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
				Case 1
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(0, 0, OutputWidth(), OutputHeight()*\Fade, $FFFFFF)
				Case 2
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(0, 0, OutputWidth()*\Fade, OutputHeight(), $FFFFFF)
				Case 3
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(OutputWidth()/2-\Fade*(OutputWidth()-20)/2, 0, (OutputWidth()-20)*\Fade, OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
				Case 4
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Line(OutputWidth()/2-(OutputWidth()/2+OutputHeight()/2)*\Fade, 0, OutputHeight(), OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
					Line(OutputWidth()/2+(OutputWidth()/2+OutputHeight()/2)*\Fade-1, OutputHeight()-1, -OutputHeight(), -OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
					FillArea(OutputWidth()/2, OutputHeight()/2, RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
				Case 5
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(0, OutputHeight()/2-\Fade*(OutputHeight()-20)/2, OutputWidth(), (OutputHeight()-20)*\Fade, RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
			EndSelect
			DrawingMode(#PB_2DDrawing_Outlined)
			Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)
			Box(1, 1, OutputWidth()-2, OutputHeight()-2, $FFFFFF)
			Box(2, 2, OutputWidth()-4, OutputHeight()-4, $FFFFFF)
			DrawingMode(#PB_2DDrawing_Transparent)
			DrawText(OutputWidth()/2-TextWidth(\Text)/2+\Pushed*2, OutputHeight()/2-TextHeight(\Text)/2+\Pushed*2, \Text, RGB(255-223*\Fade, 255-127*\Fade, 255-31*\Fade))
			StopDrawing()
		EndIf
	EndWith
	
EndProcedure


; Thread for the button fading
Procedure FadingButtonGadget_Fading(*FadingButtonGadget.FadingButtonGadget)
	
	Repeat
		If *FadingButtonGadget\Hovered = #True And *FadingButtonGadget\Counter < 30
			*FadingButtonGadget\Counter + 1
			*FadingButtonGadget\Fade = Sqr(*FadingButtonGadget\Counter/30.)
			FadingButtonGadget_Draw(*FadingButtonGadget)
		ElseIf *FadingButtonGadget\Hovered = #False And *FadingButtonGadget\Counter > 0
			*FadingButtonGadget\Counter - 1
			*FadingButtonGadget\Fade = Sqr(*FadingButtonGadget\Counter/30.)
			FadingButtonGadget_Draw(*FadingButtonGadget)
		EndIf
		Delay(10)
	Until *FadingButtonGadget\Quit
	
EndProcedure


; Procedure to examine the events on the button
Procedure FadingButtonGadget_Event()
	
	Protected *FadingButtonGadget.FadingButtonGadget = GetGadgetData(EventGadget())
	
	With *FadingButtonGadget
		Select EventType()
			Case #PB_EventType_MouseEnter
				\Hovered = #True
			Case #PB_EventType_MouseLeave
				\Hovered = #False
			Case #PB_EventType_LeftButtonDown
				\Pushed = #True
				FadingButtonGadget_Draw(*FadingButtonGadget)
			Case #PB_EventType_LeftButtonUp
				\Pushed = #False
				FadingButtonGadget_Draw(*FadingButtonGadget)
		EndSelect
	EndWith
	
EndProcedure


; Creates the fading button
Procedure FadingButtonGadget(Gadget.i, X.i, Y.i, Width.i, Height.i, Text.s, Type.i, FontID.i)
	
	Protected *FadingButtonGadget.FadingButtonGadget = AllocateStructure(FadingButtonGadget)
	
	With *FadingButtonGadget
		
		If Gadget = #PB_Any
			Gadget = CanvasGadget(Gadget, X, Y, Width, Height)
			\Gadget = Gadget
		Else
			\Gadget = Gadget
			Gadget = CanvasGadget(Gadget, X, Y, Width, Height)
		EndIf
		
		\Text = Text
		\FontID = FontID
		\Type = Type
		\Thread = CreateThread(@FadingButtonGadget_Fading(), *FadingButtonGadget)
		SetGadgetData(\Gadget, *FadingButtonGadget)
		BindGadgetEvent(\Gadget, @FadingButtonGadget_Event())
		FadingButtonGadget_Draw(*FadingButtonGadget)
		
	EndWith
	
	ProcedureReturn Gadget
	
EndProcedure


; Frees the fading button
Procedure FreeFadingButtonGadget(Gadget.i)
	
	Protected *FadingButtonGadget.FadingButtonGadget = GetGadgetData(EventGadget())
	
	With *FadingButtonGadget
		
		\Quit = #True
		WaitThread(\Thread)
		FreeGadget(*FadingButtonGadget\Gadget)
		FreeStructure(*FadingButtonGadget)
		
	EndWith
	
EndProcedure



;- Example

Enumeration
	#Window
	#Font
EndEnumeration

LoadFont(#Font, "Arial", 16, #PB_Font_Bold)

OpenWindow(#Window, 0, 0, 780, 240, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
SetWindowColor(#Window, $E08020)
FadingButtonGadget(1, 40, 40, 200, 60, "Pure Basic", 0, FontID(#Font))
FadingButtonGadget(2, 290, 40, 200, 60, "Pure Basic", 1, FontID(#Font))
FadingButtonGadget(3, 540, 40, 200, 60, "Pure Basic", 2, FontID(#Font))
FadingButtonGadget(4, 40, 140, 200, 60, "Pure Basic", 3, FontID(#Font))
FadingButtonGadget(5, 290, 140, 200, 60, "Pure Basic", 4, FontID(#Font))
FadingButtonGadget(6, 540, 140, 200, 60, "Pure Basic", 5, FontID(#Font))

Repeat
	
	Select WaitWindowEvent()
			
		Case #PB_Event_CloseWindow
			End
			
		Case #PB_Event_Gadget
			Select EventGadget()
				Case 1 To 6
					If EventType() = #PB_EventType_LeftClick
						Debug "Free Button "+EventGadget()
						FreeFadingButtonGadget(EventGadget())
					EndIf
			EndSelect
			
	EndSelect
	
ForEver

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 21:42
von AnonymousForAll
Danke Freunde

Ihr seid klasse !
STARGÅTE hat geschrieben:Habe dir mal hier ein Beispiel geschrieben.
Bitte unbedingt Thread-Safe aktivieren!
Außerdem können diese Gadgets nicht mit FreeGadget freigegeben werden, da sonst die Threads ins leere laufen.
Das müsste man dann ggf. noch erweitern.

Code: Alles auswählen

Structure FadingButtonGadget
	Gadget.i
	Counter.i
	Fade.f
	Hovered.i
	Quit.i
	Text.s
	Thread.i
	Type.i
	FontID.i
	Pushed.i
EndStructure


; Procedure to draw the button
Procedure FadingButtonGadget_Draw(*FadingButtonGadget.FadingButtonGadget)
	
	With *FadingButtonGadget
		If StartDrawing(CanvasOutput(\Gadget))
			DrawingFont(\FontID)
			Select \Type
				Case 0
					Box(0, 0, OutputWidth(), OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
				Case 1
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(0, 0, OutputWidth(), OutputHeight()*\Fade, $FFFFFF)
				Case 2
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(0, 0, OutputWidth()*\Fade, OutputHeight(), $FFFFFF)
				Case 3
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(OutputWidth()/2-\Fade*(OutputWidth()-20)/2, 0, (OutputWidth()-20)*\Fade, OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
				Case 4
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Line(OutputWidth()/2-(OutputWidth()/2+OutputHeight()/2)*\Fade, 0, OutputHeight(), OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
					Line(OutputWidth()/2+(OutputWidth()/2+OutputHeight()/2)*\Fade-1, OutputHeight()-1, -OutputHeight(), -OutputHeight(), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
					FillArea(OutputWidth()/2, OutputHeight()/2, RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade), RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
				Case 5
					Box(0, 0, OutputWidth(), OutputHeight(), $E08020)
					Box(0, OutputHeight()/2-\Fade*(OutputHeight()-20)/2, OutputWidth(), (OutputHeight()-20)*\Fade, RGB(32+223*\Fade, 128+127*\Fade, 224+31*\Fade))
			EndSelect
			DrawingMode(#PB_2DDrawing_Outlined)
			Box(0, 0, OutputWidth(), OutputHeight(), $FFFFFF)
			Box(1, 1, OutputWidth()-2, OutputHeight()-2, $FFFFFF)
			Box(2, 2, OutputWidth()-4, OutputHeight()-4, $FFFFFF)
			DrawingMode(#PB_2DDrawing_Transparent)
			DrawText(OutputWidth()/2-TextWidth(\Text)/2+\Pushed*2, OutputHeight()/2-TextHeight(\Text)/2+\Pushed*2, \Text, RGB(255-223*\Fade, 255-127*\Fade, 255-31*\Fade))
			StopDrawing()
		EndIf
	EndWith
	
EndProcedure


; Thread for the button fading
Procedure FadingButtonGadget_Fading(*FadingButtonGadget.FadingButtonGadget)
	Repeat
		If *FadingButtonGadget\Hovered = #True And *FadingButtonGadget\Counter < 30
			*FadingButtonGadget\Counter + 1
			*FadingButtonGadget\Fade = Sqr(*FadingButtonGadget\Counter/30.)
			FadingButtonGadget_Draw(*FadingButtonGadget)
		ElseIf *FadingButtonGadget\Hovered = #False And *FadingButtonGadget\Counter > 0
			*FadingButtonGadget\Counter - 1
			*FadingButtonGadget\Fade = Sqr(*FadingButtonGadget\Counter/30.)
			FadingButtonGadget_Draw(*FadingButtonGadget)
		EndIf
		Delay(10)
	Until *FadingButtonGadget\Quit
EndProcedure



; Procedure to examine the events on the button
Procedure FadingButtonGadget_Event()
	
	Protected *FadingButtonGadget.FadingButtonGadget = GetGadgetData(EventGadget())
	
	With *FadingButtonGadget
		Select EventType()
			Case #PB_EventType_MouseEnter
				\Hovered = #True
			Case #PB_EventType_MouseLeave
				\Hovered = #False
			Case #PB_EventType_LeftButtonDown
				\Pushed = #True
				FadingButtonGadget_Draw(*FadingButtonGadget)
			Case #PB_EventType_LeftButtonUp
				\Pushed = #False
				FadingButtonGadget_Draw(*FadingButtonGadget)
		EndSelect
	EndWith
	
EndProcedure




Procedure FadingButtonGadget(Gadget.i, X.i, Y.i, Width.i, Height.i, Text.s, Type.i, FontID.i)
	
	Protected *FadingButtonGadget.FadingButtonGadget = AllocateStructure(FadingButtonGadget)
	
	With *FadingButtonGadget
		
		If Gadget = #PB_Any
			Gadget = CanvasGadget(Gadget, X, Y, Width, Height)
			\Gadget = Gadget
		Else
			\Gadget = Gadget
			Gadget = CanvasGadget(Gadget, X, Y, Width, Height)
		EndIf
		
		\Text = Text
		\FontID = FontID
		\Type = Type
		\Thread = CreateThread(@FadingButtonGadget_Fading(), *FadingButtonGadget)
		SetGadgetData(\Gadget, *FadingButtonGadget)
		BindGadgetEvent(\Gadget, @FadingButtonGadget_Event())
		FadingButtonGadget_Draw(*FadingButtonGadget)
		
	EndWith
	
	ProcedureReturn Gadget
	
EndProcedure



Enumeration
	#Window
	#Font
EndEnumeration


LoadFont(#Font, "Arial", 16, #PB_Font_Bold)

OpenWindow(#Window, 0, 0, 780, 240, "WindowTitle", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
SetWindowColor(#Window, $E08020)
FadingButtonGadget(1, 40, 40, 200, 60, "Pure Basic", 0, FontID(#Font))
FadingButtonGadget(2, 290, 40, 200, 60, "Pure Basic", 1, FontID(#Font))
FadingButtonGadget(3, 540, 40, 200, 60, "Pure Basic", 2, FontID(#Font))
FadingButtonGadget(4, 40, 140, 200, 60, "Pure Basic", 3, FontID(#Font))
FadingButtonGadget(5, 290, 140, 200, 60, "Pure Basic", 4, FontID(#Font))
FadingButtonGadget(6, 540, 140, 200, 60, "Pure Basic", 5, FontID(#Font))

Repeat
	
	Select WaitWindowEvent()
			
		Case #PB_Event_CloseWindow
			End
			
		Case #PB_Event_Gadget
			Select EventGadget()
				Case 1 To 6
					If EventType() = #PB_EventType_LeftClick
						Debug EventGadget()
					EndIf
			EndSelect
			
	EndSelect
	
ForEver
Genau das wollte ich. Du hast es perfekt 1:1 umgesetzt. Man kann keinen Unterschied erkennen ob es CSS3 oder PB ist. Gut gemacht danke!

Aber was ist Thread-Safe genau und warum entsteht ein Fehler wenn man es nicht aktiviert hat? Was ist der Unterschied? Und warum gibt es überhaupt die Auswahl ob mit oder ohne Thread-Safe wenn es ohne Thread-Safe Probleme macht? Welche Vor und Nachteile gibt es beim aktivieren oder deaktivieren von Thread-Safe?

Re: Coole Buttons mit Fader

Verfasst: 28.04.2017 22:20
von STARGÅTE
https://www.purebasic.com/german/documentation/thread/index.html hat geschrieben:PureBasic hat eine spezielle Compiler-Einstellung, um threadsichere Executable zu erstellen. (/THREAD Kommandozeilen-Option oder "Erstelle threadsicheres Executable" in den IDE-Optionen.) Ohne diesen Modus sind bestimmte Funktionen (und auch der String-Zugriff) schneller, aber nicht sicher zur Verwendung in Threads. Es ist dennoch möglich, Threads ohne diesen Modus zu erstellen, aber nicht empfehlenswert, da selbst eine einfache Sache wie der lokale Zugriff auf Strings gefährlich sein kann und geschützt werden muss. Das Aktivieren dieser Option macht diese Dinge sicher innerhalb von Threads, geht jedoch zu Lasten von etwas Geschwindigkeit. Die Entscheidung, ob Threads verwendet werden oder nicht, sollte mit Bedacht gefällt werden, und der Thread-Modus sollte nur dann verwendet werden, wenn wirklicher Bedarf dafür besteht.
Ich werde morgen noch ein sicheres Freigeben des Gadgets hinzufügen, was den Thread beendet und den erstellten Speicher freigibt.

Re: Coole Buttons mit Fader

Verfasst: 30.04.2017 10:55
von STARGÅTE
Habe den Code in meinem ersten Post nun erweitert.