Jump to content
aehimself

VERY simple tag editor component

Recommended Posts

In one of my pet projects I recently needed a tag editor component. What I found was either paid or overly complicated so I decided to write my own:

 

Untitled.png.5d4d6f4732fa8f559ed1baa515dbcd51.png

 

It is a single-line, scrollable tag editor. No reordering, no edit box, nothing fancy; just shows the tags which are in the .SelectedTags property. You can remove tags by clicking on them (or removing them from the .SelectedTags...) in which case the OnTagRemoved event is fired.

The way new tags are added is up to you.

 

Feel free to use it and as usual: tips and advices to improve it is more than welcome.

 

https://github.com/aehimself/AEFramework/blob/master/AE.Comp.TagEditor.pas

Edited by aehimself
  • Like 3
  • Thanks 1

Share this post


Link to post

Would need some kind of antialiasing to the drawing, but still nice...

I bet many has need for somethign like that.

-tee-

Share this post


Link to post

Yes, I am also kind of dissatisfied with the jagged lines. Unfortunately that is what Canvas seems to be able to do.

 

Invoking any GDI / Direct2D would drastically increase the footprint and code complexity though and I don't think it worths that much.

  • Like 1

Share this post


Link to post
22 minutes ago, uligerhardt said:

FWIW, there's TTagEditor from Andreas Rejbrand.

The key here is "overly complicated". It contains way too many features for my needs, which just makes future maintenance harder if something goes wrong.

Plus I didn't like the rectangular tags :)

Share this post


Link to post
17 minutes ago, aehimself said:

The key here is "overly complicated". It contains way too many features for my needs, which just makes future maintenance harder if something goes wrong.

Plus I didn't like the rectangular tags 🙂

I see. 😉

Share this post


Link to post
2 hours ago, Tommi Prami said:

Would need some kind of antialiasing to the drawing

- or one could create a single, nicely anti-aliased tag bitmap and use 9-patch to paint it.

image.png.17dda9ce26ef84451cc540c898723eef.png

With some additional logic, you can even have overlapping labels.

image.png.5f3c671049884d9dd76161575eaf8979.png

I made a demo of this some years ago but I can't find the source anywhere.

 

2 hours ago, aehimself said:

Invoking any GDI / Direct2D would drastically increase the footprint and code complexity though and I don't think it worths that much.

I assume you meant GDI+.

Using stuff that's bundled with Windows doesn't increase the footprint and the amount of code to wrap the API is negligible.

 

Edited by Anders Melander
  • Like 1

Share this post


Link to post

Antialiased polyline is very simple to do with Image32 library:

Untitled.thumb.png.356d01c18c8384987669c1d3785f0f24.png

 

uses
  Img32,
  Img32.Draw,
  Img32.Vector;

...

Procedure TTagComponent.Paint;
var
  W: Integer;
  H: Integer;
  Path: TPathD;
  Img: TImage32;
  PenWidth: Integer;
  PenColor: TColor32;
  BrushColor: TColor32;
  textrect: TRect;
  s: String;
const
  BORDER = 4;
  SPINER = BORDER + 8;
  TEXT_H_OFFSET = SPINER + 3;
  TEXT_V_OFFSET = BORDER + 3;
begin
  W := Self.ClientWidth;
  H := Self.ClientHeight;
  Img := TImage32.Create(W, H);
  try
    BrushColor := Color32(TStyleManager.ActiveStyle.GetStyleColor(scEdit));

    If _drawactive Then
    Begin
      PenColor := Color32(TStyleManager.ActiveStyle.GetStyleFontColor(sfWindowTextDisabled));
      PenWidth := 2;
    End
    Else
    Begin
      PenColor := Color32(TStyleManager.ActiveStyle.GetStyleColor(scBorder));
      PenWidth := 1;
    End;

    Img.Clear(BrushColor);

    Path := MakePath
    (
      [
        BORDER, BORDER,
        Self.ClientWidth - SPINER, BORDER,
        Self.ClientWidth - BORDER, Self.ClientHeight div 2,
        Self.ClientWidth - SPINER, Self.ClientHeight - BORDER,
        BORDER, Self.ClientHeight - BORDER,
        SPINER, Self.ClientHeight div 2
      ]
    );
    DrawPolygon(Img, Path, frEvenOdd, BrushColor);
    DrawLine(Img, Path, PenWidth, PenColor, esPolygon);

    Img.CopyToDc(Self.Canvas.Handle, 0, 0, False);

    textrect := TRect.Create(TEXT_H_OFFSET, TEXT_V_OFFSET, W - TEXT_H_OFFSET, H - TEXT_V_OFFSET);
    s := Trim(Self.Caption);

    Self.Canvas.Font.Assign(Self.Font);
    Self.Canvas.Font.Color := TStyleManager.ActiveStyle.GetStyleFontColor(sfWindowTextNormal);
    Self.Canvas.TextRect(textrect, s, [tfSingleLine, tfVerticalCenter, tfCenter, tfEndEllipsis]);

  finally
    Img.Free;
  end;
end;

 

sample.7z

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×