From ce2e98afdccfd74aeda51d38de4946aaaefe71c5 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Wed, 13 Mar 2024 22:23:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9C=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20WPF.pas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 2 +- .../StandardUnits/WPF/WPF_Calc.pas | 40 ++ .../StandardUnits/WPF/WPF_Calc_class.pas | 54 ++ .../StandardUnits/WPF/WPF_CheckBoxColors.pas | 36 ++ .../StandardUnits/WPF/WPF_ComboBoxColors.pas | 18 + .../StandardUnits/WPF/WPF_DockPanel1.pas | 19 + .../StandardUnits/WPF/WPF_DockPanel2.pas | 13 + .../StandardUnits/WPF/WPF_FontChange.pas | 26 + .../StandardUnits/WPF/WPF_RectProperties.pas | 31 ++ Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- ReleaseGenerators/RebuildStandartModules.pas | 3 +- ReleaseGenerators/sect_Core.nsh | 4 + bin/Lib/WPF.pas | 488 ++++++++++++++++++ 15 files changed, 735 insertions(+), 5 deletions(-) create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_Calc.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_Calc_class.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_CheckBoxColors.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_ComboBoxColors.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_DockPanel1.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_DockPanel2.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_FontChange.pas create mode 100644 InstallerSamples/StandardUnits/WPF/WPF_RectProperties.pas create mode 100644 bin/Lib/WPF.pas diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 8c8d44371..d6f7ff436 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "9"; public const string Build = "0"; - public const string Revision = "3430"; + public const string Revision = "3432"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 8fbd450a7..497ea3f3c 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %COREVERSION%=0 -%REVISION%=3430 +%REVISION%=3432 %MINOR%=9 %MAJOR%=3 diff --git a/InstallerSamples/StandardUnits/WPF/WPF_Calc.pas b/InstallerSamples/StandardUnits/WPF/WPF_Calc.pas new file mode 100644 index 000000000..13ff23f40 --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_Calc.pas @@ -0,0 +1,40 @@ +uses WPF; + +begin + MainWindow.Title := 'Калькулятор'; + var mainpanel := Panels.StackPanel.AsMainContent; + var panel1 := Panels.StackPanel(Margin := 10, Horizontal := True) + .With(Background := Brushes.LightBlue) + .AddTo(mainpanel); + + var tb := CreateTextBox('0', Width := 120); + var lb := CreateLabel('+',Width := 35); + var tb1 := CreateTextBox('0', Width := 120); + var lb1 := CreateLabel('=',Width := 55); + panel1.AddElements(tb,lb,tb1,lb1); + + var panel2 := Panels.StackPanel(Margin := |10,0,10,10|, Horizontal := True) + .With(Background := Brushes.LightBlue) + .AddTo(mainpanel); + panel2.HorizontalAlignment := HA.Right; + + var Handler: EventHandler := (o,e) -> begin + var b := o as Button; + var Left := tb.Text.ToReal; + var Right := tb1.Text.ToReal; + case b.Text of + $'+': lb1.Content := '= ' + (Left + Right); + $'-': lb1.Content := '= ' + (Left - Right); + $'*': lb1.Content := '= ' + (Left * Right); + $'/': lb1.Content := '= ' + (Left / Right); + end; + end; + + var bb := CreateButtons(|$'+',$'-',$'*',$'/'|); + panel2.AddButtons(bb, Width := 35, Margin := |10,0|, Padding := 5); + + for var i:=0 to bb.Length-1 do + bb[i].Click += Handler; + + MainWindow.SizeToContent := SizeToContent.WidthAndHeight; +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_Calc_class.pas b/InstallerSamples/StandardUnits/WPF/WPF_Calc_class.pas new file mode 100644 index 000000000..f524ae1ad --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_Calc_class.pas @@ -0,0 +1,54 @@ +uses WPF; + +type Main = class + //-- Controls + mainpanel,panel1,panel2: StackPanel; + tb,tb1: TextBox; + lb,lb1: TLabel; + bb: array of Button; + //-- Event Handlers + procedure ButtonClick(o: Object; e: RoutedEventArgs); + begin + var b := o as Button; + var Left := tb.Text.ToReal; + var Right := tb1.Text.ToReal; + case b.Text of + $'+': lb1.Content := '= ' + (Left + Right); + $'-': lb1.Content := '= ' + (Left - Right); + $'*': lb1.Content := '= ' + (Left * Right); + $'/': lb1.Content := '= ' + (Left / Right); + end; + end; + //-- InitControls + procedure InitControls; + begin + MainWindow.Title := 'Калькулятор'; + mainpanel := Panels.StackPanel.AsMainContent; + panel1 := Panels.StackPanel(Margin := 10, Horizontal := True) + .With(Background := Brushes.LightBlue) + .AddTo(mainpanel); + + tb := CreateTextBox('0', Width := 120); + lb := CreateLabel('+',Width := 35); + tb1 := CreateTextBox('0', Width := 120); + lb1 := CreateLabel('=',Width := 55); + panel1.AddElements(tb,lb,tb1,lb1); + + panel2 := Panels.StackPanel(Margin := |10,0,10,10|, Horizontal := True) + .With(Background := Brushes.LightBlue) + .AddTo(mainpanel); + panel2.HorizontalAlignment := HA.Right; + + bb := CreateButtons(|$'+',$'-',$'*',$'/'|); + panel2.AddButtons(bb, Width := 35, Margin := |10,0|, Padding := 5); + + for var i:=0 to bb.Length-1 do + bb[i].Click += ButtonClick; + + MainWindow.SizeToContent := SizeToContent.WidthAndHeight; + end; +end; + +begin + Main.Create.InitControls; +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_CheckBoxColors.pas b/InstallerSamples/StandardUnits/WPF/WPF_CheckBoxColors.pas new file mode 100644 index 000000000..c80d5e8c1 --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_CheckBoxColors.pas @@ -0,0 +1,36 @@ +uses WPF; + +function MixColor(r,g,b: boolean): Color; +begin + var ri := integer(r); + var gi := integer(g); + var bi := integer(b); + Result := RGB(ri*255,gi*255,bi*255); +end; + +type Main = class + mainpanel: StackPanel; + cbr,cbg,cbb: CheckBox; + constructor; + begin + mainpanel := Panels.StackPanel(Margin := 10, Horizontal := True) + .With(Background := Brushes.LightBlue).AsMainContent; + cbr := CreateCheckBox('Красный', Margin := 5); + cbg := CreateCheckBox('Зеленый', Margin := 5, IsChecked := True); + cbb := CreateCheckBox('Синий', Margin := 5); + mainpanel.AddElements(cbr,cbg,cbb); + cbr.Click += Handler; + cbg.Click += Handler; + cbb.Click += Handler; + Handler(nil,nil); + end; + procedure Handler(o: object; e: RoutedEventArgs); + begin + var (r,g,b) := (cbr.IsChecked,cbg.IsChecked,cbb.IsChecked); + mainpanel.Background := GBrush(MixColor(r.Value,g.Value,b.Value)); + end; +end; + +begin + Main.Create; +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_ComboBoxColors.pas b/InstallerSamples/StandardUnits/WPF/WPF_ComboBoxColors.pas new file mode 100644 index 000000000..562bb54db --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_ComboBoxColors.pas @@ -0,0 +1,18 @@ +uses WPF; + +begin + var colorNames := typeof(Colors).GetProperties + .ToDictionary(pi -> pi.Name, pi -> GBrush(Color(pi.GetValue(nil,nil)))); + MainWindow.Title := 'Standard Colors'; + MainWindow.WindowStartupLocation := WindowStartupLocation.CenterScreen; + var mainpanel := CreateStackPanel(Margin := 10, Horizontal := True).AsMainContent; + var panel1 := CreateStackPanel(Width := 250).AddTo(mainpanel); + var cb := CreateComboBox.AddTo(panel1); + cb.ItemsSource := colorNames.Keys; + var rect := CreateRectangle(Height := 200, Margin := |0,10|).AddTo(panel1); + rect.Fill := Brushes.Blue; + + cb.SelectionChanged += procedure(o,e) -> (rect.Fill := colorNames[cb.SelectedValue as string]); + + MainWindow.SizeToContent := SizeToContent.WidthAndHeight; +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_DockPanel1.pas b/InstallerSamples/StandardUnits/WPF/WPF_DockPanel1.pas new file mode 100644 index 000000000..41ac2ddc4 --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_DockPanel1.pas @@ -0,0 +1,19 @@ +uses WPF; + +begin + var dpanel := DockPanel.Create.AsMainContent; + var b := Controls.Button('One'); + var b1 := Controls.Button('Two'); + var b2 := Controls.Button('Three'); + var b3 := Controls.Button('Four'); + var b4 := Controls.Button('Five'); + dpanel.Children.Add(b); + dpanel.Children.Add(b1); + dpanel.Children.Add(b2); + dpanel.Children.Add(b3); + dpanel.Children.Add(b4); + DockPanel.SetDock(b,Dock.Left); + DockPanel.SetDock(b1,Dock.Right); + DockPanel.SetDock(b2,Dock.Top); + DockPanel.SetDock(b3,Dock.Bottom); +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_DockPanel2.pas b/InstallerSamples/StandardUnits/WPF/WPF_DockPanel2.pas new file mode 100644 index 000000000..eac5c4013 --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_DockPanel2.pas @@ -0,0 +1,13 @@ +uses WPF; + +begin + var dpanel := DockPanel.Create.AsMainContent; + var b := Controls.Button('One',Width := 100).AddTo(dpanel,Dock.Left); + var b1 := Controls.Button('Two',Width := 100).AddTo(dpanel,Dock.Right); + var b2 := Controls.Button('Three',Height := 50).AddTo(dpanel,Dock.Top); + var b3 := Controls.Button('Four',Height := 50).AddTo(dpanel,Dock.Bottom); + var b4 := Controls.Button('Five').AddTo(dpanel); + b.Click += (o,e) -> begin + MainWindow.Close + end; +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_FontChange.pas b/InstallerSamples/StandardUnits/WPF/WPF_FontChange.pas new file mode 100644 index 000000000..474c584be --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_FontChange.pas @@ -0,0 +1,26 @@ +uses WPF; + +begin + MainWindow.Title := 'Свойства шрифта'; + var dpanel := CreateDockPanel(Margin := 10).AsMainContent; + var toppanel := Panels.StackPanel(Horizontal := True, Margin := 0); + var TextLabel := CreateLabel('PascalABC.NET').With(HA := HA.Center, VA := VA.Center); + TextLabel.FontSize := 100; + dpanel.Add(toppanel,Dock.Top); + dpanel.Add(TextLabel); + + CreateLabel('Размер шрифта', Margin := 0).AddTo(toppanel); + var fontsizeslider := CreateSlider(20,100,10,10,Width := 100, Value := 100).AddTo(toppanel); + fontsizeslider.ValueChanged += procedure(o,e) -> TextLabel.FontSize := fontsizeslider.Value; + + CreateLabel('Имя шрифта',Margin := |20,0|).AddTo(toppanel); + var cb := CreateComboBox(|'Segoe UI','Arial','Times New Roman','Courier New'|).AddTo(toppanel); + cb.SelectionChanged += procedure(o,e) -> TextLabel.FontFamily := cb.SelectedValue.ToString; + + var chb := CreateCheckBox('Наклонный',Margin := |20,5,0,0|).AddTo(toppanel); + chb.Click += procedure(o,e) -> (TextLabel.FontStyle := + chb.IsChecked.Value ? FontStyles.Italic : FontStyles.Normal); + var chb2 := CreateCheckBox('Жирный',Margin := |20,5,0,0|).AddTo(toppanel); + chb2.Click += procedure(o,e) -> (TextLabel.FontWeight := + chb2.IsChecked.Value ? FontWeights.Bold : FontWeights.Normal); +end. \ No newline at end of file diff --git a/InstallerSamples/StandardUnits/WPF/WPF_RectProperties.pas b/InstallerSamples/StandardUnits/WPF/WPF_RectProperties.pas new file mode 100644 index 000000000..8c22ed1bc --- /dev/null +++ b/InstallerSamples/StandardUnits/WPF/WPF_RectProperties.pas @@ -0,0 +1,31 @@ +uses WPF; + +begin + MainWindow.Title := 'Rectangle свойства'; + MainWindow.WindowStartupLocation := WindowStartupLocation.CenterScreen; + var mainpanel := CreateDockPanel(Margin := 5).AsMainContent; + var leftpanel := CreateStackPanel(Margin := 0, Width := 150) + .With(Background := Brushes.Bisque).AddTo(mainpanel,Dock.Left); + var rect := CreateRectangle(Width := 300, Height := 200).With(HA := HA.Center, VA := VA.Center).AddTo(mainpanel); + rect.Fill := Brushes.Blue; + var widthslider := CreateSlider(50,500,10,50); + var tbwidth := CreateTextBlock(); + var heightslider := CreateSlider(50,500,10,50); + var tbHeight := CreateTextBlock(); + var radiusslider := CreateSlider(0,50,10,50); + var tbRadius := CreateTextBlock(); + + leftpanel.AddElements(widthslider, tbwidth, heightslider, tbHeight, radiusslider, tbRadius); + + widthslider.ValueChanged += procedure(o,e) -> tbwidth.Text := 'Ширина: ' + widthslider.Value.ToString(0); + heightslider.ValueChanged += procedure(o,e) -> tbheight.Text := 'Высота: ' + heightslider.Value.ToString(0); + radiusslider.ValueChanged += procedure(o,e) -> begin + tbRadius.Text := 'Радиус скругления: ' + radiusslider.Value.ToString(0); + rect.RadiusX := radiusslider.Value; + rect.RadiusY := radiusslider.Value; + end; + radiusslider.Value := 10; + + widthslider.SetBinding(Slider.ValueProperty, rect,'Width'); + heightslider.SetBinding(Slider.ValueProperty, rect,'Height'); +end. \ No newline at end of file diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 982cc1ce6..79bec13b9 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.9.0.3430 +3.9.0.3432 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 8e2e84c3f..734c75231 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.9.0.3430' +!define VERSION '3.9.0.3432' diff --git a/ReleaseGenerators/RebuildStandartModules.pas b/ReleaseGenerators/RebuildStandartModules.pas index 124bcc59b..27f776aa1 100644 --- a/ReleaseGenerators/RebuildStandartModules.pas +++ b/ReleaseGenerators/RebuildStandartModules.pas @@ -19,7 +19,8 @@ uses OpenCLABC, OpenCL, OpenGLABC, OpenGL, BBCMicroBit, School, SF, TwoPanelsWindow, NUnitABC, PlotWPF, XLSX, LightPT, Tasks, Мозаика, - TasksArr, TasksMatr, TasksStr, Tasks1Begin, Tasks1BoolIfCase, Tasks1Loops, Tasks1Arr + TasksArr, TasksMatr, TasksStr, Tasks1Begin, Tasks1BoolIfCase, Tasks1Loops, Tasks1Arr, + WPF ; begin diff --git a/ReleaseGenerators/sect_Core.nsh b/ReleaseGenerators/sect_Core.nsh index 1c82e2f80..5aa718d45 100644 --- a/ReleaseGenerators/sect_Core.nsh +++ b/ReleaseGenerators/sect_Core.nsh @@ -155,6 +155,7 @@ File ..\bin\Lib\Tasks1BoolIfCase.pcu File ..\bin\Lib\Tasks1Loops.pcu File ..\bin\Lib\Tasks1Arr.pcu + File ..\bin\Lib\WPF.pcu File ..\bin\Lib\PABCRtl.dll File ..\bin\Lib\HelixToolkit.Wpf.dll @@ -243,6 +244,7 @@ ${AddFile} "Tasks1BoolIfCase.pcu" ${AddFile} "Tasks1Loops.pcu" ${AddFile} "Tasks1Arr.pcu" + ${AddFile} "WPF.pcu" ${AddFile} "turtle.png" @@ -345,6 +347,7 @@ File ..\bin\Lib\PlotWPF.pas File ..\bin\Lib\XLSX.pas File ..\bin\Lib\Мозаика.pas + File ..\bin\Lib\WPF.pas File ..\bin\Lib\__RedirectIOMode.vb File ..\bin\Lib\VBSystem.vb @@ -421,6 +424,7 @@ ${AddFile} "PlotWPF.pas" ${AddFile} "XLSX.pas" ${AddFile} "Мозаика.pas" + ${AddFile} "WPF.pas" ${AddFile} "__RedirectIOMode.vb" diff --git a/bin/Lib/WPF.pas b/bin/Lib/WPF.pas new file mode 100644 index 000000000..f22ab18ce --- /dev/null +++ b/bin/Lib/WPF.pas @@ -0,0 +1,488 @@ +unit WPF; + +{$reference 'PresentationFramework.dll'} +{$reference 'WindowsBase.dll'} +{$reference 'PresentationCore.dll'} + +{$apptype windows} + +uses System.Windows; +uses System.Windows.Controls; +uses System.Windows.Controls.Primitives; +uses System.Windows.Data; +uses System.Windows.Media; +uses System.Windows.Shapes; +uses System.Windows.Markup; + +type + TControl = Control; + + Panel = Panel; + Grid = Grid; + Canvas = Canvas; + StackPanel = StackPanel; + DockPanel = DockPanel; + WrapPanel = WrapPanel; + + TPanel = Panel; + TGrid = Grid; + TStackPanel = StackPanel; + TDockPanel = DockPanel; + TCanvas = Canvas; + + // Типы элементов управления + Button = Button; + TButton = Button; + &Label = &Label; + TLabel = &Label; + CheckBox = CheckBox; + TextBox = TextBox; + Slider = Slider; + ComboBox = ComboBox; + TextBlock = TextBlock; + Rectangle = Rectangle; + + DrawingVisual = DrawingVisual; + + Thickness = Thickness; + TThickness = Thickness; + FontStyle = FontStyle; + FontStyles = FontStyles; + GridLength = GridLength; + GridUnitType = GridUnitType; + Brushes = Brushes; + Brush = Brush; + Pen = Pen; + Point = Point; + Colors = Colors; + SolidColorBrush = SolidColorBrush; + Orientation = Orientation; + TOrientation = Orientation; + VerticalAlignment = VerticalAlignment; + HorizontalAlignment = HorizontalAlignment; + HA = HorizontalAlignment; + VA = VerticalAlignment; + Dock = Dock; + Color = Color; + TColor = Color; + TickPlacement = TickPlacement; + Binding = Binding; + PropertyPath = PropertyPath; + + EventArgs = System.EventArgs; + RoutedEventArgs = RoutedEventArgs; + RoutedEventHandler = RoutedEventHandler; + EventHandler = RoutedEventHandler; + + SizeToContent = SizeToContent; + + FontWeight = FontWeight; + FontWeights = FontWeights; + WindowStartupLocation = WindowStartupLocation; + +var Application := new Application; +var MainWindow: Window; +var Content: UIElement; +var CurrentParent: FrameworkElement := nil; + +type + Drawing = class(FrameworkElement) + public + children: VisualCollection; + protected + function GetVisualChild(index: integer): Visual; override; + begin + if (index < 0) or (index >= children.Count) then + raise new System.ArgumentOutOfRangeException(); + Result := children[index]; + end; + public + constructor := children := new VisualCollection(Self); + property VisualChildrenCount: integer read children.Count; override; + procedure Add(v: DrawingVisual) := children.Add(v); + end; + +function RGB(r,g,b: byte) := Color.Fromrgb(r, g, b); +function ARGB(a,r,g,b: byte) := Color.FromArgb(a, r, g, b); +function GrayColor(b: byte): Color := RGB(b, b, b); +function RandomColor := RGB(PABCSystem.Random(256), PABCSystem.Random(256), PABCSystem.Random(256)); +function EmptyColor: Color := ARGB(0,0,0,0); +function Pnt(x,y: real) := new Point(x,y); +function Rect(x,y,w,h: real) := new System.Windows.Rect(x,y,w,h); + +function CreateDrawing := Drawing.Create; + +function operator implicit(n: integer): Thickness; extensionmethod; +begin + Result := new Thickness(n); +end; + +function operator implicit(n: real): Thickness; extensionmethod; +begin + Result := new Thickness(n); +end; + +function operator implicit(a: array of real): Thickness; extensionmethod; +begin + case a.Length of + 1: Result := new Thickness(a[0]); + 2: Result := new Thickness(a[0],a[1],0,0); + 3: Result := new Thickness(a[0],a[1],a[2],0); + 4: Result := new Thickness(a[0],a[1],a[2],a[3]); + end; +end; + +function operator implicit(a: array of integer): Thickness; extensionmethod; +begin + case a.Length of + 1: Result := new Thickness(a[0]); + 2: Result := new Thickness(a[0],a[1],0,0); + 3: Result := new Thickness(a[0],a[1],a[2],0); + 4: Result := new Thickness(a[0],a[1],a[2],a[3]); + end; +end; + +function operator implicit(name: string): FontFamily; extensionmethod; +begin + Result := new FontFamily(name); +end; + + +procedure SetPosition(Self: Control; Left,Top: real); extensionmethod; +begin + Canvas.SetLeft(Self,Left); + Canvas.SetTop(Self,Top); +end; + +procedure Add(Self: Panel; c: FrameworkElement); extensionmethod := Self.Children.Add(c); + +procedure Add(Self: Grid; c: FrameworkElement; row,col: integer); extensionmethod; +begin + Self.Children.Add(c); + Grid.SetRow(c,row); + Grid.SetColumn(c,col); +end; + +function AddToCell(Self: T; gr: TGrid; row,col: integer): T; extensionmethod; where T: FrameworkElement; +begin + Result := Self; + if gr<>nil then + gr.Add(Result,row,col); +end; + +function AddTo(Self: T; gr: TPanel): T; extensionmethod; where T: FrameworkElement; +begin + Result := Self; + if gr<>nil then + gr.Add(Result); +end; + +function AddTo(Self: DrawingVisual; dr: Drawing): DrawingVisual; extensionmethod; +begin + Result := Self; + if dr<>nil then + dr.children.Add(Result); +end; + +function GBrush(c: Color): Brush := new SolidColorBrush(c); +function GBrush(r,g,b: integer): Brush := new SolidColorBrush(Color.FromRgb(r,g,b)); +function GBrush(a,r,g,b: integer): Brush := new SolidColorBrush(Color.FromARgb(a,r,g,b)); + +function GPen(c: Color; width: real := 1) := new Pen(GBrush(c),width); + +var CurrentPen := GPen(Colors.Black,1); +var CurrentBrush := GBrush(Colors.White); + +// Декораторы +function &With(Self: TGrid; ShowGridLines: boolean := True): TGrid; extensionmethod; +begin + Self.ShowGridLines := ShowGridLines; + Result := Self; +end; + +function &With(Self: T; Margin: Thickness := 0; + HA: HorizontalAlignment := WPF.HA.Stretch; + VA: VerticalAlignment := WPF.VA.Stretch + ): T; extensionmethod; where T: FrameworkElement; +begin + Self.Margin := Margin; + Self.HorizontalAlignment := HA; + Self.VerticalAlignment := VA; + Result := Self; +end; + +function &With(Self: StackPanel; Background: Brush := nil; + Color: TColor := Colors.White): StackPanel; extensionmethod; +begin + if Background <> nil then + Self.Background := Background + else Self.Background := GBrush(color); + Result := Self; +end; + +function &With(Self: Canvas; Background: Brush := nil; + Color: TColor := Colors.White): Canvas; extensionmethod; +begin + if Background <> nil then + Self.Background := Background + else Self.Background := GBrush(color); + Result := Self; +end; + +function AsMainContent(Self: T): T; extensionmethod; where T: FrameworkElement; +begin + MainWindow.Content := Self; + Result := Self; + CurrentParent := Self; +end; + +procedure Render(Self: DrawingVisual; draw: DrawingContext -> ()); extensionmethod; +begin + var dc := Self.RenderOpen(); + draw(dc); + dc.Close; +end; + +function CreateBinding(Source: FrameworkElement; PropertyName: string; Mode: BindingMode := BindingMode.Default): Binding; +begin + var bind := new Binding(); + bind.Source := Source; + bind.Path := new PropertyPath(PropertyName); + bind.Mode := Mode; + Result := bind; +end; + +function SetBinding(Self: FrameworkElement; dp: DependencyProperty; dest: FrameworkElement; + PropertyName: string; Mode: BindingMode := BindingMode.Default): BindingExpressionBase; extensionmethod + := Self.SetBinding(dp,CreateBinding(dest,PropertyName,Mode)); + +// Методы расширения панелей +procedure DockPanel.Add(c: FrameworkElement; dock: WPF.Dock); +begin + Self.Add(c); + DockPanel.SetDock(c,dock); +end; + +procedure StackPanel.Add(c: FrameworkElement); +begin + Self.Children.Add(c); +end; + +procedure StackPanel.AddElements(params aa: array of FrameworkElement); +begin + foreach var c in aa do + Self.Children.Add(c); +end; + +procedure StackPanel.AddButtons(buttons: array of Button; + Width: real := real.NaN; Height: real := real.NaN; Padding: Thickness := 0; Margin: Thickness := 0); +begin + foreach var b in buttons do + begin + b.Margin := Margin; + b.Padding := Padding; + b.Width := Width; + b.Height := Height; + Self.Add(b); + end; +end; + +function Text(Self: TButton): string; extensionmethod := Self.Content as string; +function Text(Self: &Label): string; extensionmethod := Self.Content as string; +function Text(Self: CheckBox): string; extensionmethod := Self.Content as string; + +function AddTo(Self: T; gr: DockPanel; dock: WPF.Dock): T; extensionmethod; where T: FrameworkElement; +begin + Result := Self; + if gr<>nil then + gr.Add(Result,dock); +end; + +function Init(Self: FrameworkElement; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0): FrameworkElement; extensionmethod; +begin + Self.Width := Width; + Self.Height := Height; + Self.Margin := Margin; + Result := Self; +end; + +function LoadFromXaml(fname: string): object; +begin + var s := ReadAllText(fname); + var context := new ParserContext(); + context.XmlnsDictionary.Add('','http://schemas.microsoft.com/winfx/2006/xaml/presentation'); + context.XmlnsDictionary.Add('x', 'http://schemas.microsoft.com/winfx/2006/xaml'); + Result := System.Windows.Markup.XamlReader.Parse(ReadAllText(fname),nil); + + //var s := new System.IO.FileStream(fname, System.IO.FileMode.Open); + //Result := System.Windows.Markup.XamlReader.Load(s); + //s.Close(); +end; + +// Функции создания элементов управления + +function CreateButton(Text: string; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0; Padding: Thickness := 0): Button; +begin + Result := Button.Create; + Result.Init(Width,Height,Margin); + Result.Content := Text; + Result.Padding := Padding; +end; + +function CreateButtons(Texts: array of string; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0; Padding: Thickness := 0): array of Button; +begin + Result := new Button[Texts.Length]; + for var i:=0 to Result.Length - 1 do + Result[i] := CreateButton(Texts[i], Width, Height, Margin, Padding); +end; + +function CreateTextBox(Text: string; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0): TextBox; +begin + Result := TextBox.Create; + Result.Init(Width,Height,Margin); + Result.Text := Text; +end; + +function CreateLabel(Text: string; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0): &Label; +begin + Result := &Label.Create; + Result.Init(Width,Height,Margin); + Result.Content := Text; +end; + +function CreateTextBlock(Text: string := ''; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0): TextBlock; +begin + Result := TextBlock.Create; + Result.Init(Width,Height,Margin); + Result.Text := Text; +end; + +function CreateCheckBox(Text: string; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0; IsChecked: boolean := False): CheckBox; +begin + Result := CheckBox.Create; + Result.Init(Width,Height,Margin); + Result.Content := Text; + Result.IsChecked := IsChecked; +end; + +function CreateSlider(Min: real := 0; Max: real := 10; Step: real := 1; TickFrequency: real := 1; + Width: real := real.NaN; Height: real := real.NaN; Margin: Thickness := 0; + Value: real := real.NaN): Slider; +begin + Result := Slider.Create; + Result.Init(Width,Height,Margin); + Result.Minimum := Min; + Result.Maximum := Max; + Result.SmallChange := Step; + Result.LargeChange := Step; + Result.TickFrequency := TickFrequency; + Result.TickPlacement := TickPlacement.TopLeft; + if not real.IsNaN(Value) then + Result.Value := Value +end; + +//-- Создание панелей + +function CreateComboBox(Items: array of string := nil; Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0): ComboBox; +begin + Result := ComboBox.Create; + Result.Init(Width,Height,Margin); + if items <> nil then + foreach var item in items do + Result.Items.Add(item); + Result.SelectedIndex := 0; +end; + +function CreateGrid(rows: integer := 1; cols: integer := 1; ColumnWidths: array of real := nil; + RowHeights: array of real := nil): Grid; +begin + var gr := new Grid; + //gr.ShowGridLines := True; + loop rows do + gr.RowDefinitions.Add(new RowDefinition); + loop cols do + gr.ColumnDefinitions.Add(new ColumnDefinition); + if ColumnWidths <> nil then + for var i:=0 to ColumnWidths.Length - 1 do + gr.ColumnDefinitions[i].Width := new GridLength(ColumnWidths[i],GridUnitType.Star); + if RowHeights <> nil then + for var i:=0 to RowHeights.Length - 1 do + gr.RowDefinitions[i].Height := new GridLength(RowHeights[i],GridUnitType.Star); + Result := gr; +end; + +function CreateDockPanel(Margin: Thickness := 0): DockPanel; +begin + Result := new DockPanel; + Result.Margin := Margin; +end; + +function CreateCanvas(Margin: Thickness := 0): Canvas; +begin + Result := new Canvas; + Result.Margin := Margin; +end; + +function CreateStackPanel(Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0; Horizontal: boolean := False): StackPanel; +begin + Result := new StackPanel; + Result.Init(Width,Height,Margin); + if Horizontal then + Result.Orientation := Orientation.Horizontal; +end; + +function CreateRectangle(Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0): Rectangle; +begin + Result := new Rectangle; + Result.Init(Width,Height,Margin); +end; + +type + ///!# + Controls = static class + static function Button(Text: string; Left: real := real.NaN; Top: real := real.NaN; + Width: real := real.NaN; Height: real := real.NaN; Margin: Thickness := 0; + Padding: Thickness := 0): TButton + := WPF.CreateButton(Text,Width,Height,Margin,Padding); + static function Drawing: WPF.Drawing + := CreateDrawing; + static function DrawingVisual: WPF.DrawingVisual + := new WPF.DrawingVisual; + end; + Panels = static class + static function Grid(rows: integer := 1; cols: integer := 1; ColumnWidths: array of real := nil; RowHeights: array of real := nil): TGrid + := CreateGrid(rows,cols,ColumnWidths,RowHeights); + static function StackPanel(Width: real := real.NaN; Height: real := real.NaN; + Margin: Thickness := 0; Horizontal: boolean := False): TStackPanel + := CreateStackPanel(Width,Height,Margin,Horizontal); + static function DockPanel(Margin: Thickness := 0): TDockPanel := CreateDockPanel(Margin); + end; + +initialization + MainWindow := new Window; + + MainWindow.Width := 800; + MainWindow.Height := 600; + MainWindow.Title := 'WPF'; + + var w := SystemParameters.PrimaryScreenWidth - MainWindow.Width; + var h := SystemParameters.PrimaryScreenHeight - Mainwindow.Height; + MainWindow.Left := w/2; + MainWindow.Top := h/2; + + var gr := new Grid; + MainWindow.Content := gr; + CurrentParent := MainWindow; +finalization + Application.Run(MainWindow); +end. \ No newline at end of file