Das Forentreffen 2018 findet am 20./21. April in Dresden statt. Weitere Infos hier
Anmeldungen zum Forentreffen 2018 sind auf der Anmeldeseite möglich
Zur Homepage des Deutschsprachige Xbase-Entwickler e. V.
Xbase++-Wiki des Deutschsprachige Xbase-Entwickler e. V.

lbUP

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

lbUP

Beitrag von Statler » Di, 14. Nov 2017 16:48

Hallo zusammen,

ich moechte beim Resizen meiner Browser ein Grid einhalten, es sollen nur ganze Zeilen sichtbar sein.

Meine Idee war, den Callback lbUP zu benutzen und dann den Dialog passend zu resizen.

Also: Fenster wird resized -> resize ist fertig -> Maus wird losgelassen (lbUP) -> Fenster wird angepasst.

Der lbUP (als Methode) kommt aber nicht. Definiere ich lbDOWN (Methode) ohne Weiterleitung, kommt lbUP durch. Leite ich allerding lbDOWN weiter oder ueberlade die Methode nicht, bleibt lbUP stumm.

aktuell bin ich ratlos.

Gruss

Achim

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6831
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: lbUP

Beitrag von Tom » Di, 14. Nov 2017 17:06

Warum verwendest Du nicht direkt den RESIZE-Callback des Fensters? Vorteil: Als Parameter des Codeblocks werden alte und neue Fenstergröße gereicht.
Herzlich,
Tom

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10674
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: lbUP

Beitrag von AUGE_OHR » Di, 14. Nov 2017 17:08

hi

zum "resize" positioniert man die Maus unten rechts auf dem "Gripper" und zieht es in die gewünschte Grösse.
klar benötigt man dann dazu den o:resize Callback Slot, von der o:DrawingArea, den man "füllen" muss.

Code: Alles auswählen

   oXbp:drawingArea:resize := {|mp1,mp2,obj| obj:childList()[1]:setSize(mp2) } 
zu LbUp :
wenn man ein Lbup "abfangen" will z.b. bei DragDrop muss man mit o:captureMouse() die Events "umleiten" auf das Object was den o:Lbdn ausgelöst hat.
gruss by OHR
Jimmy

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: lbUP

Beitrag von Statler » Di, 14. Nov 2017 18:09

Hallo zusammen,

>Warum verwendest Du nicht direkt den RESIZE-Callback des Fensters? Vorteil: Als Parameter des Codeblocks werden alte und neue Fenstergröße gereicht.

mache ich ja, das Resize meldet mit die aktuelle Groesse des XbpDialog. Den kann ich dort aber nicht beeinflussen. Ausserdem erfolgt das Resize quasi in Echtzeit, das sind unmengen an Vorgaengen. Darum moechte ich feststellen, wann der Vorgang definitiv zu Ende ist und dann final das Finetuning machen.

Wenn ich in dem Resize Slot per setSize () den Dialog anpasse, gibt das Chaos.

>wenn man ein Lbup "abfangen" will z.b. bei DragDrop muss man mit o:captureMouse() die Events "umleiten" auf das Object was den o:Lbdn ausgelöst hat.

Das werde ich mal probieren.

Gruss

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10674
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: lbUP

Beitrag von AUGE_OHR » Di, 14. Nov 2017 19:31

hi,
Statler hat geschrieben:
Di, 14. Nov 2017 18:09
Wenn ich in dem Resize Slot per setSize () den Dialog anpasse, gibt das Chaos.
das wäre "rekursive" [-X

---

bei o:DrawingArea:resize hast du die Parameter

Code: Alles auswählen

|aOldSize,aNewSize,self|
im Prinzip ist nur aNewSize interessant was die neue Grösse der o:DrawingArea enthält.

in dem Beispiel oben wird die gesamte o:DrawingArea vom Browser ausgefüllt deshalb

Code: Alles auswählen

o:SetSize(aNewSize)
:!: beim "resize" wird o:SetPos / o:SetSize() nur für die Child benutzt, NICHT für die o:DrawingArea (= o:ClientSize) oder das Fenster selbst (rekursiver Aufruf)

nun hat man gewöhnlich mehr als nur ein Browse in einem Fenster, also müssen auch die anderen XbParts "behandelt" werden.

die Frage die sich daraus ergibt : wie "resize" man "jedes einzelne" XbParts :?:

auch ist es nicht mit der Änderung der Grösse des XbPart getan. auch der Font müsste angepasst werden (s.a. Thema DPI Skaling). es ist ja wohl klar das es "viel Arbeit" wäre wenn man "alle" Koordinaten "einzeln" mit X- / Y-Faktor versehen würde [-X

---

nun gibt, seit v1.9x, in Xbase++ den "LayoutManager".
dabei muss man vor dem o:Create() eines XbPart einiges "erledigen" (Konstanten setzen).

dabei wird folgendes "festgehalten" :
1.) ursprüngliche Grösse des Fenster bei o:Create()
1a.) ggf Grösse des Desktop / DPI Skaling
2.) Pos/Size
3.) Font Name/Grösse

danach darf man NICHT mehr den o:Resize Callback Slot bestücken denn das macht dann der "LayoutManager".
leider scheint der "Layoutmanager" sich dabei an aOldSize zu orientieren was dazu führt das, nach mehrmaligen hin/her, Pos/Size nicht mehr stimmen.

---

die CLASS DXE_Dialog*** arbeitet wie der LayoutManager aber er nimmt nur aNewSize und "errechnet",
mit der ursprünglichen Grösse, beim "resize" dann den X-/Y-Faktor aus welcher dann angewendet wird.

auch kann man damit die Font Grösse anpassen (lassen) ohne das man sich darum kümmern muss.
das ganz geht natürlich nur wenn die XbParts mit dem XbpDialog über o:Childlist() "verknüpft" sind denn sonst "findet" man die ja nicht.

Fazit : bei o:Resize / DPI-Skaling sollte man vorher ein Konzept "für alle Fenster" entwickeln und nicht für jedes Fenster separat.

*** viewtopic.php?f=16&t=9963
gruss by OHR
Jimmy

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: lbUP

Beitrag von Statler » Di, 14. Nov 2017 19:50

Hallo,

viel zu kompliziert !

Mein resize arbeitet einwandfrei, das ist nicht das Problem. Beim Resize kann man aber naturgemaess pixelweise vergroessern, verkleinern. Ich moechte da aber ein Raster drueber legen, das z.B. nur in 20'er Pixelschritten Vergroessert/verkleinert werden kann. Dadurch moechte ich vermeiden, das Browserzeilen nur halb sichtbar sind.

Ein Grid waehrend des Resize ist nicht machbar, also moechte ich feststellen, wann das resize beendet wurde und dann um ein paar Pixel korrigieren. Beendet ist ein Resize dann, wenn die Maus losgelassen wurde.

Bisher habe ich es aber noch nicht geschafft, zu detektieren, wann die Maus losgelassen wurde.

Gruss

Achim

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10674
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: lbUP

Beitrag von AUGE_OHR » Di, 14. Nov 2017 21:26

hi,
Statler hat geschrieben:
Di, 14. Nov 2017 19:50
Bisher habe ich es aber noch nicht geschafft, zu detektieren, wann die Maus losgelassen wurde.
das wirst du IMHO auch nicht schaffen wenn du nicht VORHER definiert das die Events "nur an das Object" gesendet werden sollen.

---

ich verstehe zwar dein Problem, "letzte Zeile" wird nicht vollständig angezeigt, aber "so" wie du es denkst geht es nicht.

1.) ein "resize" geht auch OHNE Maus -> nix o:Down / o:Up
2.) die Höhe einer ROW ist abhängig vom FONT
3.) per Maus geht das "resize" IMHO über den "Frame". der ist jedoch nicht Bestandteil der o:DrawingArea

was du machen kannst wäre im Codeblock Slot "mehr" als eine Function anzugeben

Code: Alles auswählen

::drawingArea:resize := {|aOldSize,aNewSize,oSelf| MyResize(aOldSize,aNewSize,oSelf),;
                                                         MyKorrektur(aNewSize,oSelf) }

PROCEDURE MyKorrektur(aNewSize,oSelf)
LOCAL cStr := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
LOCAL oPS
LOCAL oFont
LOCAL cTmp
LOCAL aBox
LOCAL aSize
STATIC aOld := {0,0}

   IF aNewSize[1] = aOld[1] .AND. aNewSize[2] = aOld[2] 
      RETURN
   ENDIF
   aOld := ACLONE(aNewSize)

   oPS := APPDESKTOP() :lockPS()
   oFont := GraSetFont( oPS )
   IF oFont != NIL
      GraSetFont( oPS, oFont )
   ENDIF
   aBox := GraQueryTextBox( oPS, cStr )
   APPDESKTOP() :unlockPS()

   aDims[ 1 ] := aBox[ 3 ] [ 1 ] - aBox[ 1 ] [ 1 ] // UnUsed
   aDims[ 2 ] := aBox[ 1 ] [ 2 ] - aBox[ 2 ] [ 2 ] 

   aSize := ACLONE(aNewSize)   
   aSize[2] := ((nROW + nFrame) * aDims[ 2 ] ) + ((nHeader + nFrame) * aDims[ 2 ] ) // + ((nFooter + nFrame) * aDims[ 2 ] ) 
   ... 
   aSize[2] += andere XbParts etc.
   
   // und nun per Event weiter !!!
   PostAppEvent(xbeP_Resize, {1,1},aSize,oSelf)
   
RETURN
gruss by OHR
Jimmy

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: lbUP

Beitrag von Statler » Di, 14. Nov 2017 22:02

Hallo,

>das wirst du IMHO auch nicht schaffen wenn du nicht VORHER definiert das die Events "nur an das Object" gesendet werden sollen.

wie kann man das festlegen ?

Ich habe mein Ziel fast erreicht, nach dem loslassen der Maus wird ein "motion" Event generiert, aber nur wenn sich der Mauszeiger noch auf dem Fenster befindet. Ist der Mauszeiger neben dem Fenster (Groessenanschlag) erfolgt kein Event. Die Maus wird dann ueber dem gesperrten Desktop losgelassen, die Events kommen nicht mehr durch. (Modales Fenster)

Wenn ich temporaer alle Events auf das aktive Fenster umlenken koennte, waere das vermutlich die Loesung. Das Prinzip von :captureMouse () ist mir noch nicht ganz klar.

Gruss

Achim

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10674
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: lbUP

Beitrag von AUGE_OHR » Di, 14. Nov 2017 22:16

Code: Alles auswählen

   DO WHILE nEvent <> xbeP_Close
      nEvent := AppEvent( @mp1, @mp2, @oXbp )
      DO CASE
         CASE nEvent == xbeM_LbDown .AND. oXbp:isDerivedFrom("XbpIWindow")
            aDragArea := GetCursorPos()
            ... 
            oDlg:drawingArea:captureMouse( .T. )
            lMove := .T.

         CASE nEvent == xbeM_Motion .AND. oXbp:isDerivedFrom("XbpIWindow")
            IF lMove = .T.
               aDragArea := GetCursorPos()
               ...
         CASE nEvent == xbeM_LbUp   .AND. oXbp:isDerivedFrom("XbpIWindow")
            aDragArea := GetCursorPos()
            ...
            oDlg:drawingArea:captureMouse( .F. )
            lMove := .F.
         OTHERWISE
            oXbp:handleEvent( nEvent, mp1, mp2 )
      ENDCASE
   ENDDO
gruss by OHR
Jimmy

Statler
UDF-Programmierer
UDF-Programmierer
Beiträge: 57
Registriert: Di, 22. Jan 2008 9:49
Wohnort: Aachen

Re: lbUP

Beitrag von Statler » Do, 16. Nov 2017 20:21

Hallo,

das hier funktioniert:

::lCalibrateLock wird in der Resize Routine bedient, dadurch werden Minimize/Maximize Zustaende abgefangen.
nach dem Beenden des Resize, also nach dem loslassen der Maus, wird die Methode Calibrate () augerufen, in der das Fenster angepasst werden kann. Durch den Aufruf von SetSize () wuerde eine Rekursion enstehen, das wird aber durch ::lCalibrateLock verhindert
Mit der Tastatur funktioniert das auch, nach ENTER erfolgt der Aufruf von Calibrate ()

der modale Eventhandler ist eine Methode meiner Dialog Classe, von daher kann man da auf Self pruefen.

das Fenster muss waehrend des Resizen auf "nicht Modal" stehen, ansonsten wuerde das Loslassen der Maus ausserhalb des modalen Fensters nicht weitergeleitet. Alles nicht so einfach :?

Gruss

Code: Alles auswählen

// Modaler Eventhandler

LOCAL nEvent, mp1, mp2, oObj, oXbpPart, nModalState, lResizeInProgress:= .F.
      
DO WHILE nEvent <> xbeP_Close
   nEvent:= AppEvent (@mp1, @mp2, @oObj)
   *
   * // Calibrate Event generieren //
   *
   IF ! lResizeInProgress
      IF nEvent == xbeP_Resize
         IF oObj == SELF
            IF ::getFrameState () <> 3
               ::lcalibrateLock:= .T.
            ENDIF
            *
            IF ! ::lcalibrateLock
               nModalState:= ::getModalstate ()
               ::setModalstate (XBP_DISP_MODELESS)
               oXbpPart:= oObj
               *
               lResizeInProgress:= .T.
            ENDIF
         ENDIF
      ENDIF
   ELSE
      IF nEvent == xbeM_Motion
         ::setModalstate (nModalState)
         *
         oXbpPart:calibrate ()
         *
         lResizeInProgress:= .F.
      ENDIF
   ENDIF
   *
   * // Events weiterleiten //
   *
   oObj:handleEvent (nEvent, mp1, mp2)
ENDDO

Antworten