Замечания и предложения

Предлагаю добавить самописный модуль в папку стандартных модулей паскаля - WPFButton, или же в WPFObjects добавить как отдельный класс.

Думаю “Кнопки” понадобятся многим,кто пишет программы,связанные с WPF на данном языке.

unit WPFButton;

interface

uses SIRObjectsWPF;

type
  ButtonWPF = class(RectangleWPF)
    private clb: boolean;
    public event Click: procedure;
  
  private
    procedure MouseDown(x, y: real; mb: integer);
    begin
      if (ObjectUnderPoint(x, y) = self) and (mb = 1)
      then begin
        self.AnimMoveTo(self.Left + 2, self.Top + 2, 0.1);
        clb := true;
      end;
    end;
    
    procedure MouseUp(x, y: real; mb: integer);
    begin
      if (ObjectUnderPoint(x, y) = self)
        then 
        if Click <> nil
          then Click;
      
      if clb
      then begin
        self.AnimMoveTo(self.Left - 2, self.Top - 2, 0.1);
        clb := false;
      end;
    end;
    
    public constructor Create(x, y, w, h: real; cl: Gcolor; s: string);
    begin
      inherited Create(x, y, w, h, cl);
      self.Text := s;
      OnMouseDown += MouseDown;
      OnMouseUp += MouseUp;
    end;
    
    public constructor Create(x, y, w, h, bw: real; cl: Gcolor; bcl: GColor; s: string);
    begin
      inherited Create(x, y, w, h, cl, bw, bcl);
      self.Text := s;
      OnMouseDown += MouseDown;
      OnMouseUp += MouseUp;
    end;
    
    procedure Dispose;
    begin
      OnMouseDown -= MouseDown;
      OnMouseUp -= MouseUp;
    end;
  
  end;


implementation

begin

end. 
1 лайк

А убирать как? Наверное деструктор надо…

Т.к. я унаследовал от класса RectangleWPF, то процедура с именем “Destroy” уже есть.Может назвать Dispose?

Все,добавил.

Рассмотрите такой код:

uses GraphWPF,Controls;

begin
  Window.Title := 'Цвета';
  Font.Size := 40;
  AddLeftPanel(150);

  var rb := IntegerBlock('Красный:',12,255);
  var r := Slider(0,255,255);
  EmptyBlock;
  var gb := IntegerBlock('Зеленый:',12,255);
  var g := Slider(0,255,255);
  EmptyBlock;
  var bb := IntegerBlock('Синий:',12,255);
  var b := Slider(0,255,255);
  
  EmptyBlock;
  var bt := Button('Выход');
  bt.Click := procedure -> Window.Close;
  

  r.Frequency := 16;
  g.Frequency := 16;
  b.Frequency := 16;
  
  var p: procedure := ()-> begin
    Window.Clear(RGB(r.Value.Round,g.Value.Round,b.Value.Round));
    rb.Value := r.Value.Round;
    gb.Value := g.Value.Round;
    bb.Value := b.Value.Round;
    DrawText(GraphWindow.ClientRect,$'R={rb.Value}, G={gb.Value}, B={bb.Value}');
  end;
  r.ValueChanged := p;
  g.ValueChanged := p;
  b.ValueChanged := p;
  p;
end.

Так же хочу предложить изменения в класс “PictureWPF”. В модуле WPFObjects я не нашел возможности отобразить картинку из Ресурсов программы. По этому добавил в PictureWPF несколько методов,и конструкторы,для возможности отобразить картинку из Ресурсов.

Если изменить этот класс в модуле,тоон не работает.При запуске программы вылетает ошибка компилятора “Чтения за концом потока” .Но если скопировать код из модуля WPFObjects изменить название модуля,и изменить класс,то работает,но при таком подходе нужно модуль всегда рядом с программой носить.

PictureWPF = class(ObjectWPF)
private
  PName: string;
  function CreateBitmapImage(fname: string) := new BitmapImage(new System.Uri(fname, System.UriKind.Relative)); 
  procedure Rest(x, y, w, h: real; b: BitmapImage);
  begin
    var im := new System.Windows.Controls.Image();
    im.Source := b;
    im.Width := w;
    im.Height := h;
    
    InitOb(x, y, w, h, im);
  end;
  
  function GetString(self: string; oi, ni: integer): string;
  begin
    for var i := oi to ni do 
      result += self[i];
  end;
  
  procedure InitOb5(x, y, w, h: real; name: string);
  begin
    PName := GetString(name, 1, name.LastIndexOf('.'));
    var bmi := new System.Windows.Media.Imaging.BitmapImage();
    bmi.BeginInit();
    bmi.StreamSource := GetResourceStream(name);
    bmi.EndInit();
    Rest(x, y, w, h, bmi);
  end;
  
  procedure InitOb4(x, y: real; name: string);
  begin
    PName := GetString(name, 1, name.LastIndexOf('.'));
    var bmi := new System.Windows.Media.Imaging.BitmapImage();
    bmi.BeginInit();
    bmi.StreamSource := GetResourceStream(name);
    bmi.EndInit();
    Rest(x, y, bmi.PixelWidth, bmi.PixelHeight, bmi);
  end;
  
  procedure InitOb3(x, y, w, h: real; fname: string);
  begin
    var b := CreateBitmapImage(fname);
    Rest(x, y, w, h, b);
  end;
  
  procedure InitOb2(x, y: real; fname: string);
  begin
    var b := CreateBitmapImage(fname);
    Rest(x, y, b.PixelWidth, b.PixelHeight, b);
  end;
  
  function GetInternalGeometry: Geometry; override;
  begin
    var r := Rect(0, 0, Width, Height);
    Result := new RectangleGeometry(r);
  end;

public
  function Element := ob as System.Windows.Controls.Image;
    /// Создает рисунок из файла fname с координатами левого верхнего угла (x,y)
  constructor(x, y: real; fname: string):= Invoke(InitOb2, x, y, fname);
    /// Создает рисунок из файла fname с координатами левого верхнего угла (x,y) и размерами (w,h)
constructor(x, y, w, h: real; fname: string):= Invoke(InitOb3, x, y, w, h, fname);
    /// Создает рисунок из файла fname с координатой левого верхнего угла, заданной точкой p
constructor(p: Point; fname: string):= Invoke(InitOb2, p.x, p.y, fname);
    /// Создает рисунок из файла fname  с координатой левого верхнего угла, заданной точкой p, и размерами (w,h)
constructor(p: Point; w, h: real; fname: string):= Invoke(InitOb3, p.x, p.y, w, h, fname);
    ///Создает рисунок из потока
constructor(x, y: real; name: string;b:boolean:=false):=Invoke(InitOb4, x, y, name);
    ///Создает рисунок из потока с шириной w и высотой h
constructor(x, y, w, h: real; name: string;b:boolean:=false):=Invoke(InitOb5, x, y, w, h, name);
    /// Декоратор текста объекта
function SetText(txt: string; size: real := 16; fontname: string := 'Arial'; c: GColor := Colors.Black): PictureWPF  
:= inherited SetText(txt, size, fontname, c) as PictureWPF;
    /// Декоратор поворота объекта
  function SetRotate(da: real): PictureWPF := inherited SetRotate(da) as PictureWPF;
  
  property Name: string read PName write PName := value;
end;

Не работает. “Program1.pas(31) : ClientRect не объявлен в типе GraphWindowType” У меня стоит не последняя версия, т.к. последнее обновление сломало что-то,не помню что именно,нет времени искать минимальный код,поставил версию до последнего обновления

Немного изменил ваш код,теперь работает:

uses GraphWPF, Controls;

begin
  Window.Title := 'Цвета';
  Font.Size := 40;
  AddLeftPanel(150);
  
  var rb := IntegerBlock('Красный:', 12, 255);
  var r := Slider(0, 255, 255);
  EmptyBlock;
  var gb := IntegerBlock('Зеленый:', 12, 255);
  var g := Slider(0, 255, 255);
  EmptyBlock;
  var bb := IntegerBlock('Синий:', 12, 255);
  var b := Slider(0, 255, 255);
  
  EmptyBlock;
  var bt := Button('Выход');
  bt.Click := procedure -> Window.Close;
  
  
  r.Frequency := 16;
  g.Frequency := 16;
  b.Frequency := 16;
  
  var p: procedure := () -> begin
    Window.Clear(RGB(r.Value.Round, g.Value.Round, b.Value.Round));
    rb.Value := r.Value.Round;
    gb.Value := g.Value.Round;
    bb.Value := b.Value.Round;
    DrawText(Window.ClientRect, $'R={rb.Value}, G={gb.Value}, B={bb.Value}');
  end;
  r.ValueChanged += p;
  g.ValueChanged += p;
  b.ValueChanged += p;
  p;
end.

Лучше тогда принимать System.IO.Stream а не string.

Изначально так и было,но тогда не получится реализовать свойство “Name”

А как записать картинку в ресурсы?

{$resource Картинка.png}

begin
  
end.

Не обязательно возвращать полноценное имя при создании из потока. Можно возвращать nil, а можно кидать исключение.

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

Хорошо,как тогда назвать?

Так и назвать, именем ресурса. И можно ещё в скобках добавить, что имеется в виду $resource, раз даже @Admin забыл что такое ресурсы программы))

1 лайк

А какие еще могут быть ресурсы?

@Admin,примите мои поправки и предложения?

Какие?

Давайте по одному

1 лайк

Первым делом хотелось бы вот это:

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