:resize über Faktor [erledigt]

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

:resize über Faktor [erledigt]

Beitrag von AUGE_OHR »

hi,

bei :resize werden ja die Parameter aOldSize und aNewSize übergeben.

nun kann man zum :resize mit "absolut %" oder mit einem "Faktor %" arbeiten

Code: Alles auswählen

 // volle Grösse "aussen
 aDraw  := oDlg:CurrentSize()

 oDraw  := oDlg:drawingArea
 aChild := oDraw:Childlist()
 iMax   := LEN(aChild)
 oDraw:LockUpdate(.T.)
 i     := 1
 FOR i := 1 TO iMax
    aSize := aChild[i]:currentsize()
    aPos  := aChild[i]:currentPos()

    aSize[1] := CalcSize(aSize[1],aOldSize[1],aNewSize[1])
    aSize[2] := CalcSize(aSize[2],aOldSize[2],aNewSize[2])

    aPos[1]  := CalcPos(aPos[1],aOldSize[1],aNewSize[1])
    aPos[2]  := CalcPos(aPos[2],aOldSize[2],aNewSize[2])

    aChild[i]:setposandSize(aPos,aSize)
    DO CASE
mit den Function

Code: Alles auswählen

FUNCTION CalcSize(nSize,nOldSize,nNewSize)
LOCAL nNum
   nNum := ROUND(nNewSize/nOldSize*nSize,0)
RETURN nNum

FUNCTION CalcPos(nPos,nOldSize,nNewSize)
LOCAL nNum
   nNum := ROUND(nNewSize/nOldSize*nPos,0)
RETURN nNum
hat man aber einen "Rundungs Fehler" bei der Darstellung / Position der sich mit der Zeit summiert.

jemand eine Idee wie man das "ausgleichen" könnte ?
Zuletzt geändert von AUGE_OHR am Sa, 12. Jun 2010 19:57, insgesamt 1-mal geändert.
gruss by OHR
Jimmy
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: :resize über Faktor

Beitrag von Herbert »

Ich behalte die Originalgrösse der Fenster. Auf diese Weise kann man stets von diesen Werten her rechnen

Oder du definierst eine Variable des Objekts, in welcher du den Zoomfaktor festhälst. So kennst du jederzeit die Originalgrösse wieder und verlierst nicht durch die ewigen Rundungen den Ausgangswert.
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: :resize über Faktor

Beitrag von AUGE_OHR »

Herbert hat geschrieben:Ich behalte die Originalgrösse der Fenster. Auf diese Weise kann man stets von diesen Werten her rechnen

Oder du definierst eine Variable des Objekts, in welcher du den Zoomfaktor festhälst. So kennst du jederzeit die Originalgrösse wieder und verlierst nicht durch die ewigen Rundungen den Ausgangswert.
hm ... ja ... die Original Grösse ist die vom Formdesigner ...

angenommen dir Maske war für 800x600 ausgelegt und nun mit 1600x1200 maximiert.

Code: Alles auswählen

#define nWide 800
#define nHigh  600
aOldSize := {nWide,nHigh}
aNewSize := {1600,1200}
wenn ich also von der original Grösse ausgehe hatte ich "prozentual"

Code: Alles auswählen

nNum    := nNewSize/nOldSize*nSize
wobei dann Rundungs Fehler entstehen
ich müsste also mit Pixel "rechnen" ?

Code: Alles auswählen

nDiff   := nNewSize-nOldSize
nProz   := nWide/nDiff
nNum    := nSize+(nSize*nProz)
aber da kommt "so" ja das selbe raus. Ich muss ja auch hier auch über nProz gehen ... oder ?

Wenn ich "neu" eine solche Maske anlege "weiss" ich :
a.) wieviele Childs auf der :drawingArea sind
b.) würde ich die Object in ein Array aufnehmen ... oder aus dem Array :create()n

nun hab ich aber die Maske mit "hunderten" von XbParts und muss durch die :Childlist() "blind" die Childs resizen ...
Die "prozentuale" Methode funktioniert bei Maximize/Normalize durchaus "akzeptabel" wenn man nur das macht,
aber wenn ich mit der Maus das Fenster paar mal vergrössere / verkleinere sieht man doch paar Pixel Unterschiede.

ok das könnte ich mit :border := XBPDLG_DLGBORDER unterbinden, aber ich frage mich ob man vielleicht "in Stufen" ein resize machen könnte ? wenn man jeweils 10 % Schritte, was dann auch besser mit dem Font "passt", hätte müsste es ja "passen", oder ?
gruss by OHR
Jimmy
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: :resize über Faktor

Beitrag von AUGE_OHR »

hi,

Code: Alles auswählen

oDraw:LockUpdate(.T.)
// für 800x600 auf 8/6 Pixel
aNewSize := {INT((aNewSize[1])/8),INT((aNewSize[2])/6)}
aOldSize := {INT((aOldSize[1])/8),INT((aOldSize[2])/6)}
i     := 1
FOR i := 1 TO iMax
   aSize := aChild[i]:currentsize()
   aPos  := aChild[i]:currentPos()

   aSize[1] := CalcSize(aSize[1],aOldSize[1],aNewSize[1],aDraw[1],1)
   aSize[2] := CalcSize(aSize[2],aOldSize[2],aNewSize[2],aDraw[2],2)

   aPos[1]  := CalcPos(aPos[1],aOldSize[1],aNewSize[1],aDraw[1],1)
   aPos[2]  := CalcPos(aPos[2],aOldSize[2],aNewSize[2],aDraw[2],2)

   aChild[i]:setposandSize(aPos,aSize)
   DO CASE
so nun habe ich die Grössen korrigiert die nur noch ein "vielfaches" haben können, oder ?

Code: Alles auswählen

FUNCTION CalcSize(nSize,nOldSize,nNewSize,nFull,nNo)
LOCAL nNum
   nNum    := nNewSize/nOldSize*nSize
trotzdem "verschieben" sich immer noch die XbPart um ein paar Pixel ... :banghead:
gruss by OHR
Jimmy
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14662
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: :resize über Faktor

Beitrag von Jan »

Moin Jimmy,

meiner Meinung nach wirst Du das nur lösen können, wenn Du ausschließlich von einer Startgröße ausgehst und alle Berechnungen darauf ausrichtest. Sonst wirst Du immer wieder in die Rundungsfalle laufen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: :resize über Faktor

Beitrag von AUGE_OHR »

moin,

damit kann man zwischen Normalize und Maximize resizen ohne das Pixel "verschoben" werden.

Code: Alles auswählen

// alter Masken Grösse alz Bezug
#define nWide 800
#define nHigh 600

FUNCTION CalcSize(nSize,nOldSize,nNewSize,nFull,nNo)
LOCAL nNum
LOCAL nProz
LOCAL aSize := AppDeskTop():currentsize()

   IF nNo   == 1
      IF (nNewSize-nOldSize) > 0
         nProz := nWide/nSize
         nNum  := MIN(aSize[1],nFull)/nProz
      ELSE
         nProz := MAX(aSize[1],nFull)/nSize
         nNum  := nWide/nProz
      ENDIF
   ELSE
      IF (nNewSize-nOldSize) > 0
         nProz := nHigh/nSize
         nNum  := MIN(aSize[2],nFull)/nProz
      ELSE
         nProz := MAX(aSize[2],nFull)/nSize
         nNum  := nHigh/nProz
      ENDIF
   ENDIF
   nNum     := ROUND(nNum,0)
RETURN nNum

FUNCTION CalcPos(nSize,nOldSize,nNewSize,nFull,nNo)
LOCAL  nNum := CalcSize(nSize,nOldSize,nNewSize,nFull,nNo)
RETURN nNum
leider geht es nur mit Normalize und Maximize sodas man oDlg:border := XBPDLG_DLGBORDER setzten muss.

Code: Alles auswählen

aDraw  := oDlg:CurrentSize()
...
aSize[1] := CalcSize(aSize[1],aOldSize[1],aNewSize[1],aDraw[1],1)
mir ist dabei aufgefallen da er mir für aDraw[1] bzw nFull 1032 statt 1024 rausgibt ... die 6 Pixel haben wohl das "verschieben" ausgemacht.

ich frage mich nur warum das dann bei "stufenlosen" resize nicht funktioniert ... :-k
gruss by OHR
Jimmy
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: :resize über Faktor

Beitrag von Herbert »

Jimmy, gibts da wieder Unterschiede zwischen Win7/Vista und/oder XP?
Grüsse Herbert
Immer in Bewegung...
Günter Beyes
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 315
Registriert: Mo, 16. Okt 2006 13:04
Wohnort: Region Stuttgart

Re: :resize über Faktor

Beitrag von Günter Beyes »

Hallo Jimmy,

wie sieht es aus, wenn du nicht nur beim Dialog bzw. der DrawingArea von der Startgröße ausgehst,
sondern entsprechend auch bei allen darauf liegenden XbParts?

Günter

Etwa so:

Code: Alles auswählen

nach oDlg:create():
oDlg:drawingArea:Cargo := oDlg:drawingArea:currentSize()

und bei allen XbParts
oXbp:cargo := { oXbp:currentPos(), oXbp:currentSize() }

Code: Alles auswählen

oDlg:drawingArea:resize := {|a,b,o|DAResize(a,b,o)}   

PROCEDURE DAResize( aOld, aNew, oDA )

aOrgDASize := oDA:cargo 

nXFactor  := aNew[1] / aOrgDASize[1]
nYFactor  := aNew[2] / aOrgDASize[2]

aChild := oDraw:childlist()
for i := 1 to len( aChild )
   oChild   := aChild[i]
   aOrgPos  := oChild:cargo[1]
   aOrgSize := oChild:cargo[2]
   aPos     := { aOrgPos[1] * nXFactor, aOrgPos[2] * nYFactor }
   aSize    := { aOrgSize[1] * nXFactor, aOrgSize[2] * nYFactor }
   oChild:setPosAndSize( aPos, aSize )
next

RETURN
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: :resize über Faktor

Beitrag von Herbert »

Super! hat mir die Idee geliefert, Dialoge generell vergrössern zu können.
Das Problem tritt dann auf, wenn in der Windows-Umgebung die Darstellung generell skaliert wird (Anzeigeeigenschaften 125% resp. 150%).

Code: Alles auswählen

PROCEDURE ResizeAll(oDraw,nFaktor)
LOCAL aChild[0],aSize[2],oChild,aPos[4]
IF nFaktor <> 1
  aChild := oDraw:childlist()
  for i := 1 to len( aChild )
    oChild   := aChild[i]
    aPos := oChild:CurrentPos()
    aPos[1] := INT(aPos[1]*nFaktor)  // (nFaktor/1.333))
    aPos[2] := INT(aPos[2]*nFaktor)  // (nFaktor/1.333))
    aSize := oChild:CurrentSize()
    aSize[1] := INT(aSize[1]*nFaktor)  // (nFaktor/1.333))
    aSize[2] := INT(aSize[2]*nFaktor)  // (nFaktor/1.333))
    oChild:setPosAndSize( aPos, aSize )
  next
ENDIF
RETURN
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12913
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: :resize über Faktor

Beitrag von AUGE_OHR »

Günter Beyes hat geschrieben:Etwa so:

Code: Alles auswählen

und bei allen XbParts
oXbp:cargo := { oXbp:currentPos(), oXbp:currentSize() }
hm ... ja ... ich könnte ja gleich nach dem oDlg:Create(), wo noch alles "original" ist, durch die :Childlist() und alle "nachträglich" mit einem :Cargo versehen.

wenn die Maske neu erstellt würde, hätte ich gleich aus einem Array (oder DBF) die XbParts :create()ed.
nun wollte ich Zeit sparen um nicht den gesamten Source durcharbeiten zu müssen, aber die Suche nach einer "einfachen" Lösung hat doch länger gedauert. (die Lösungen haben mich nicht zufrieden gestellt ...)

die letzte Lösung, welche nur mit Maximize/Normalize funktioniert, "reicht" eigentlich aus ... mehr war nicht "gefragt".
Da ich mich bei der Lösung auf "feste" Werte beziehe stimmen die Pixel auch bei mehrmaligen "hin-und-her"

ok, danke für eure Beträge. Ich denke der Thread ist damit [erledigt]
gruss by OHR
Jimmy
Antworten