Перейти к содержанию
Fire Monkey от А до Я
  • 0

компонент – Индикатор("лампочка")


ddr 2

Вопрос

Здравствуйте.

Разработал свой первый визуальный компонент – Индикатор из 4-х состоянийLed_All.png.8471ecf2d4ec7e69b14cf483d578f179.png. Разобраться слету во всех иерархиях имеющихся классов тяжко. Что «наинтернетил», так и сделал. Есть вопросы. И в целом любая критика приветствуется.

1.       Разумно ли выбран TImage в качестве предка?

2.       Основной вопрос. В TLEDIndicator.Paint, с помощью

 Canvas.DrawEllipse(TRectF.Create(1, 1,width-2,width-2), 1);

отприсовывается внешний контур Индикатора. Применен отступ от краёв в 1 пиксель. И это вынужденная мера. Если сделать без отступа TRectF.Create(0, 0,Width-1,Width-1), то при изменении статуса индикатора подразумевающие изменения цвета внешнего контура, остаются частично «следы» старого цвета контура.Led_bugg.png.d856acf2de0f76f72531c2c1890fb3c5.png Если окно свернуть/развернуть, то «следы» пропадают. Делаю вывод, что все корректно, и это скорее всего результат используемого в DrawEllipse «сглаживания». Логично попробовать решить это через очистку канвы. В качестве эксперимента в Paint добавляю 

Canvas.Clear(TAlphaColorRec.Green);

В результате зеленеет(очищается) вся форма!?!?!? Смотрю размер канвы. 640x480. Тоже вопросы.. откуда??? Пытаюсь изменить размер канвы 

Canvas.SetSize(trunc(Width),trunc(Height));

Результат- ошибки, зависание, аварийное завершение.

Меня вполне устраивает решение с отступом в 1 пиксель, но хочу разобраться с полученным, я явно делаю, что-то не правильно.

3.       Как задать размеры элемента по умолчанию?

unit ULEDIndicator;

interface

uses
  System.SysUtils, System.Classes, FMX.Types, FMX.Controls, FMX.Objects,FMX.Graphics,System.Types,System.UITypes;

type
  TLEDStatus=(Red,Green,Null);

  TLEDIndicator = class(TImage)   {вопрос 1}
  private
    FStatus: TLEDStatus;
    procedure SetLEDStatus(Value:TLEDStatus);
    Function GetInColor:TColor; inline;
    Function GetOutColor:TColor; inline;
  protected
    procedure Paint; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property Status:TLEDStatus read Fstatus write SetLEDStatus stored true default TLEDStatus.Green;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TLEDIndicator]);
end;

constructor TLEDIndicator.Create(AOwner: TComponent);
Begin
 inherited;
 FStatus:=TLEDStatus.Green;
End;

procedure TLEDIndicator.Paint;
var IWidth:integer;
begin
 inherited; {вопрос 2}
 IWidth:=Canvas.Width;
// Canvas.Clear(TAlphaColorRec.Green);
 Canvas.Stroke.Color:=GetIncolor;
 Canvas.Fill.Color:=GetOutColor;
 Canvas.Stroke.Thickness:=1;
 Canvas.Stroke.Dash:= TStrokeDash.Solid;
 Canvas.Stroke.Kind:= TBrushKind.Solid;
 Canvas.DrawEllipse(TRectF.Create(1, 1,width-2,width-2), 1);{вопрос 2}
 Canvas.FillEllipse(TRectF.Create(3, 3,width-4,width-4), 1);
end;

procedure TLEDIndicator.SetLEDStatus(Value:TLEDStatus);
Begin
 Fstatus:=Value;
 Repaint;
End;

Function TLEDIndicator.GetInColor:TColor;
Begin
 if Enabled then Result:= TAlphaColorF.Create(42 / 255, 42 / 255, 42 / 255, 1).ToAlphaColor
 else Result:=TAlphaColorF.Create($E5/ 255, $E5 / 255, $E5/ 255, 1).ToAlphaColor;
End;

Function TLEDIndicator.GetOutColor:TColor;
Begin
 if Enabled then
   case FStatus of
    Red:Result:= TAlphaColorRec.Red;
    Green:Result:= TAlphaColorRec.Green;
    Null:Result:=TAlphaColorF.Create($E5/ 255, $E5 / 255, $E5/ 255, 1).ToAlphaColor;
   end
 else Result:=TAlphaColorF.Create($E5/ 255, $E5 / 255, $E5/ 255, 1).ToAlphaColor
End;

end.

 

Ссылка на комментарий

Рекомендуемые сообщения

  • 0
1 час назад, ddr 2 сказал:

1.       Разумно ли выбран TImage в качестве предка?

Лучше TPaintBox или TShape

1 час назад, ddr 2 сказал:

Canvas.SetSize

вообще лучше не делать - размер холста задаётся автоматом в зависимости от размеров контрола

1 час назад, ddr 2 сказал:

3.       Как задать размеры элемента по умолчанию?

переопределите функцию    GetDefaultSize: TSizeF

1 час назад, ddr 2 сказал:

procedure TLEDIndicator.Paint;

begin inherited; {вопрос 2}

Вы контрол рисуете полностью сами, значит inherited тут не надо

А вообще - посмотрите исходники TCircle-TEllipse-TShape - всё станет намного понятнее.

Ссылка на комментарий
  • 0
В 21.07.2020 в 18:33, dnekrasov сказал:

А вообще - посмотрите исходники TCircle-TEllipse-TShape - всё станет намного понятнее.

Спасибо. Ясности действительно прибавило. 

Ещё мне вот эти исходники помогли разбираться http://fire-monkey.ru/topic/1902-семисегментный-индикатор/ ,как создавать  визуальные компоненты на примитивах.

По моим базовым непониманиям, по которыхзадавал вопросы:

- очищать канву в Paint не нужно, она и так очищена;

- при рисовании примитовов на  канве нужно следить, что бы ничего не "нарисовать" вне размеров элемента, иначе будет, как я писал выше.

 

В 21.07.2020 в 18:33, dnekrasov сказал:
В 21.07.2020 в 17:02, ddr 2 сказал:

3.       Как задать размеры элемента по умолчанию?

переопределите функцию    GetDefaultSize: TSizeF

Что-то такое "размеры по умолчанию", я так и не понял. Я своём вопросе я имел в виду значения Width и Heigth которые отображаются в Object Inspector при добавлении компонента в Design. Получается не корректно задал вопрос. Прошу прощения. А решение, которое я нашел, что инициализация указанных свойств в конструкторе.

Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...