Eigene GUI Slider?

Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

Mathias-Kwiatkowski

Betreff: Eigene GUI Slider?

BeitragSa, Jul 28, 2012 0:15
Antworten mit Zitat
Benutzer-Profile anzeigen
wollte slider programmieren , also falls in meinen fenstern etwas enthalten ist was über der fensterposition ist, und das fenster aktiv ist, taucht ein slider auf. das is auch nich mein problem, mein grosses problem ist ehr die X achse zu setzen.

sprich wenn sich die Cam im fenster vergrössert, schiebt man den inhalt somit nach links weg.
fazit : CamX=CamX+1


hier der codeausschnitt der benötigt wird.
(um nicht gleich die ganze gui zu posten xD
Code: [AUSKLAPPEN]
   If Self.ScrollX > 0 Then
            If Self.Activ = 1 Then
               TTT:Float = 0
               If Self.ScrollY > 0 Then TTT:Float = 15
               SichtW:Float = Self.W - TTT
               BereichW:Float = -ttt + Self.ScrollX
               
               MaxLeng:Float = Float(SichtW) / Float(BereichW)
               SetColor 255, 255, 255
               DrawRect Self.X + 1 + MaxLeng * Self.CamX / BereichW, Self.Y + Self.H - 15, Self.W - 1, 14
               
               SliderMaxLeng:Float = Float(Self.W - 1) * maxleng / 100.0
               SetScale SliderMaxLeng, 1
               SetColor 0, 0, 255
               CC:Float = SliderMaxLeng * Self.CamX       '<- Die Rechnung um den slider in der X achse nach rechts zu schieben. wenn dort folgende rechnung steht, funktioniert gar nichts : SliderMaxLeng * Self.CamX / BereichW
               DrawRect Self.X + 1 + CC, Self.Y + Self.H - 15, 100, 14
               SetScale 1, 1
               SetColor 255, 0, 0
               If BaseMouseX > Self.X + 2 And BaseMouseX < Self.X + 2 + TextWidth("<-") And BaseMouseY > Self.Y + Self.H - TextHeight("W") - 1 And BaseMouseY < Self.Y + Self.H - 1 Then
                  SetColor 255, 255, 0
                  If BaseMouseButtonLeft = 2 Or BaseMouseButtonLeft = 5 Then
                     BaseMouseButtonLeft = 5
                     Self.CamX = Self.CamX - 1
                     If Self.CamX < 0 Then Self.CamX = 0
                  End If
               EndIf
               DrawText "<-", Self.X + 2, Self.Y + Self.H - TextHeight("W") - 1
               
               SetColor 255, 0, 0
               If BaseMouseX > Self.X + Self.W - TextWidth("->") - 2 And BaseMouseX < Self.X + Self.W - 2 And BaseMouseY > Self.Y + Self.H - TextHeight("W") - 1 And BaseMouseY < Self.Y + Self.H - 1 Then
                  SetColor 255, 255, 0
                  If BaseMouseButtonLeft = 2 Or BaseMouseButtonLeft = 5 Then
                     BaseMouseButtonLeft = 5
                     Self.CamX = Self.CamX + 1
                     If Self.CamX > BereichW - SichtW Then Self.CamX = BereichW - SichtW
                  End If
               EndIf
               DrawText "->", Self.X + Self.W - TextWidth("->") - 2, Self.Y + Self.H - TextHeight("W") - 1
            EndIf
         Else
            Self.CamX = 0
         EndIf

Midimaster

BeitragSa, Jul 28, 2012 0:25
Antworten mit Zitat
Benutzer-Profile anzeigen
hast du ein problem beim slider oder beim bildausschnitt?

slider am beispiel x-achse
der slider hat zwei größen:

die breite, die ihm zum sliden zur verfügung steht (fensterbreite) sagen wir mal 800 pix
die breite des zu großen bildes (sagen wir mal 1000pix)

daraus ergibt sich, dass die 800pix die 1000pix repräsentieren müssen. der sichtbare teil des bildes sind 800 von 1000pix also 80%

der slider selbst ist 800pix lang seine sliderbar darf aber nur 80% von 800 = 640 pix lang sein und kann nur 160pix bewegt werden. also von 0 bis 160. dies repräsentiert einen scrollbaren bildbereich von 0 bis 160/0.8 also von 0 bis 200. Wird der slider also um 80 pixel bewegt, dann bewegt sich das image um 100pix negativ
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Mathias-Kwiatkowski

BeitragSa, Jul 28, 2012 1:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
dies repräsentiert einen scrollbaren bildbereich von 0 bis 160/0.8 also von 0 bis 200. Wird der slider also um 80 pixel bewegt, dann bewegt sich das image um 100pix negativ



wie komme ich auf die 160/0.8 also auf 160 weiss ich wie aber wie auf die 0.8? rechenweg?

EDIT: ah die 80% / 100 alles kla^^ fals ich falsch liegt sags^^


Edit:
Nein es funktioniert rein gar nich, also folgendes:

In SichtW=1000
In BereichW=800 damit wir bei dem beispiel bleiben 1000 zu 800

meine rechnung is dort ja genaustens zu verfolgen.


Code: [AUSKLAPPEN]
SichtW:Float = Self.W - 16
               BereichW:Float = Self.ScrollX
               
               
               MaxLeng:Float = Float(SichtW) / Float(BereichW)
               SetColor 192, 192, 192
               DrawRect Self.X + 1, Self.Y + Self.H - 15, SichtW, 15
               SetColor 0, 0, 0
               DrawRect Self.X + 1 + 1, Self.Y + Self.H - 15 + 1, SichtW - 2, 15 - 2
               BereichProzent:Float =BereichW/100
               SichtbarProzent:Float = SichtW / 100
               
               ProzentSumme = BereichProzent * SichtbarProzent
               Mov:Float = SichtW / 100 * ProzentSumme
               MaxMov:Float = (SichtW - Mov) / (ProzentSumme / 100)


und nun kommt die sache mit der cam
Code: [AUSKLAPPEN]
Self.CamX = Self.CamX + 1
                     If Self.CamX > MaxMov Then Self.CamX = MaxMov


der balken fährt voll aus der leiste raus. und ein ende gibt es somit denk ich auch nich.
rückgabe wert von BisMov = 1.#INF0000


mache ich es aber so:

Code: [AUSKLAPPEN]
   Self.CamX = Self.CamX + 1
                     If Self.CamX > MaxMov Then Self.CamX = MaxMov

verhält sich der balken völlig richtig, aber man sieht nich den gesammten inhalt des fensters. der button der bis 1000 geht erscheint nicht.

Midimaster

BeitragSa, Jul 28, 2012 9:57
Antworten mit Zitat
Benutzer-Profile anzeigen
ich blick nicht ganz mit deinen variablennamen durch, aber hier mein Beispiel:

BlitzMax: [AUSKLAPPEN]
SuperStrict
Graphics 800,600

Global FensterBreite#=600, BildBreite#=900, ScrollPosX#=0
Global ScrollBarFaktor#=FensterBreite/BildBreite
Global FPS:TTimer=CreateTimer(60)
Repeat
SetClsColor 0,0,255
SetColor 255,255,255
Cls
DrawRect 100,100,FensterBreite,300
SetColor 111,111,111
DrawRect 100,100,FensterBreite,15
SetColor 55,55,55
DrawRect 100+ScrollPosX,100,FensterBreite*ScrollbarFaktor,15
SetColor 255,0,0
DrawRect 100-ScrollPosX/ScrollbarFaktor,150,BildBreite,20
If MouseDown(1)
Local localX#=MouseX()-100
If (localX>=0) And (localX<=(1-ScrollbarFaktor)*FensterBreite)
ScrollPosX=LocalX
EndIf
EndIf
Flip 0
WaitTimer FPS
Until KeyHit(Key_Escape)
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Mathias-Kwiatkowski

BeitragSa, Jul 28, 2012 11:38
Antworten mit Zitat
Benutzer-Profile anzeigen
jop nichts anderes habe ich ausser das man bei mir auf buttons klicken muss. und dennoch wird der komplette inhalt nicht angezeigt,. warum auch immer

meine abfrage muss so lauten, damit der komplette inhalt im fenster angezeigt wird
If Self.CamX > Self.ScrollX - SichtW Then Self.CamX = Self.ScrollX - SichtW

aber dann stimmt die slider Grösse nicht mehr und des ding fährt bedenkenslos aus dem fenster raus

Midimaster

BeitragSa, Jul 28, 2012 13:17
Antworten mit Zitat
Benutzer-Profile anzeigen
aber das eine hat doch nichts mit dem anderen zu tun.... die Slidergröße ist doch immer FensterGröße*Fenstergröße/BildGröße und unabhängig vom ScrollX
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Mathias-Kwiatkowski

BeitragSa, Jul 28, 2012 14:01
Antworten mit Zitat
Benutzer-Profile anzeigen
darauf kam ich auch

beachte nur die X zeichnung


Code: [AUSKLAPPEN]
Method Draw(XW:Float = 0, YW:Int = 0)
      For BGUI:TBaseGui = EachIn BaseGuiList
         If bgui.Window = Self.Win Then
            XX:Float = bgui.Window.CamX / bgui.Window.FaktorX
            YY:Float = bgui.Window.Camy
         EndIf
      Next
      
      XW = XW + Self.X - xx
      YW = YW + Self.Y - yy
      

      
      SetColor 192, 192, 192
      DrawRect XW + 1, YW + 1, Self.W - 1, Self.H - 1
      SetColor Self.Color[0], Self.Color[0], Self.Color[0]
      DrawLine XW, YW, XW + Self.W, YW
      DrawLine XW, YW, XW, YW + Self.H
      SetColor Self.Color[1], Self.Color[1], Self.Color[1]
      DrawLine XW + Self.W, YW, XW + Self.W, YW + Self.H
      DrawLine XW, YW + Self.H, XW + Self.W, YW + Self.H
      
      SetColor Self.Color[1], Self.Color[1], Self.Color[1]
      DrawText Self.Text, XW + Self.W / 2 - TextWidth(Self.Text) / 2, YW + Self.H / 2 - TextHeight("W") / 2
      SetColor Self.Color[0], Self.Color[0], Self.Color[0]
      DrawText Self.Text, XW + Self.W / 2 - TextWidth(Self.Text) / 2 + 1, YW + Self.H / 2 - TextHeight("W") / 2 + 1
      
      For BGUI:TBaseGui = EachIn BaseGuiList
         If bgui.Window = Self.Win Then
            'Auf dem Button Fahren und Klicken, wenn fenster activ ist
            If bgui.Window.Activ = 1 Then
               If BaseMouseX > bgui.Window.X And BaseMouseX < bgui.Window.X + bgui.Window.W And BaseMouseY > bgui.Window.Y + 2 + TextHeight("W") And BaseMouseY < bgui.Window.Y + bgui.Window.H Then
                  If BaseMouseX > XW And BaseMouseX < XW + Self.W And BaseMouseY > YW And BaseMouseY < YW + Self.H Then
                     Self.Activ = 1
                  Else
                     Self.Activ = 0
                  End If
                  
                  If BaseMouseButtonLeft = 2 And Self.Activ = 1 Then
                     Self.ButtonActiv = 1
                  Else
                     Self.ButtonActiv = 0
                  EndIf
               Else
                  Self.Activ = 0
                  Self.ButtonActiv = 0
               EndIf
            End If
            'Errechnen ob buttonweite grösser als window weite ist

            If Self.X + Self.W > bgui.Window.W - 2 Then
               If Self.X + Self.W > bgui.Window.ScrollX Then bgui.Window.ScrollX = Self.X + Self.W + 2
            EndIf

            If Self.Y + Self.H > bgui.Window.H - TextHeight("W") - 2 Then
               If Self.Y + Self.H > bgui.Window.ScrollY Then bgui.Window.Scrolly = Self.Y + Self.H + TextHeight("W") + 2
            EndIf
            
         End If
      Next
      
      If Self.Activ = 1 Then
         Self.Color[0] = Self.Color[0] - 4
         If Self.Color[0] < 0 Then Self.Color[0] = 0
         Self.Color[1] = Self.Color[1] + 4
         If Self.Color[1] > 255 Then Self.Color[1] = 255
      End If
      If Self.Activ = 0 Then
         Self.Color[0] = Self.Color[0] + 4
         If Self.Color[0] > 255 Then Self.Color[0] = 255
         Self.Color[1] = Self.Color[1] - 4
         If Self.Color[1] < 0 Then Self.Color[1] = 0
      End If
      SetColor 255, 255, 255
   End Method

Midimaster

BeitragSa, Jul 28, 2012 14:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Sei mir nicht böse... aber ich habe keine Ahnung, was dein Code hier tut. Ungenaue Variablennamen und fehlende Kommentierung in Kombination mit "nur Teil-Code" statt eines lauffähigen Beispiels machen es für Dritte nahezu unmöglich dir zu helfen.

Auch sind deine Beschreibungen, was noch nicht zufriedenstellend läuft so kurz, dass man nicht wirklich erfährt, wo Du nun beraten werden willst....


Ich werde ja demnächst ein GUI-Tutorial hier schreiben. Da wird der Slider einfach aus 2 Gadgets bestehen. Das eine ist die umgebende Mutter und darin als zweites Gadget ein Rechteck, dass sich nur innerhalb der Mutter bewegen darf. Dieses Gadget hat dann die Eigenschaft ScrollEnable=YES und BorderTyp=IN_BORDER, was bedeutet, das der Slider sich innerhalb der Mutter bewegen darf aber nicht darüber hinaus.

Ein Fenster, in dem damit ein zu großes Bild bewegt werden kann, wären wieder zwei solche Gadgets. Das Fenster wäre die Mutter, das bild wäre das Child mit den Eigenschaften ScrollEnable=YES und BorderTyp=OUT_BORDER, was dann wiederum bedeutet, dass man das innere Objekt nur soweit bewegen kann das seine AußenKanten nie im Fenster zu sehen sein dürfen.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Mathias-Kwiatkowski

BeitragMo, Dez 17, 2012 19:27
Antworten mit Zitat
Benutzer-Profile anzeigen
hi nach langer zeit kann ich vieleicht weitermachen ^^...

also das problem des sliders ist immernoch aktuell.
mein problem sind die angaben.

ich habe 3 ("Weiten") um es bildlich zu machen so:
user posted image

erst mal fenster weite dann im fenster die sliderweite und dann noch das gesammte was man ja nicht sieht aber das gescrollt werden muss.

in meinem programm möchte ich es gern so machen
Slider.Set (Bis)
Slider.Get()

das heisst, mit slider.set möchte ich dem slider nun mitteilen das er z.b. 200 pixel scrollen soll
mit slider.get möchte ich erfragen an welcher position sich nun der lustige schieberegler befindet.

ich habe mir nun mehrfach alles durchgelesen und auch mehrfach durchgearbeitet, was von dir (Midmaster) kam. aber alles passt nicht wirklich.

dein bsp. funktioniert natürlich, hat ja auch eine angabe weniger. und wenn ich nun sag der slider muss 200 pix scrollen dann darf er auch nur 200. mit dem bsp funktioniert es nicht so wirklich ganz.

ok meine probleme, sind:
herrauszufinden wie ich den scrollbalken vom slider eine maximale weite gebe ( so das er z.b. auch nur 200 pix weit scrollt.)

die richtige positionsabfrage (wo steht der slider)

vieleicht weiss nun jemand ein rat den ich nun befolgen kann. oder ein rechenweg. da es eigentlich nur eine rechnerei ist.

Mathias-Kwiatkowski

BeitragMo, Dez 17, 2012 19:27
Antworten mit Zitat
Benutzer-Profile anzeigen
hi nach langer zeit kann ich vieleicht weitermachen ^^...

also das problem des sliders ist immernoch aktuell.
mein problem sind die angaben.

ich habe 3 ("Weiten") um es bildlich zu machen so:
user posted image

erst mal fenster weite dann im fenster die sliderweite und dann noch das gesammte was man ja nicht sieht aber das gescrollt werden muss.

in meinem programm möchte ich es gern so machen
Slider.Set (Bis)
Slider.Get()

das heisst, mit slider.set möchte ich dem slider nun mitteilen das er z.b. 200 pixel scrollen soll
mit slider.get möchte ich erfragen an welcher position sich nun der lustige schieberegler befindet.

ich habe mir nun mehrfach alles durchgelesen und auch mehrfach durchgearbeitet, was von dir (Midmaster) kam. aber alles passt nicht wirklich.

dein bsp. funktioniert natürlich, hat ja auch eine angabe weniger. und wenn ich nun sag der slider muss 200 pix scrollen dann darf er auch nur 200. mit dem bsp funktioniert es nicht so wirklich ganz.

ok meine probleme, sind:
herrauszufinden wie ich den scrollbalken vom slider eine maximale weite gebe ( so das er z.b. auch nur 200 pix weit scrollt.)

die richtige positionsabfrage (wo steht der slider)

vieleicht weiss nun jemand ein rat den ich nun befolgen kann. oder ein rechenweg. da es eigentlich nur eine rechnerei ist.

EDIT doppelpost. aus unerklärlichen gründen wurde mein beitrag 2 mal gesand.
ich möchte mich für den doppelpost entschuldigen.
 

PhillipK

BeitragMo, Dez 17, 2012 19:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist ne reine logiksache, gelle?

Ich würde das ganze mit Floatzahlen regeln (alternativ double)

1) Du brauchst die Breite vom Slider-Pin (dat ding was gezogen wird)
2) Du brauchst die breite vom Slider generell (dat ding, wo der pin drauf läuft)
3) Nun rechnest du widht - pin_width als "slider breite"

4) Wenn du den wert abfragst, gib eine zahl zwischen 0.0 und 1.0 zurück: startpunkt_des_pins / double(bei_3_errechnete_breite)
5) Beim setzen musst du lediglich drauf aufpassen, das der wert zwischen 0 und der von 3) errechneten breite leigt, ansonsten auf 0 bzw auf MaxBreite setzen Smile

Um nun den fensterinhalt zu verschieben, könntest du SetOrigin() nutzen. als wert für x nimmst du: (Breite_gesamtzeugs - Breite_sichtbares) * Slider.get()
Eventuell noch mit den vorzeichen spielen, dafür bin ich immer zu blöde *g*

Sinn dahinter ist, das du eine gleit-breite hast (die differenz zwischen sichtbaren und gesamt) und diesen mit der Sliderposition verrechnet. Bei 1 gibt es logischerweise die volle verschiebung, was darin resultiert, das du den letzten sichtbaren teil siehst. Bei 0 gibt es den anfangsbereich, wie in deiner skizze dargestellt =)

Und nochmal zur erinnerung: Bei beidem, sliderbreite und slider-pin-breite, sowie Sichtbaren und Totales,mögliches, sichtbare brauchst du die Differenz. Arbeitest du mit den ganzen werten, wird es verzerrt aussehen Sad

Okay ich merke, ich hab mal wieder nicht das zeug, zu erklären. Ich schaue gleich mal, das ich meine idee umsetze, schön abgepackt als Type =) (editiere ich dann hier rien)

Mathias-Kwiatkowski

BeitragMo, Dez 17, 2012 20:00
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
Ich würde das ganze mit Floatzahlen regeln (alternativ double)

1) Du brauchst die Breite vom Slider-Pin (dat ding was gezogen wird)
2) Du brauchst die breite vom Slider generell (dat ding, wo der pin drauf läuft)


genau das is ja das problem alleine herrauszufinden wie gross der slider sein darf...
je mehr inhalt desto kleiner wird ja laut logig der balken, ... das das ganze in float sein sollte ist an sich schon kla.

Midimaster

BeitragMo, Dez 17, 2012 20:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Mathias....

deinem Beispielbild fehlt eine Rahmenbox... nämlich, die worin sich der Slider bewegen darf. Die ist aber wichtig für die Berechnungen.

Soll die in dem Beispielbild ebenfalls 500 breit sein? und darin der Slider mit 300?

Oder meinst du mit den 300 den Sliderrahmen und darin soll der (dann kleinere) Silder nur richtig verschoben werden?


Wenn Dein Originalbild 1000 breit ist und das Fenster 500, dann folgt daraus, dass der Sliderrahmen 500 und der Slider 250 sein muss! und eben nicht 300!!! Das kann du probieren wie du willst das geht nie auf!

Slider zu SliderRahmen immer wie Bild zu Fenster!!!

Einen Slider von 250 in einem Rahmen von 500 kannst du um 250 bewegen. Und das entspricht genau dem was sich das Original-Bild in seinem Fesnter bewegen kann, nämlich ein 1000er Bild um 500 in einem 500er Rahmen


Experimentiere in meinem Beispiel noch mal mit den beiden Werten bei ...

Global FensterBreite#=...
Global BildBreite#=....

....rum, und du wirst sehe es geht immer, egal welche Werte du reinschreibst!
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
  • Zuletzt bearbeitet von Midimaster am Mo, Dez 17, 2012 20:31, insgesamt einmal bearbeitet

Mathias-Kwiatkowski

BeitragMo, Dez 17, 2012 20:27
Antworten mit Zitat
Benutzer-Profile anzeigen
also die rahmenbox is vorhanden, da ich ja nicht weiss wie gross der slider sein darf fehlt also der slider.

aber was is wenn der sliderrahmen nunmal 300 ist?

ich kann ja angeben wo der slider ist also

x,y,w,h

start x (x)
start y (y)
ende width (w)
ende height (h)

so der rahmen ist nun 300 wie gross der slider ist weiss der hund ^^ und das fenster ist 500 gross. aber das bild 1000

Midimaster

BeitragMo, Dez 17, 2012 20:32
Antworten mit Zitat
Benutzer-Profile anzeigen
na, wenn der sliderrahmen nur 300 ist, dann darf der slider nur 150 sein.
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Mathias-Kwiatkowski

BeitragMo, Dez 17, 2012 20:35
Antworten mit Zitat
Benutzer-Profile anzeigen
das heisst also
sliderboxweite / ( fenster / gesammtbild )

dieses müsste dann ja die richtige rechnung sein oder?

Midimaster

BeitragMo, Dez 17, 2012 20:42
Antworten mit Zitat
Benutzer-Profile anzeigen
so hier jetzt ein code mit variablem sliderrahmen

BlitzMax: [AUSKLAPPEN]

SuperStrict
Graphics 800,600

Global FensterBreite#=500, BildBreite#=1000, ScrollPosX#=0

' nun mal so Rahmen ungleich Fenster
Global RahmenBreite#=300
Global SizeFaktor#=FensterBreite/RahmenBreite

Global ScrollBarFaktor#=FensterBreite/BildBreite
Global FPS:TTimer=CreateTimer(60)
Repeat
SetClsColor 0,0,255
Cls
' das Fenster in weiß:
SetColor 255,255,255
DrawRect 100,100,FensterBreite,300

' der Slider-Rahmen in grau
SetColor 111,111,111
DrawRect 100,100,RahmenBreite,15

' der Slider in dunkelgrau:
SetColor 55,55,55
DrawRect 100+ScrollPosX,100,RahmenBreite*ScrollbarFaktor,15

' das Bild in rot
SetColor 255,0,0
DrawRect 100-ScrollPosX/ScrollbarFaktor*SizeFaktor,150,BildBreite,20



If MouseDown(1)
Local localX#=MouseX()-100
If (localX>=0) And (localX<=(1-ScrollbarFaktor)*RahmenBreite)
ScrollPosX=LocalX
EndIf
EndIf
Flip 0
WaitTimer FPS
Until KeyHit(Key_Escape)
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

Mathias-Kwiatkowski

BeitragMo, Dez 17, 2012 21:07
Antworten mit Zitat
Benutzer-Profile anzeigen
wenn ich es so mache so wie du dein code verwendest, funktioniert es eben nicht.

ich habe nun in meinem type die variabeln umgetippert, so wie du sie genutzt hast. aber es geht einfach nicht ^^

das resultat ist das hier:
user posted image

ich gebe ja zu das dein testprog funktioniert. das habe ich auch zahlreiche male geschafft. aber sobald es umgesetzt wird. is einfach ende.... und mal abgesehen davon scrollen kann man das nich nenn. schau mal wie klein die balken werden. der balken auf dem desktop is nur 50 schritte lang ^^

und im fenster selber sieht man das nich durchgescrollt wird. also bis zum ende.

nur so nebenbei. von wegen uhrheberecht, es geht um die eigene gui entwicklung das hintergrundsbild ist
variabel und stammt vom amiga os 3.0 . . .



EDIT:
Code: [AUSKLAPPEN]

so benannte ich nun die felder im type
Field ScrollBarFaktor:Float
Field RahmenBreite:Float
Field SizeFaktor:Float
Field FensterBreite:Float
Field BildBreite:Float
   
und das ist nun die rechenformel

   Self.FensterBreite = Self.Haben 'weite des fensters
   Self.RahmenBreite = Self.WH - 2 'weite des rahmens vom slider
   Self.BildBreite = Self.Brauchen 'bildweite
         
   Self.SizeFaktor = Self.FensterBreite / Self.RahmenBreite
   Self.ScrollBarFaktor = Self.FensterBreite / Self.BildBreite


hier die angaben die gemacht werden können

   Method SetRange(von:Float, Bis:Float)
      Self.Haben = von
      Self.Brauchen = Bis
   End Method
   
   Method GetSlider:Float()
      Return Self.Pos / Self.ScrollBarFaktor * Self.SizeFaktor
   End Method



lustig ist das jeder slider sich anders verhällt.

Midimaster

BeitragMo, Dez 17, 2012 21:31
Antworten mit Zitat
Benutzer-Profile anzeigen
jedesmal, wenn du haben und brauchen neu festlegst, musst du auch die sliderbreite neu berechnen lassen. der Sliderrahmen bleibt ja immer gleich groß, doch der darin befindliche Slider wird größer oder kleiner.

Schließlich repäsentiert er das Verhältnis von Fenster zu OriginalBild. Ist das Originalbild 10x so groß wie das zur Verfügung stehende Fenster, dann nimmt auch der Slider nur 1/10tel des Sliderrahmens ein. der Restplatz sind dann die 9/10tel, die auch die 9/10 des verdeckten Teils des Originalbildes repräsentieren.

Ist Self.WH wirklich die SliderRahmenbreite in Pixeln?


tipp:
printe doch mal alle Vorgabenzahlen und daraus errechnete Variablenwerte eines konkreten Beispiels in das Consolenfenster und sende uns diese Werte. Man müsste schon an den Zahlen sehen, wo es hakt!
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
  • Zuletzt bearbeitet von Midimaster am Mo, Dez 17, 2012 21:42, insgesamt 2-mal bearbeitet
 

PhillipK

BeitragMo, Dez 17, 2012 21:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Okay tut mir leid, ich steige durch die namen der variablen nicht ganz so durch Sad

Du schreibst, das du ein type hast, was die scrollbar regelt?
Sicherheitskopie und direkt weg.

Dann leg das Type in einer Testumgebung neu an, ähnlich minimalistisch wie midimaster's code.

Ich mach das (jetzt endlich) auch einmal: Ein kleines absolutes mini-type schreiben, was nur 3 methoden und eine funktion hat:
SetSlider(), GetSlider(), Draw() und als funktion : Create Smile

Das draw spielt hier die wichtigste rolle, deshalb die testumgebung:
Es soll absolut nix anderes machen, wie einen fixwert Breite und Höhe entgegen nehmen (das, was später durch den slider verändert werden soll) und eine Diagonale Linie darstellen. Schwer? Nein.
Grund ist ganz einfach: Sollte dein slidercode korrekt sein und das drawen verzogen, ist es schwer festzustellen.
Wenn sich alles gleich verhält, ist es vielleicht auch nurn minibug.. irgendwo ne Globale statt lokale angesprochen. Egal - neu machen, austesten. Ist ja nicht viel code =)

EDIT:

Hui, ich muss sagen, dafür das die rechnungen recht simpel sind, verfranze ich mich auch ständig.
Hab nun ein kleines type angelegt, was über einen Viewport und Origin ein "fenster" simuliert und einen inhalt dort anzeigt.
Ich bastel das grade noch ein wenig aus und entferne diverse fix-werte, damit das ganze nachvollziehbar bleibt. Grafisch HOCH AUFWENDIG, es stellt immerhin ein vollwertiges fenster und einen fullhd-guislider dar
:>
(4 lines als rahmen, 2 rects, einer ist der anfasser, einer der slider...)


EDIT 2:
Herzlichen glückwunsch, phillip Wink
Hab doch glatt meinen eigenen bday vergessen, weil mich das problem grade so gefesselt hat Very Happy

Hier mal mein code. Enthalten sind ein TSlider Type, welches ein paar schnittstellen zum ansteuern und zeichnen enthält.
Ein paar wichtige sachen wirst du für dich ändern müssen, zb musste mein Slider wissen, wie breit das fenster / der inhalt ist (zur berechnung) und ausserdem wie hoch ein fenster ist (zum zeichnen)

Obwohl ich versucht habe, das ganze einfach zu halten, ist es doch ne ecke komplexer geworden. Anyways, ich hab viele kommentare reingebombt, vielleicht hilft es dir ja Smile

Anmerkung: Ich habe differenziert zwischen *beispiel* SetPosition und SetTotalPosition.
Die GetPos, SetPos dinger etc beziehen sich auf double werte zwischen 0 und 1. Halt "wie weit" der pin auf dem slider gewandert ist.

Der Total-krams bezieht sich auf pixeleinheiten auf Slider-breite gebracht. NICHT auf die Mitte des Pins! Oder ums besser zu sagen: Total = normal * breite.
Ist eher ne persöhnliche vorliebe.. Kick die dinger raus, wenn du sie nicht brauchst - sonst killt das die übersichtlichkeit Smile


Die Draw-Schnittstelle musst du selber einbauen und eventuell auch ganz woanders einbauen. Hier stört zb, das der Slider Breite (höhe?) vom INHALT (Bild, text, etc) wissen muss. Ebenso das ich überall zumindest die Fensterbreite brauche.
Um dir die möglichkeit des nachvollziehens zu geben, habe ich recht eindeutige namen gewählt und alles brav als Fields abgepackt.

CODE:
BlitzMax: [AUSKLAPPEN]
SuperStrict

Const WINDOW_SIZE_X:Int = 1024
Const WINDOW_SIZE_Y:Int = 768


Type TSlider

'goodie: "Fensterposition" um diese in die DrawBerechnung mit einfließen zu lassen :)
Field WindowPosX:Int = 50
Field WindowPosY:Int = 50
Field WindowSizeX:Int = 0
Field WindowSizeY:Int = 0

Field ContentWidth:Int = 0

'Nötiges, um die berechnugnen durchzuführen:
Field sizeX:Int = 0
Field sizeY:Int = 0
Field pinSizeX:Int = 0
Field pinSizeY:Int = 0

'Internes: _pos als momentane sliderposition
Field _pos:Double = 0.0
'Internes: _active, um festzustellen, ob überhaupt etwas "scrollbares" dargestellt werden muss.
Field _active:Int = 1

Function Create:TSlider(fensterBreite:Int, inhaltBreite:Int, fensterHoehe:Int)
'Fensterbreite bezieht sich auf den Sichtbaren bereich, dein Viewport.
'inhaltBreite bezieht sich auf das totale ganze.

Local slider:TSlider = New TSlider
slider.WindowSizeX = fensterBreite
slider.WindowSizeY = fensterHoehe

slider.ContentWidth = inhaltBreite

slider.sizeX = fensterBreite
slider.sizeY = 30

If inhaltBreite = 0 Or (fensterBreite >= inhaltBreite) Then
slider._active = 0
Else
slider._active = 1
slider.pinSizeX = slider.sizeX * (Double(fensterBreite) / Double(inhaltBreite))
slider.pinSizeY = slider.sizeY
EndIf

Return slider
End Function

Method SetTotalPosition:Int(pos:Int)
If pos < 0 Then pos = 0
If pos > sizeX Then pos = sizeX

_pos = Double(pos) / Double(sizeX) 'Warnung: Stellt nicht den startpunkt des sliders dar, sondern den umgerechneten punkt auf dem Scrollbalken :)
End Method
Method SetPosition:Int(pos:Double)
If pos < 0 Then pos = 0
If pos > 1 Then pos = 1
_pos = pos
End Method
Method GetPosition:Double()
Return _pos
End Method
Method GetTotalPosition:Int()
Return _pos * sizeX ' Warnung: Stellt nicht den startpunkt des sliders dar, sondern den umgerechneten punkt auf dem Scrollbalken :)
End Method

Method doStep:Int(px:Int)
'doStep ist eine hilfsfunktion, der man pixel-einheiten einer bewegung am slider übergibt. Zb Von MouseXSpeed(). Sie rechnet den pixelwert in die eigentliche Position.
Local fak:Double = Double(px) / Double(sizeX - pinSizeX)
_pos:+fak

'Clamping: Verhindern, das der slider seinen rahmen sprengt :)
If _pos > 1 Then _pos = 1
If _pos < 0 Then _pos = 0
EndMethod

Method calcPosition:Double(x:Int)
'x steht für die gewünschte mitte des sliders. Typischerweise für MouseX()-self.windowPosX zu verwenden :)
Return (Double(x - (pinSizeX * 0.5)) / Double(sizeX - pinsizex))
End Method

Method calcTotalPosition:Int(x:Int)
'x steht für die gewünschte mitte des sliders.
Return (Double(x - (pinSizeX * 0.5)) / Double(sizeX - pinsizex)) * sizeX
End Method

Method Resize:Int(fensterBreite:Int, inhaltBreite:Int, fensterHoehe:Int)
WindowSizeX = fensterBreite
WindowSizeY = fensterHoehe

ContentWidth = inhaltBreite

sizeX = fensterBreite
sizeY = 30

If inhaltBreite = 0 Or (fensterBreite >= inhaltBreite) Then
_active = 0
Else
_active = 1
pinSizeX = sizeX * (Double(fensterBreite) / Double(inhaltBreite))
pinSizeY = sizeY
EndIf
End Method


Method Draw:Int()
Local x:Int = windowPosX 'faulheit: Da ich diese beiden variablen nur zum nachvollziehen mit einbaue, kürze ich sie hier mit x und y ab.
Local y:Int = windowPosY

'------ Scrollbalken part

If _active Then
'slider hat was zu tun: Zeichnen.
SetColor(150, 150, 150)

'Den Hintergrund, sprich der slider an sich :)
DrawRect(x, y + WindowSizeY - pinSizeY, sizeX, sizeY) 'ACHTUNG: Hier habe ich von der höhe pinSizeY abgezogen, damit der slider noch innerhalb des "Fensters" liegt


SetColor(255, 255, 255)

'Den Anfasser, den ich generell überall als Pin bezeichne
DrawRect(x + (WindowSizeX - pinSizeX) * Self.GetPosition(), y + WindowSizeY - pinSizeY, pinSizeX, pinSizeY) 'ACHTUNG: Hier habe ich ebenfalls pinSizeY der höhe abgezogen.

EndIf

'"rahmen" zeichnen. -> Für das Gedachte fenster drumrum.
SetColor(255, 230, 230)
DrawLine(x, y, WindowSizeX + x, y)
DrawLine(WindowSizeX + x, y, WindowSizeX + x, WindowSizeY + y)
DrawLine(WindowSizeX + x, WindowSizeY + y, x, WindowSizeY + y)
DrawLine(x, WindowSizeY + y, x, y)
SetColor(255, 0, 0)

'"inhalt" zeichnen. -> Um den Scrolleffekt sichtbar zu machen. Achte auf SetViewport und SetOrigin - diese befehle sind nur die faulste methode die mir eingefallen sind.
' In wirklichkeit kannst du alles mit dem Self.GetPosition() wert anfangen, was du magst :)
SetViewport(x, y, WindowSizeX, WindowSizeY)
SetOrigin(-Self.GetPosition() * (ContentWidth - WindowSizeX), 0)

'Der eigentliche inhalt: eine Diagonale linie, um den scrolleffekt sichtbar zu machen.
DrawLine(x, y, ContentWidth + x, WindowSizeY + y - pinSizeY) 'ACHTUNG: Ums korrekt darzustellen, hab ich hier pinSizeY abgezogen *g* Der Platz des sliders eben.

'Wieder aufräumen:
SetViewport(0, 0, WINDOW_SIZE_X, WINDOW_SIZE_Y)
SetOrigin(0, 0)

SetColor(255, 255, 255)

End Method


'Steuerung:
Method isPointInside:Int(x:Int, y:Int)

Local sliderSX:Int = WindowPosX + (WindowSizeX - pinSizeX) * Self.GetPosition()
Local sliderSY:Int = WindowPosy + WindowSizeY - pinsizeY



'Soll prüfen, ob ein punkt innerhalb des sliders ist und ob dieser eventuell sogar auf dem pin sitzt.
If x < WindowPosX Or y < WindowPosY Or x > WindowPosX + WindowSizeX Or y > WindowPosY + WindowSizeY Then
Return 0 ' ganz und gar ausserhalb des fensters.
EndIf
If y < sliderSY Then
Return 0 ' oberhalb des sliders? schlecht.
EndIf
If x >= sliderSX And x <= sliderSX + pinSizeX And y >= sliderSY And y <= sliderSY + pinSizeY Then
Return 2 'auf dem slider`- pin
EndIf

Return 1 ' nur irgendwo auf dem slider
End Method
End Type




Graphics(WINDOW_SIZE_X, WINDOW_SIZE_Y)

Local winWidth:Int = 500
Local contentWidth:Int = 2000


Local slider:TSlider = TSlider.Create(winWidth, contentWidth, 500)

While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()

Select slider.isPointInside(MouseX(), MouseY())
Case 0 ' nix..
Case 1 ' auf dem slider: Punkt umrechnen und Totale Position setzen.
If MouseHit(1) Then
slider.SetPosition(slider.calcPosition(MouseX() - slider.WindowPosX))
FlushMouse()
EndIf
Case 2 ' auf dem slider-pin: MouseXSpeed() übertragen.
If MouseDown(1) Then slider.doStep(MouseXSpeed())
End Select

MouseXSpeed() 'aufrufen, um wert "frisch" zu halten

Cls

slider.Draw()

contentWidth:+(KeyDown(KEY_D) - KeyDown(KEY_A)) * 5
slider.Resize(winWidth, contentWidth, 500)

Flip 1
Wend


Kurz die goodies:
isPointInside:
BlitzMax: [AUSKLAPPEN]
'Abfrage, ob maus auf dem slider ist. Returnt 0, wenn nicht, 1 wenn die maus NUR auf dem Slider ist und 2, wenn die maus auf dem Slider-Pin (Anfasser) ist.
Select slider.isPointInside(MouseX(), MouseY())


Resize:
BlitzMax: [AUSKLAPPEN]
'Updatet den Slider. Braucht Fensterbreite, Inhaltbreite (um die breite des Sliders zu berechnen), sowie die fensterhöhe (nur für zeichnung intressant. Musste ich mit reinnehmen :3
slider.Resize(winWidth, contentWidth, 500)


Getter / Setter:
SetPosition( x:double ) - Setzt die position anhand eines Skalierungswertes (von 0 bis 1)
GetPosition( x:double ) - Gibt den aktuellen positionswert.

doStep: (zum vereinfachten bewegen des pins)
BlitzMax: [AUSKLAPPEN]
'doStep ist mit Translate aus 3d engines zu vergleichen. es nimmt zb -1 oder 1 als wert. Der wert entspricht (je nach gleitzahlen ungenauigkeit) etwa einer anzahl pixeln ( wert: -1 = ungefähr -1 pixel bewegung auf den slider)
slider.doStep(MouseXSpeed())


calcPosition:
BlitzMax: [AUSKLAPPEN]
'Berechnet den nötigen pos-wert, um den Slider mittig zu platzieren. 
'ACHTUNG: Da der Slider das fenster eigentlich nicht umbedingt kennen sollte, muss man hier die fensterposition von der Mausposition zb abziehen :) Das hardcoded zu übernehmen ist einfach dreckig.. :3
slider.calcPosition(MouseX() - slider.WindowPosX)

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group