scrollen wie iPad ...?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Then
Beiträge: 278
Registriert: 06.09.2004 13:26
Wohnort: Siegen

scrollen wie iPad ...?

Beitrag von Then »

Hallo,

hätte jemand evtl. einen Ansatz für mich, wie man eine gefüllte Liste per Finger (Mausbewegung) scrollen kann wie das iPad, oder iPhone ?? Macht man da ein ListIconGadget und scrollt das oder besser als Image.. nur wie wählt man dann aus ?? Ich plane auf meine Touchpad ein MP3 Player zu proggen und die Auswahl soll mit Finger sein...
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: scrollen wie iPad ...?

Beitrag von NicTheQuick »

Ich würde an deiner Stelle kein ListIconGadget nehmen, sondern ein Image (evtl. mehrere Images), oder wenn es sowieso Vollbild werden soll, einen Screen verwenden.

Ist dein Problem jetzt hauptsächlich das weiche Scrollen wie beim iPad oder das Erkennen von Klicks?
Benutzeravatar
Then
Beiträge: 278
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Re: scrollen wie iPad ...?

Beitrag von Then »

hm... eben beides... wie soll ich nun erkennen, welches File ausgewählt wurde ??

ach.... noch viel schlimmer, es soll ja sogar erkannt werden, das ich jetzt scrollen will und jetzt auswähle ! Boah ! :freak:
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: scrollen wie iPad ...?

Beitrag von NicTheQuick »

Ich hatte ja vor kurzem ein Seminar mit Multitouch-Tables gemacht. Da haben wir LibAVG benutzt. Aber dafür gibt es noch keinen Wrapper für PureBasic. Und es wäre sowieso ein wenig oversized, da du ja eh nur SingleTouch verwendest.

Im Grunde brauchst du nur die Events für MouseDown und MouseUp abzufangen und dabei die Position des Mauszeigers auszulesen. Dazwischen gibt es dann noch die Events, die dir die Mausbewegung liefern, die lassen wir aber der Einfachheit halber weg.

Deine Dateienliste benötigt eine x- und y-Position, eine x- und y-Geschwindigkeit und eine Dämpfung pro Frame oder Millisekunde. Werte für die Dämpfung sind kleiner als 1 und besser sogar kleiner als 0.01.
In deiner Hauptschleife oder einem extra Thread musst du ständig die Geschwindigkeit mit der Dämpfung multiplizieren, sodass die Geschwindigkeit zunehmend kleiner wird. Außerdem musst du die Geschwindigkeit auch dauernd auf die Position addieren.
Klickt jemand auf die Dateienliste, speicherst du die Position des Mauszeigers und setzt die Geschwindigkeit auf Null. Solange die Maustaste gedrückt ist, speicherst du in regelmäßigen Abständen (z.B. 10 ms) die relative Position der Maus zu vorher in einer Liste. Dabei kannst du darauf achten, das in dieser Liste immer nur die letzten 10 Position gespeichert bleiben oder sie aber später kürzen. Währenddessen verschiebst du deine Dateienliste anhand dieser relativen Positionen. Kommt jetzt das MouseUp-Event, bildest du den Durchschnitt aller relativen Positionen in dieser Liste. Ist dieser Durchschnitt groß (s. euklidische Norm) genug, setzt du ihn als momentane Geschwindigkeit für die Dateienliste. Ist dies nicht der Fall, berechnest du einfach aus der Position der Maus die Datei, die angeklickt wurde und spielst sie ab, oder was auch immer du damit tun möchtest.
Weitere Dinge wie das Einhalten der Begrenzung oben und unten, müssen natürlich auch noch beachtet werden.
Benutzeravatar
Then
Beiträge: 278
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Re: scrollen wie iPad ...?

Beitrag von Then »

Also mit folgendem Code :

Code: Alles auswählen

UseJPEGImageDecoder()

InitSprite()
InitMouse()
InitKeyboard()

bild=LoadImage(1,"Test.JPG")  ;- <=== HIER ANPASSEN !!!

OpenWindow(0,0,0,488,800,"",#PB_Window_ScreenCentered)
 CreateGadgetList(WindowID(0))
 OpenWindowedScreen(WindowID(0),0,0,488,800,1,1,1)
 
 CreateSprite(1,488,976)
  StartDrawing(SpriteOutput(1))
   DrawImage(bild,0,0)
  StopDrawing()
 
  DisplaySprite(1,0,0)
  FlipBuffers()
   
 Repeat
  ExamineMouse()
  ExamineKeyboard()
  Delay(1)
  
  If MouseButton(1)=1
   DisplaySprite(1,0,MouseY())
   FlipBuffers()
  EndIf
  
  Until KeyboardPushed(#PB_Key_Escape) 
geht schonmal grob das verschieben... wie mache ichs jetzt, dass ich ein viiiiieeeeel größeres Sprite weiter schieben kann ?? Es startet immer da, wo ich mit der Maus klicke, statt es weiter hoch oder runter zu schieben.
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: scrollen wie iPad ...?

Beitrag von NicTheQuick »

Du musst nur machen, was ich oben geschrieben habe. Das heißt ich mag das jetzt nicht doppelt erklären.
Aber ich versuche mal ein Mini-Beispiel zu proggen und melde mich dann wieder.
Benutzeravatar
Then
Beiträge: 278
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Re: scrollen wie iPad ...?

Beitrag von Then »

Sorry, aber mit Grafikprogrammierung hatte ich bisher nix am Hut, habe Touchscreen-Kassen Systeme, Warenwirtschaft oder CNC-Steuerungen programmiert aber das ist Neuland für mich und da muß ich jetzt scheinbar durch...
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: scrollen wie iPad ...?

Beitrag von NicTheQuick »

Okay, habe mal auf die Schnelle was gebastelt. Aber nicht erschrecken! :D

Ich habe die Hauptschleife so einfach wie möglich gehalten und die Parameter für den Glider ein bisschen kommentiert. Also einfach mal ein bisschen rumprobieren.

Code: Alles auswählen

EnableExplicit

Structure Rect
	top.i
	left.i
	width.i
	height.i
EndStructure

Structure Vector2D
	x.d
	y.d
EndStructure

Structure Point2D
	x.d
	y.d
EndStructure

Enumeration ;freedom
	#AXIS_X = 1
	#AXIS_Y = 2
EndEnumeration

Structure GlidePanel
	;müssen gesetzt werden
	panel.Rect			;äußerer Rahmen, in dem alles angezeigt werden soll
	hSprite.i			;Sprite, das als Inhalt dient
	position.Point2D	;Position des Sprites
	content.Rect		;Bereich, in dem gescrollt werden kann, relativ zu panel
	damping.d			;aktuelle Dämpfung für die Geschwindigkeit
	freedom.i			;Flags für die Benutzung von x- und y-Achse
	
	;werden intern gesetzt
	speed.Point2D		;aktuelle Geschwindigkeit des Sprites
	oldMouseRel.Point2D
	mouseDown.i
	acquired.i
	List mouseRelPos.Point2D()
EndStructure

Procedure GlidePanel_Init(*panel.GlidePanel)
	With *panel
		\speed\x = 0
		\speed\y = 0
		\acquired = #False
		\mouseDown = #False
		ClearList(\mouseRelPos())
	EndWith
	
	ProcedureReturn #True
EndProcedure

Procedure GlidePanel_Update(*panel.GlidePanel)
	Protected mouseRel.Point2D
	With *panel
		If \freedom & #AXIS_X
			mouseRel\x = MouseX() - \panel\left
		EndIf
		If \freedom & #AXIS_Y
			mouseRel\y = MouseY() - \panel\top
		EndIf
		
		If MouseButton(1)
			If (mouseRel\x < 0 Or mouseRel\x >= \panel\width Or mouseRel\y < 0 Or mouseRel\y >= \panel\height Or \mouseDown) And Not \acquired
				\mouseDown = #True
			Else
				If Not \acquired ;MouseDown
					\oldMouseRel = mouseRel
					\speed\x = 0
					\speed\y = 0
					\acquired = #True
				Else ;MouseMoveClicked
					LastElement(\mouseRelPos())
					If AddElement(\mouseRelPos())
						\mouseRelPos()\x = mouseRel\x - \oldMouseRel\x
						\mouseRelPos()\y = mouseRel\y - \oldMouseRel\y
						\position\x + \mouseRelPos()\x
						\position\y + \mouseRelPos()\y
						\oldMouseRel = mouseRel
					EndIf
					If ListSize(\mouseRelPos()) > 10
						FirstElement(\mouseRelPos())
						DeleteElement(\mouseRelPos())
					EndIf
				EndIf
			EndIf
			
		Else
			\mouseDown = #False
			If \acquired ;MouseUp
				mouseRel\x = 0
				mouseRel\y = 0
				ForEach \mouseRelPos()
					mouseRel\x + \mouseRelPos()\x
					mouseRel\y + \mouseRelPos()\y
				Next
				mouseRel\x / ListSize(\mouseRelPos())
				mouseRel\y / ListSize(\mouseRelPos())
				\speed\x = mouseRel\x
				\speed\y = mouseRel\y
				\acquired = #False
			EndIf
		EndIf
		
		\position\x + \speed\x
		\position\y + \speed\y
		\speed\x * (1. - \damping)
		\speed\y * (1. - \damping)
		
		If \position\y < \content\top
			\position\y = \content\top
		EndIf
		If \position\y > \content\top + \content\height
			\position\y = \content\top + \content\height
		EndIf
		If \position\x < \content\left
			\position\x = \content\left
		EndIf
		If \position\x > \content\left + \content\width
			\position\x = \content\left + \content\width
		EndIf
	EndWith
EndProcedure

Procedure GlidePanel_Display(*panel.GlidePanel)
	With *panel
		ClipSprite(\hSprite, -\position\x, -\position\y, \panel\width, \panel\height)
		DisplaySprite(*panel\hSprite, *panel\panel\left, *panel\panel\top)
		ClipSprite(\hSprite, #PB_Default, #PB_Default, #PB_Default, #PB_Default)
	EndWith
EndProcedure

UseJPEGImageDecoder()

InitSprite()
InitMouse()
InitKeyboard()

If Not OpenWindow(0, 0, 0, 488, 800, "", #PB_Window_ScreenCentered) : End : EndIf
If Not OpenWindowedScreen(WindowID(0), 0, 0, 488, 800, 0, 0, 0) : End : EndIf

Define image.i, sprite.i, mouse.i

image = LoadImage(#PB_Any, "/home/nicolas/Bilder/gf1029019.jpg")
If Not image : End : EndIf

sprite = CreateSprite(#PB_Any, 488, 976)
If Not sprite : End : EndIf
If StartDrawing(SpriteOutput(sprite))
	Box(0, 0, 488, 976, $ff0000)
	DrawImage(ImageID(image), 0, 0)
	StopDrawing()
EndIf

mouse = CreateSprite(#PB_Any, 10, 10)
If Not mouse : End : EndIf
If StartDrawing(SpriteOutput(mouse))
	Circle(5, 5, 5, RGB(255, 255, 255))
	StopDrawing()
EndIf

Define glider.GlidePanel

With glider\panel					;Die Ausmaße des Panels und seine Position auf dem Bildschirm
	\top = 100
	\left = 50
	\width = 388
	\height = 600
EndWith
glider\hSprite = sprite
glider\position\x = 0				;die anfängliche Position des Sprites im Panel
glider\position\y = 0
With glider\content					;Der Scrollbereich
	\left = -SpriteWidth(sprite) + 20
	\top = -SpriteHeight(sprite) + 20
	\width = 388 + SpriteWidth(sprite) - 40
	\height = 600 + SpriteHeight(sprite) - 40
EndWith
glider\damping = 0.01				;je höher dieser Wert, desto schneller bleibt der Glider stehen
glider\freedom = #AXIS_X | #AXIS_Y	;durch setzen dieser Flags wird auf beiden achsen gescrollt

If Not GlidePanel_Init(glider) : End : EndIf

Repeat
	ClearScreen(0)
	ExamineMouse()
	ExamineKeyboard()
	
	GlidePanel_Update(glider)
	
	GlidePanel_Display(glider)
	
	DisplaySprite(mouse, MouseX() - 5, MouseY() - 5)
	
	FlipBuffers()
	
Until KeyboardPushed(#PB_Key_Escape)
Benutzeravatar
Then
Beiträge: 278
Registriert: 06.09.2004 13:26
Wohnort: Siegen

Re: scrollen wie iPad ...?

Beitrag von Then »

muss erst die 4.5 installieren... startet leider mit Fehlern....

dennoch erstma danke !
PB 6.10LTs / Windows 11 64Bit (i9/32GB/ 1TB-SSD+4TB-HDD/3060GTX12GB) / 2x27" Multitouch

... ich mache dazu keine Aussage, weil ich mich damit selbst belasten könnte !
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8807
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: scrollen wie iPad ...?

Beitrag von NicTheQuick »

Achso, da hab ich nicht dran gedacht. Das hätte man auch anders machen können, aber 4.50 installieren ist immer gut.
Antworten