TMultiButton, ein Button mit einem integrierten Button

Zur Vorstellung von Komponenten und Units für Lazarus
wennerer
Beiträge: 253
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 19.3 Cinnamon, Lazarus Stable 2.0.10 r63673M FPC 3.2.0
CPU-Target: x86_64-linux-gtk2

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von wennerer »

Hallo Winni,
da hast du natürlich mit allem Recht. Aber einfach mal nur schnell strg+c ist ja auch doof. Ich werd auf jeden Fall in meine unit diesen Satz aufnehmen:
for some improvements see viewtopic.php?f=29&t=13252
Es sind nun ja bereits etliche Verbesserungen aus dem Forum eingeflossen!

Viele Grüße
Bernd

wennerer
Beiträge: 253
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 19.3 Cinnamon, Lazarus Stable 2.0.10 r63673M FPC 3.2.0
CPU-Target: x86_64-linux-gtk2

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von wennerer »

Hallo,
ich hab nun noch einige Anregungen eingebaut.

Siro schrieb:
Du scheinst einen "virtuellen" Rahmen um deine Schaltfläche zu haben.
Das verwirrte mich etwas bei den Einstellungen "Width" und Height"
Weil der eigentlich sichtbare Bereich kleiner nach innen versetzt ist.
Dort hast Du eine "feste" Größe von 5 Pixel vorgesehen.
Der eigentliche "Hotspot" ist also an allen 4 Kanten um 5 Pixel kleiner.
Im Prinzip scheinen die 5 Pixel der "Hover" Rahmen (Focus Rahmen) zu sein.
sollte evtl. einstellbar sein ?
Es lässt sich nun mit der Eigenschaft HoverFrameWidth die Breite frei einstellen. Allerdings sieht man dann bei einer Rechteckform bzw. RoundRect und einer Breite von 0 keinen Hover und Focus mehr.
Zusätzlich hab ich eine Beschreibung bei width und height im OI hinterlegt.
OI.jpg
OI.jpg (13.8 KiB) 391 mal betrachtet
Ich hoffe damit wird das für einen Anwender etwas plausibler.
Wenn BorderWidth sichtbar ist, wäre noch eine Positionsanpassung des Textes sinnvoll:
bei taLeftJustify BorderWidth dazu addieren
bei taRightJustify entsprechend abziehen
Die Textausgabe mit TextRect ist auf der einen Seite sehr angenehm aber leider funktioniert nicht immer alles so wie man es erwartet. Verrechnungen zum Beispiel funktionieren nur mit taLeftJustify und tlTop. Ich habe deshalb das Textrechteck um BorderWidth verkleinert und FTextStyle.Clipping auf true eingestellt. Damit sollte der Text im Rechteck bleiben und nicht von der Border verdeckt werden (zumindest solange das Rechteck nicht zu klein wird).
Ein Datum oder Version in jeder Datei oben rein
Ja das muss ich mir unbedingt angewöhnen!

Die verschiedenen Verbesserungen für die Unit PtIn habe ich soweit eingebaut!

Vielen Dank an Alle und viele Grüße!
Bernd
Dateianhänge
Release02.zip
(18.11 KiB) 13-mal heruntergeladen

Benutzeravatar
Winni
Beiträge: 545
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von Winni »

Hi!


Hover für Faule. Hat aber auch nen guten Effekt:

a) Schriftgrößer änden. Ausrichtung muss taCenter sein.
b) Font-Farbe ändern. Von Gelb auf schwarz ist reichlich Kontrast.Und freut die BVB-Fans.
c) Font-Style ändern. Von normal [ ] auf bold , italic oder Beides.

Das kann man alles kombinieren oder für sich benutzen.

Winni

wp_xyz
Beiträge: 3514
Registriert: Fr 8. Apr 2011, 09:01

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von wp_xyz »

wennerer hat geschrieben:
Mo 23. Nov 2020, 17:33
Die Textausgabe mit TextRect ist auf der einen Seite sehr angenehm aber leider funktioniert nicht immer alles so wie man es erwartet. Verrechnungen zum Beispiel funktionieren nur mit taLeftJustify und tlTop.
Wenn man es einmal verstanden hat, ist es ganz einfach: TextRect schreibt in das vorgegebene Rechteck, je nachdem wie die TextStyle-Elemente Alignment und Layout gesetzt sind, wobei aber die angegebenen X und Y-Koordinaten nicht immer verwendet werden:

Ist Alignment = taRightJustify wird der Text rechtsbündig an den rechten Rechteck-Rand gesetzt, bei Alignment taCenter horizontal im Rechteck zentriert, egal welchen Wert die X-Koordinate hat. Nur wenn Alignment = taLeftJustify ist, wird der Text linksbündig am Ort der Koordinate X begonnen.

Genauso mit der vertikalen Positionierung: Layout = tlBottom mal den Text an den unteren Rand des Rechtecks, tlCenter vertikal zentriert im Rechteck. Auch hier wird die Koordinate (nun Y) ignoriert. Nur wenn Layout = tlTop ist, wird der Text am Ort der Koordinate gezeichnet, und zwar so, dass die Text-Oberkante bei Y liegt.

Überzeuge dich mit dem folgenden Code. Setze eine Paintbox aufs Formular und weise ihr folgenden OnPaint-Handler zu.

Code: Alles auswählen

procedure TForm1.PaintBox1Paint(Sender: TObject);
const
  s = 'Text';
  ignored = MaxInt;
var
  ts: TTextStyle;
  R: TRect;
begin
  with PaintBox1.Canvas do begin
    Brush.Color := clWhite;
    R := Rect(0, 0, Paintbox1.Width, Paintbox1.Height);
    FillRect(R);

    ts := TextStyle;
    ts.Alignment := taLeftJustify;
    ts.Layout := tlTop;
    TextRect(R, R.Left, R.Top, s, ts);

    ts.Alignment := taCenter;
    TextRect(R, ignored, 0, s, ts);

    ts.Alignment := taRightJustify;
    TextRect(R, ignored, 0, s, ts);

    ts.Layout := tlCenter;
    ts.Alignment := taLeftJustify;
    TextRect(R, 0, ignored, s, ts);

    ts.Alignment := taCenter;
    TextRect(R, ignored, ignored, s, ts);

    ts.Alignment := taRightJustify;
    TextRect(R, ignored, ignored, s, ts);

    ts.Layout := tlBottom;
    ts.Alignment := taLeftJustify;
    Textrect(R, 0, ignored, s, ts);

    ts.Alignment := taCenter;
    TextRect(R, ignored, ignored, s, ts);

    ts.Alignment := taRightJustify;
    Textrect(R, ignored, ignored, s, ts);
  end;
end; 

wennerer
Beiträge: 253
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 19.3 Cinnamon, Lazarus Stable 2.0.10 r63673M FPC 3.2.0
CPU-Target: x86_64-linux-gtk2

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von wennerer »

Hallo wp_xyz,
nach anfänglichen Schwierigkeiten hab ich das Verhalten von TextRect schon verstanden.
siehe: viewtopic.php?f=55&t=13225

Ich hab mich da aber vielleicht etwas missverständlich ausgedrückt. Ich verwende TextRect für die Ausgabe der Caption. Dies ist einerseits wegen der bereitgestellten Eigenschaften sehr angenehm. Auf der anderen Seite hab ich dann aber im OI die Properties CaptionLeft und CaptionTop die halt eventuell nicht reagieren.
Konkretes Beispiel: Bei taRightJustify und etwas dickem Rand wird der Text rechts etwas verdeckt. Mit CaptionLeft lässt sich leider nichts korrigieren. Wenn man weiß das TextRect verwendet wurde ist das natürlich klar. Meine Lösung ist jetzt das ich das TextRect um die Breite des Randes verkleinere.
Richtig cool wäre es wenn CaptionLeft und CaptionTop nur sichtbar wären wenn sie auch benutzt werden können, oder sie wären ausgegraut. Hab so was aber noch nie gesehen. Kann man so was machen?

Viele Grüße
Bernd

Sieben
Beiträge: 102
Registriert: Mo 24. Aug 2020, 14:16
OS, Lazarus, FPC: Ubuntu Xenial 32, Lazarus 2.0.10, FPC 3.2.0
CPU-Target: i386

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von Sieben »

Das habe ich beides auch noch nicht gesehen und wüsste auf Anhieb auch keinen Ansatz. Du kannst aber einen entsprechenden Setter schreiben, der Werte bei unpassenden Randbedingungen wieder zurücksetzt und/oder (am besten nur zur Designzeit) auch Meldungen ausgibt.

wp_xyz
Beiträge: 3514
Registriert: Fr 8. Apr 2011, 09:01

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von wp_xyz »

wennerer hat geschrieben:
Mo 23. Nov 2020, 19:17
Richtig cool wäre es wenn CaptionLeft und CaptionTop nur sichtbar wären wenn sie auch benutzt werden können, oder sie wären ausgegraut. Hab so was aber noch nie gesehen. Kann man so was machen?
Das geht nicht, gelegentlich findet man auch in der LCL Beispiele, dass Properties mitgeschleppt werden, die nur in einem bestimmten Zusammenhang angewendet werden.

Was du machen kannst, ist, den beiden Properties einen unverfänglicheren, allgemeiner gültigen Namen zu geben. Ich würde die beiden statt CaptionLeft/CaptionTop HorMargin/VertMargin nennen. Das wäre dann der Abstand der Caption zum Rand des Buttons, was sowohl bei links-/rechtsbündiger und oberer/unterer Ausrichtung einen Sinn gäbe. Und dass sie bei zentrierter Ausgabe unnötig sind, ist unmittelbar klar.

wennerer
Beiträge: 253
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 19.3 Cinnamon, Lazarus Stable 2.0.10 r63673M FPC 3.2.0
CPU-Target: x86_64-linux-gtk2

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von wennerer »

Hallo,
ich habe erst nochmal über alle Antworten etwas nachdenken müssen :wink:

Winni schrieb:
Hover für Faule. Hat aber auch nen guten Effekt:

a) Schriftgrößer änden. Ausrichtung muss taCenter sein.
b) Font-Farbe ändern. Von Gelb auf schwarz ist reichlich Kontrast.Und freut die BVB-Fans.
c) Font-Style ändern. Von normal [ ] auf bold , italic oder Beides.

Ja, habe nun eine Property HoverFontColor hinzugefügt. Damit hat man noch eine weitere Möglichkeit den Hover/Fokus darzustellen.

Sieben schrieb:
Du kannst aber einen entsprechenden Setter schreiben, der Werte bei unpassenden Randbedingungen wieder zurücksetzt und/oder (am besten nur zur Designzeit) auch Meldungen ausgibt.
Find ich auch gut. Hab ich so eingebaut. Es sollte jetzt eine ShowMessage ausgelöst werden.

wp_xyz schrieb:
Was du machen kannst, ist, den beiden Properties einen unverfänglicheren, allgemeiner gültigen Namen zu geben. Ich würde die beiden statt CaptionLeft/CaptionTop HorMargin/VertMargin nennen.......
Ich weiß nicht ob das sehr viel verbessert. Aber es klingt viel professioneller! Hab ich deshalb auch so umgesetzt (CaptionHorMargin, CaptionVerMargin).

Vielen Dank an euch für die Antworten. Mir ist schon klar das ich der einzige sein werde der die Komponente in einem kleinen Programm verwenden wird. Ich finde es aber dennoch schön wenn ich durch die Tipps hier im Forum die Komponente ein bisschen verbessern kann.

Viele Grüße
Bernd
Dateianhänge
Release03.zip
(246.87 KiB) 14-mal heruntergeladen

siro
Beiträge: 399
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 10
CPU-Target: 64Bit
Wohnort: Berlin

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von siro »

PtInPoly hat sich ja nun verändert und ich habe mal einen Test gemacht:
In Windows kann man sehr schön Zeiten messen und es zeigt sich, dass die neue PtInPoly rund 4 mal schneller ist als die ehemalige (alte) Version.
600ns zu 2,2µs
Poly_Time.jpg
Poly_Time.jpg (13.56 KiB) 275 mal betrachtet
Ich weis nicht ob man sowas auch unter Linux testen kann.

Code: Alles auswählen


var freq,tStart,tStop:Int64;
var t:Single;  

 ...... 
 if Form = Poly then
  begin
   p.X:=x;p.Y:=y;
   QueryPerformanceFrequency(freq);

   QueryPerformanceCounter(tStart);
   if PtInPoly(aPolygon,p)    then aColor := cllime else aColor:=clyellow;
   QueryPerformanceCounter(tStop);
   t:=(tStop-tStart) / freq; { in Sekunden umrechnen }
   Label1.caption:=FloatToStr(t);

   QueryPerformanceCounter(tStart);
   if PtInPolyOld(aPolygon,p) then aColor := cllime else aColor:=clyellow;
   QueryPerformanceCounter(tStop);
   t:=(tStop-tStart) / freq; { in Sekunden umrechnen }
   Label2.caption:=FloatToStr(t);
  end;                                 
                                                 
Textausrichtung auch nochmal geprüft:
Der Zusätzliche Abstand geht auch.
Jo, sieht gut aus.

Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

Benutzeravatar
Winni
Beiträge: 545
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.06, fpc 3.04
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: TMultiButton, ein Button mit einem integrierten Button

Beitrag von Winni »

Hi!

Ich kannte "QueryPerformanceCounter" bis eben nicht .

Aber was auf *allen* Plattformen funktioniert, ist

getTickCount64
aus der unit lazsysutils.pas.

Das gibt dir Millisekunden zurück, und zwar seit dem der Rechner gestartet wurde.

Damit kannst du also genauso rechnen:

Code: Alles auswählen

Procedure Irgendwas;
var  startTime = Qword;
begin
StartTime := getTickCount64;
...
showMessage ('Das hat gedauert: '+IntTor(GetTickCount - startTime)+' Millisekunden');
end;
Für die geschichtlich Interesserten. Und für den Humor:

Die frühen Versionen von Windows NT (Anfang der 90iger) waren der hoffnungsvolle Lichtblick in der Geschichte
der Windows-Rechner: Als Server einsetzbar und halbwegs stabil. Kein Wunder: Codiert von dem ehemaligen VMS-Team - abgeworben von DEC. Eine Macke hatten die Rechner: alle ??? Tage krachte das OS ohne ersichtlichen Grund. Da dieser Zyklus anscheinend > 40 Tage war, ging man dazu über, die NT-Rechner am Monats-Ersten zu booten.
An dieser Stelle zeigte es sich, wie hilfreich die 4 Grundrechen-Arten seien können. Wenn das wühlen in zig Seiten von C-Code nicht geholfen hat:

Damals war getTickCount64 noch nicht erfunden und alles wurde mit 32 Bit erledigt - das war gerade das Modernste im Schrank. Nun geht das große Rechnen los:

MaxDWord / 1000 MillSec = 49.xxxx Tage.

Es war ein simpler 32-Bit-Overflow, den NT nicht verkraftete.
Großes Gelächter allerseits.
Und die Geburt von GetTickCount64

Bei großen Dimensionsdifferenzen sollte man also mal X * PI * Daumen gucken,
ob das dann alles noch in einen Int64 (oder Double) passt.

Winni

Antworten