diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 08e217568..d368ecaa6 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 = "6"; public const string Build = "3"; - public const string Revision = "2589"; + public const string Revision = "2591"; 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 2491e8550..c76a5dae1 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %MINOR%=6 -%REVISION%=2589 +%REVISION%=2591 %COREVERSION%=3 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 676971064..3b094cadf 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.6.3.2589 +3.6.3.2591 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 177971401..3e608f81f 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.6.3.2589' +!define VERSION '3.6.3.2591' diff --git a/ReleaseGenerators/RebuildStandartModules.pas b/ReleaseGenerators/RebuildStandartModules.pas index 3dacd3073..63b210545 100644 --- a/ReleaseGenerators/RebuildStandartModules.pas +++ b/ReleaseGenerators/RebuildStandartModules.pas @@ -15,7 +15,7 @@ ABCDatabases,BlockFileOfT,Controls, OpenCL, OpenCLABC, OpenGL, OpenGLABC, - BBCMicroBit, School, SF + BBCMicroBit, School, SF, TwoPanelsWindow ; begin diff --git a/ReleaseGenerators/sect_Core.nsh b/ReleaseGenerators/sect_Core.nsh index a2b6d610f..c2e701e74 100644 --- a/ReleaseGenerators/sect_Core.nsh +++ b/ReleaseGenerators/sect_Core.nsh @@ -135,6 +135,7 @@ File ..\bin\Lib\School.pcu File ..\bin\Lib\SF.pcu File ..\bin\Lib\Turtle.pcu + File ..\bin\Lib\TwoPanelsWindow.pcu File ..\bin\Lib\PABCRtl.dll File ..\bin\Lib\HelixToolkit.Wpf.dll @@ -204,6 +205,8 @@ ${AddFile} "School.pcu" ${AddFile} "SF.pcu" ${AddFile} "Turtle.pcu" + ${AddFile} "TwoPanelsWindow.pcu" + ${AddFile} "PABCRtl.dll" ${AddFile} "HelixToolkit.Wpf.dll" @@ -284,6 +287,7 @@ File ..\bin\Lib\School.pas File ..\bin\Lib\SF.pas File ..\bin\Lib\Turtle.pas + File ..\bin\Lib\TwoPanelsWindow.pas File ..\bin\Lib\__RedirectIOMode.vb File ..\bin\Lib\VBSystem.vb @@ -350,6 +354,8 @@ ${AddFile} "School.pas" ${AddFile} "SF.pas" ${AddFile} "Turtle.pas" + ${AddFile} "TwoPanelsWindow.pas" + ${AddFile} "__RedirectIOMode.vb" ${AddFile} "VBSystem.vb" diff --git a/TestSuite/CompilationSamples/GraphWPF.pas b/TestSuite/CompilationSamples/GraphWPF.pas index fc456e094..cb86be1f3 100644 --- a/TestSuite/CompilationSamples/GraphWPF.pas +++ b/TestSuite/CompilationSamples/GraphWPF.pas @@ -1931,6 +1931,7 @@ public begin host1 := new Canvas; host := new MyVisualHost(); + host1.ClipToBounds := True; host1.SizeChanged += (s,e) -> begin var sz := e.NewSize; diff --git a/TestSuite/CompilationSamples/graph3d.pas b/TestSuite/CompilationSamples/graph3d.pas index d5e028473..bc33b6b0a 100644 --- a/TestSuite/CompilationSamples/graph3d.pas +++ b/TestSuite/CompilationSamples/graph3d.pas @@ -3385,7 +3385,7 @@ function Pyramid(p: Point3D; Sides: integer; Height, Radius: real; m: Material): function PyramidWireFrame(x, y, z: real; Sides: integer; Height, Radius: real; Thickness: real; c: Color): PyramidTWireFrame := Inv(()->PyramidTWireFrame.Create(x, y, z, Sides, Radius, Height, thickness, c)); -function PyramidWireFrame(p: Point3D; Sides: integer; Height, Radius: real; Thickness: real; c: Color): PyramidTWireFrame := PyramidWireFrame(p.x, p.y, p.z, Sides, Radius, Height, thickness, c); +function PyramidWireFrame(p: Point3D; Sides: integer; Height, Radius: real; Thickness: real; c: Color): PyramidTWireFrame := PyramidWireFrame(p.x, p.y, p.z, Sides, Height, Radius, thickness, c); function Lego(x, y, z: real; Rows, Columns, Height: integer; m: Material): LegoT := Inv(()->LegoT.Create(x, y, z, Rows, Columns, Height, m)); diff --git a/VisualPascalABCNET/AutoInsertCode/AutoInsertCode.cs b/VisualPascalABCNET/AutoInsertCode/AutoInsertCode.cs index dfe430529..c412de063 100644 --- a/VisualPascalABCNET/AutoInsertCode/AutoInsertCode.cs +++ b/VisualPascalABCNET/AutoInsertCode/AutoInsertCode.cs @@ -202,6 +202,24 @@ namespace VisualPascalABC return true; } + else if (TextToLower == "with") + { + string cur, next, prev; + GetCurNextLines(out cur, out next, out prev); + if (!string.IsNullOrWhiteSpace(cur.Substring(caret.Column))) + return false; + var icur = Indent(cur); + ta.InsertString("\n" + Spaces(icur + 2)); + if (cur.TrimStart().ToLower().StartsWith("match") && next == null || Indent(next) < icur || Indent(next) == icur && !next.TrimStart().ToLower().StartsWith("end")) + { + var tl_beg = new TextLocation(ta.Caret.Column, ta.Caret.Line); + int offset = doc.PositionToOffset(tl_beg); + var send = "\n" + Spaces(icur) + "end;"; + doc.Insert(offset, send); + } + return true; + } + else if (Regex.IsMatch(TextToLower, "then|else|do|try|except|finally|var")) { if (ta.Caret.Line > 0 && TextToLower == "else") diff --git a/bin/Lib/Controls.pas b/bin/Lib/Controls.pas index 1bacbe659..201ea0c2d 100644 --- a/bin/Lib/Controls.pas +++ b/bin/Lib/Controls.pas @@ -1,383 +1,573 @@ // Copyright (©) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) -///Модуль элементов управления для GraphWPF +///Модуль элементов управления для GraphWPF и WPFObjects unit Controls; interface -uses GraphWPFBase; +uses GraphWPFBase,GraphWPF; uses System.Windows; uses System.Windows.Media; uses System.Windows.Controls; +uses System.Windows.Controls.Primitives; uses System.ComponentModel; -procedure AddRightPanel(Width: real := 200; c: Color := Colors.LightGray; Margin: real := 10); -procedure AddLeftPanel(Width: real := 200; c: Color := Colors.LightGray; Margin: real := 10); -procedure AddTopPanel(Height: real := 70; c: Color := Colors.LightGray; Margin: real := 10); -procedure AddBottomPanel(Height: real := 70; c: Color := Colors.LightGray; Margin: real := 10); -procedure AddStatusBar(Height: real := 24); - -var - ActivePanel: Panel; - GlobalHMargin := 12; +const PanelsColor = Colors.WhiteSmoke; type + Dock = System.Windows.Controls.Dock; GButton = System.Windows.Controls.Button; GTextBlock = System.Windows.Controls.TextBlock; GTextBox = System.Windows.Controls.TextBox; GListBox = System.Windows.Controls.ListBox; + GPanel = System.Windows.Controls.Panel; + GControl = System.Windows.Controls.Control; + GStatusBar = System.Windows.Controls.Primitives.StatusBar; + Colors = System.Windows.Media.Colors; Key = System.Windows.Input.Key; + +var + ActivePanel: GPanel; + GlobalHMargin := 12; + +type ///!# - CommonControl = class + PanelWPF = class + protected + p: StackPanel; + bb: Border; + procedure CreateP(wh: real; d: Dock; c: Color; InternalMargin: real); + begin + bb := new Border(); + bb.Background := new SolidColorBrush(c); + p := new StackPanel; + bb.Child := p; + p.Background := GetBrush(c); + p.Margin := new System.Windows.Thickness(InternalMargin); + + if (d = Dock.Left) or (d = Dock.Right) then + begin + p.Orientation := Orientation.Vertical; + bb.Width := wh; + end + else + begin + p.Orientation := Orientation.Horizontal; + bb.Height := wh; + end; + DockPanel.SetDock(bb, d); + MainDockPanel.children.Insert(0, bb); + ActivePanel := p; + end; + procedure SetColorP(c: GColor); + begin + p.Background := GetBrush(c); + bb.Background := p.Background + end; + function GetColorP := (p.Background as SolidColorBrush).Color; + public + constructor Create(wh: real := 150; d: Dock := Dock.Left; c: Color := PanelsColor; internalMargin: real := 10); + begin + Invoke(CreateP,wh,d,c,internalMargin); + end; + property Color: GColor read Invoke&(GetColorP) write Invoke(SetColorP, value); + property InternalMargin: real + read InvokeReal(()->p.Margin.Left) + write Invoke(procedure -> p.Margin := new System.Windows.Thickness(internalMargin), value); + end; + + LeftPanelWPF = class(PanelWPF) + public + constructor Create(width: real := 150; c: GColor := PanelsColor; internalMargin: real := 10); + begin + inherited Create(width, Dock.Left,c,internalMargin) + end; + end; + + RightPanelWPF = class(PanelWPF) + public + constructor Create(width: real := 150; c: GColor := PanelsColor; internalMargin: real := 10); + begin + inherited Create(width, Dock.Right,c,internalMargin) + end; + end; + + ///!# + CommonElementWPF = class protected element: FrameworkElement; - function GetM: real := InvokeReal(()->element.Margin.Top); - procedure SetMP(m: real) := element.Margin := new Thickness(m); - procedure SetM(m: real) := Invoke(SetMP, m); - function GetW: real := InvokeReal(()->element.Width); + procedure Init0(el: FrameworkElement; width: real := 0; x: real := -1; y: real := -1); + begin + element := el; + element.Focusable := False; + if ActivePanel is StackPanel(var sp) then + if sp.Orientation = Orientation.Vertical then + element.Margin := new Thickness(0,0,0,GlobalHMargin); + //else element.Margin := new Thickness(0,0,GlobalHMargin,0); + if x<>-1 then + begin + element.SetLeft(x); + element.SetTop(y); + end; + if width>0 then + element.Width := width; + ActivePanel.Children.Add(element); + end; + procedure SetWP(w: real) := element.Width := w; - procedure SetW(w: real) := Invoke(SetWP, w); - function GetH: real := InvokeReal(()->element.Height); procedure SetHP(h: real) := element.Height := h; - procedure SetH(h: real) := Invoke(SetHP, h); + procedure SetMP(m: real) := element.Margin := new Thickness(0,0,0,m); + procedure SetEP(enabled: boolean) := element.IsEnabled := enabled; public - property Width: real read GetW write SetW; - property Height: real read GetH write SetH; - property Margin: real read GetM write SetM; + property Width: real read InvokeReal(()->element.Width) write Invoke(SetWP, value); + property Height: real read InvokeReal(()->element.Height) write Invoke(SetHP, value); + property Margin: real read InvokeReal(()->element.Margin.Bottom) write Invoke(SetMP, value); + property Enabled: boolean read InvokeBoolean(()->element.IsEnabled) write Invoke(SetEP, value); end; + + CommonControlWPF = class(CommonElementWPF) + private + procedure SetFSzP(size: real) := control.FontSize := size; + public + property Control: GControl read element as GControl; + property FontSize: real read InvokeReal(()->control.FontSize) write Invoke(SetFSzP, value); + end; + ///!# - ButtonT = class(CommonControl) + ClickableControlWPF = class(CommonControlWPF) protected - function b: GButton := element as GButton; - procedure BClick(sender: Object; e: RoutedEventArgs); + procedure ClickP(sender: Object; e: RoutedEventArgs); + begin + if Click <> nil then + Click; + end; + public + Click: procedure; + end; + + ///!# + ButtonWPF = class(CommonControlWPF) + protected + property b: GButton read element as GButton; + + procedure CreatePXY(x,y: real; Txt: string; width: real; fontSize: real); + begin + Init0(new GButton,width,x,y); + Text := Txt; + Self.FontSize := fontSize; + b.Click += (o,e) -> if Click <> nil then Click; + end; + procedure CreateP(text: string; fontSize: real) := CreatePXY(-1,-1,text,0,fontSize); + + procedure SetTextP(t: string) := b.Content := t; + public + Click: procedure; + constructor Create(Txt: string; fontSize: real := 12) := Invoke(CreateP, Txt, fontSize); + constructor Create(x, y: real; Txt: string; width: real := 0; fontSize: real := 12) := Invoke(CreatePXY, x, y, Txt, width, fontSize); + + property Text: string read InvokeString(()->b.Content as string) write Invoke(SetTextP, value); + end; + + ///!# + TextBlockWPF = class(CommonElementWPF) + protected + property tb: GTextBlock read element as GTextBlock; + + procedure CreatePXY(x, y: real; Txt: string; width: real; fontsize: real); + begin + Init0(new GTextBlock, width, x, y); + Margin := 3; + Text := Txt; + Self.FontSize := fontSize; + end; + procedure CreateP(text: string; fontSize: real) := CreatePXY(-1,-1,text,0,fontSize); + + procedure SetTextP(t: string) := tb.Text := t; + procedure SetFontSizeP(sz: real) := tb.FontSize := sz; + public + constructor Create(Txt: string; fontsize: real := 12):= Invoke(CreateP, Txt, fontsize); + constructor Create(x, y: real; Txt: string; width: real := 0; fontSize: real := 12):= Invoke(CreatePXY, x, y, Txt, width, fontSize); + + property Text: string read InvokeString(()->tb.Text) write Invoke(SetTextP, value); + property FontSize: real read InvokeReal(()->tb.FontSize) write Invoke(SetFontSizeP, value); + end; + + IntegerBlockWPF = class(TextBlockWPF) + private + val := 0; + message: string; + procedure CreatePXY(x, y: real; message: string; width: real; initValue: integer := 0; fontSize: real := 12); + begin + inherited CreatePXY(x,y,message + ' ' + initValue, width, fontSize); + Self.message := message; + val := initValue; + end; + procedure CreateP(message: string; initValue: integer := 0; fontSize: real := 12) := CreatePXY(-1,-1,message,0,initValue,fontSize); + public + constructor Create(message: string; initValue: integer := 0; fontSize: real := 12) := Invoke(CreateP, message, initValue, fontSize); + constructor Create(x, y: real; message: string; width: real := 0; initValue: integer := 0; fontSize: real := 12) := Invoke(CreatePXY, x, y, message, width, initValue, fontSize); + + property Value: integer read val write begin val := value; Text := message + ' ' + val; end; + end; + + RealBlockWPF = class(TextBlockWPF) + private + val := 0.0; + message: string; + procedure CreatePXY(x, y: real; message: string; width: real; initValue: real := 0; fontSize: real := 12); + begin + inherited CreatePXY(x,y,message + ' ' + initValue, width, fontSize); + Self.message := message; + val := initValue; + end; + procedure CreateP(message: string; initValue: real := 0; fontSize: real := 12) := CreatePXY(-1,-1,message,0,initValue,fontSize); + public + constructor Create(message: string; initValue: real := 0; fontSize: real := 12) := Invoke(CreateP, message, initValue, fontSize); + constructor Create(x, y: real; message: string; width: real := 0; initValue: real := 0; fontSize: real := 12) := Invoke(CreatePXY, x, y, message, width, initValue, fontSize); + + property Value: real read val write begin val := value; Text := message + ' ' + val.ToString(FracDigits); end; + auto property FracDigits: integer := 1; + end; + + ///!# + TextBoxWPF = class(CommonControlWPF) + protected + property tb: GTextBox read element as GTextBox; + + procedure SetTextP(t: string) := tb.Text := t; + + procedure CreatePXY(x,y: real; txt: string; width: real); + begin + Init0(new GTextBox,width,x,y); + Text := txt; + tb.TextChanged += (o,e) -> if Click <> nil then Click; + element.Focusable := True; + //element.HorizontalAlignment := HorizontalAlignment.Stretch; + end; + procedure CreateP(text: string) := CreatePXY(-1,-1,text,0); + public + Click: procedure; + constructor Create(text: string := '') := Invoke(CreateP, text); + constructor Create(x,y: real; text: string := ''; width: real := 0) := Invoke(CreatePXY, x, y, text, width); + + property Text: string read InvokeString(()->tb.Text) write Invoke(SetTextP, value); + end; + + IntegerBoxWPF = class(TextBoxWPF) + function GetValue: integer; + begin + if Trim(Text) = '' then + Result := 0 + else Result := integer.Parse(Text); + Result := Result.Clamp(Min,Max); + end; + + procedure SetValue(x: integer) := Text := x.Clamp(Min,Max).ToString; + procedure Rest(min,max:integer); + begin + Self.Min := min; + Self.Max := max; + Value := Min; + tb.MouseWheel += (o, e) -> begin + if e.Delta > 0 then + Value := Value + 1 + else if e.Delta < 0 then + Value := Value - 1 + end; + tb.KeyDown += (o, e) -> begin + if not ((e.Key >= Key.D0) and (e.Key <= Key.D9)) then + e.Handled := True; + end; + end; + public + constructor Create(min: integer := 0; max: integer := 10); + begin + inherited Create(''); + Rest(min,max); + end; + constructor Create(x,y: real; min,max: integer; width: real := 0); + begin + inherited Create(x,y,'',width); + Rest(min,max); + end; + + auto property Min: integer := 0; + auto property Max: integer := 100; + + property Value: integer read GetValue write SetValue; + end; + + {TextBoxWithBlockWPF = class(CommonControlWPF) + private + l: TextBlock; + protected + function tb: GTextBox := (element as StackPanel).Children[1] as GTextBox; + procedure BTextChanged(sender: Object; e: TextChangedEventArgs); begin if Click <> nil then Click; end; - function GetText: string := InvokeString(()->b.Content as string); - procedure SetTextP(t: string) := b.Content := t; + function GetText: string := InvokeString(()->tb.Text); + procedure SetTextP(t: string) := tb.Text := t; procedure SetText(t: string) := Invoke(SetTextP, t); - procedure CreateP(Txt: string; fontSize: real); + procedure CreateP(BlockTxt, Txt: string; w: real); begin - element := new GButton; - element.Margin := new Thickness(0, 0, 0, GlobalHMargin); - //Margin := GlobalMargin; + var sp := new StackPanel; + element := sp; + + sp.Orientation := Orientation.Horizontal; + sp.HorizontalAlignment := HorizontalAlignment.Stretch; + l := new TextBlock(); + l.Text := BlockTxt; + sp.Children.Add(l); + var tb := new GTextBox; + tb.Width := 100; + tb.VerticalAlignment := VerticalAlignment.Stretch; + tb.Margin := new Thickness(0, 0, 0, GlobalHMargin); + sp.Children.Add(tb); Text := Txt; - Self.FontSize := fontSize; - b.Click += BClick; - b.Focusable := False; - ActivePanel.Children.Add(b); - end; - - procedure CreatePXY(x, y: real; Txt: string; fontSize: real); - begin - element := new GButton; - element.SetLeft(x); - element.SetTop(y); - element.Margin := new Thickness(0, 0, 0, GlobalHMargin); - //Margin := GlobalMargin; - Text := Txt; - b.Click += BClick; - b.Focusable := False; - ActivePanel.Children.Add(b); + if w > 0 then + Width := w; + tb.TextChanged += BTextChanged; + ActivePanel.Children.Add(sp); end; public Click: procedure; - constructor Create(Txt: string; fontSize: real := 12); + constructor Create(blockTxt: string; Txt: string := ''; w: real := 0); begin - Invoke(CreateP, Txt, fontSize); - end; - - constructor Create(x, y: real; Txt: string; fontsize: real := 12); - begin - Invoke(CreatePXY, x, y, Txt, fontsize); + Invoke(CreateP, blockTxt, Txt, w); end; property Text: string read GetText write SetText; - property FontSize: real read InvokeReal(()->b.FontSize) write Invoke(procedure(t: real) -> b.FontSize := t, value); - property Enabled: boolean read InvokeBoolean(()->b.IsEnabled) write Invoke(procedure(t: boolean) -> b.IsEnabled := t, value); - end; - + property FontSize: real read InvokeReal(()->tb.FontSize) write Invoke(procedure(t: real) -> begin tb.FontSize := t; l.FontSize := t; end, value); + end;} + ///!# - TextBlockT = class(CommonControl) + ListBoxWPF = class(CommonControlWPF) protected - function b: GTextBlock := element as GTextBlock; - procedure CreateP(Txt: string; fontsize: real); + function lb: GListBox := element as GListBox; + procedure CreatePXY(x,y,w,h: real); begin - var tb := new GTextBlock; - element := tb; - //element.Margin := new Thickness(0, 0, 0, GlobalHMargin); - //element.Margin := new Thickness(5,5,5,0); - tb.FontSize := fontsize; - Text := Txt; - ActivePanel.Children.Add(b); + Init0(new GListBox,w,x,y); + //element.HorizontalAlignment := HorizontalAlignment.Stretch; + Height := h; + lb.SelectionChanged += (o,e) -> if SelectionChanged<>nil then SelectionChanged; end; + procedure CreateP(h: real) := CreatePXY(-1,-1,0,h); - procedure CreatePXY(x, y: real; Txt: string; fontsize: real); + procedure AddP(s: string); begin - var tb := new GTextBlock; - element := tb; - element.Margin := new Thickness(0, 0, 0, GlobalHMargin); - //tb.Background := new SolidColorBrush(Colors.White); - //tb.Opacity := 0.7; - Canvas.SetLeft(element, x); - Canvas.SetTop(element, y); - tb.FontSize := fontsize; - Text := Txt; - ActivePanel.Children.Add(b); - end; - + var lbi := new ListBoxItem(); + lbi.Content := s; + lb.Items.Add(lbi); + end; + + procedure AddRangeP(ss: sequence of string); + begin + foreach var s in ss do + AddP(s); + end; + + procedure SortP := lb.Items.SortDescriptions.Add(new SortDescription('Content', ListSortDirection.Ascending)); + procedure SortPDescending := lb.Items.SortDescriptions.Add(new SortDescription('Content', ListSortDirection.Descending)); public - constructor Create(Txt: string; fontsize: real := 12):= Invoke(CreateP, Txt, fontsize); - constructor Create(x, y: real; Txt: string; fontsize: real := 12):= Invoke(CreatePXY, x, y, Txt, fontsize); -property Text: string read InvokeString(()->b.Text) write Invoke(procedure(t: string) -> b.Text := t, value); -property FontSize: real read InvokeReal(()->b.FontSize) write Invoke(procedure(t: real) -> b.FontSize := t, value); -end; - -IntegerBlockT = class(TextBlockT) -private - val := 0; - message: string; - procedure CreateP(message: string; fontSize: real := 12; initValue: integer := 0); - begin - inherited CreateP(message + ' ' + initValue, fontSize); - Self.message := message; - val := initValue; + SelectionChanged: procedure; + constructor Create(height: real := 150):= Invoke(CreateP, height); + constructor Create(x,y: real; width: real; height: real := 150):= Invoke(CreatePXY, x, y, width, height); + procedure Sort := Invoke(SortP); + procedure SortDescending := Invoke(SortPDescending); + procedure Add(s: string) := Invoke(AddP, s); + procedure AddRange(ss: sequence of string) := Invoke(AddRangeP, ss); + property Count: integer read InvokeInteger(()->lb.Items.Count); + property SelectedIndex: integer read InvokeInteger(()->lb.SelectedIndex) write Invoke(procedure(t: integer) -> lb.SelectedIndex := t, value); + property SelectedText: string read InvokeString(()->(lb.SelectedItem as ListBoxItem).Content.ToString) + write Invoke(procedure(t: string) -> (lb.SelectedItem as ListBoxItem).Content := t, value); end; -public - property Value: integer read val write begin val := value; Text := message + ' ' + val; end; - constructor Create(message: string; fontSize: real := 12; initValue: integer := 0):= Invoke(CreateP, message, fontSize, initValue); -end; - -RealBlockT = class(TextBlockT) -private - val := 0.0; - message: string; - procedure CreateP(message: string; fontSize: real := 12; initValue: real := 0); - begin - inherited CreateP(message + ' ' + initValue.ToString(FracDigits), fontSize); - Self.message := message; - val := initValue; - end; - -public - property Value: real read val write begin val := value; Text := message + ' ' + val.ToString(FracDigits); end; - constructor Create(message: string; fontSize: real := 12; initValue: real := 0):= Invoke(CreateP, message, fontSize, initValue); -auto property FracDigits: integer := 1; -end; - - ///!# -TextBoxT = class(CommonControl) -protected - function tb: GTextBox := element as GTextBox; - procedure BTextChanged(sender: Object; e: TextChangedEventArgs); - begin - if Click <> nil then - Click; - end; - - function GetText: string := InvokeString(()->tb.Text); - procedure SetTextP(t: string) := tb.Text := t; - procedure SetText(t: string) := Invoke(SetTextP, t); - procedure CreateP(Txt: string; w: real); - begin - element := new GTextBox; - element.HorizontalAlignment := HorizontalAlignment.Stretch; - element.Margin := new Thickness(0, 0, 0, GlobalHMargin); - Text := Txt; - if w > 0 then - Width := w; - tb.TextChanged += BTextChanged; - ActivePanel.Children.Add(tb); - end; - -public - event Click: procedure; - constructor Create(Txt: string := ''; w: real := 0); - begin - Invoke(CreateP, Txt, w); - end; - - property Text: string read GetText write SetText; - property FontSize: real read InvokeReal(()->tb.FontSize) write Invoke(procedure(t: real) -> tb.FontSize := t, value); -end; - -IntegerBoxT = class(TextBoxT) - function GetValue: integer; - begin - if Trim(Text) = '' then - Result := 0 - else Result := integer.Parse(Text); - end; - - procedure SetValue(x: integer) := Text := x.ToString; -public - constructor Create(w: real := 0); - begin - inherited Create('0', w); - var tb := element as GTextBox; - tb.MouseWheel += procedure (o, e) -> begin - if e.Delta > 0 then - SetValue(GetValue + 1) - else if e.Delta < 0 then - SetValue(GetValue - 1) + SliderWPF = class(CommonControlWPF) + private + function sl: Slider := element as Slider; + function GetMinimum: real := InvokeReal(()->sl.Minimum); + procedure SetMinimumP(r: real) := sl.Minimum := r; + procedure SetMinimum(r: real) := Invoke(SetMinimumP, r); + function GetMaximum: real := InvokeReal(()->sl.Maximum); + procedure SetMaximumP(r: real) := sl.Maximum := r; + procedure SetMaximum(r: real) := Invoke(SetMaximumP, r); + function GetValue: real := InvokeReal(()->sl.Value); + procedure SetValueP(r: real) := sl.Value := r; + procedure SetValue(r: real) := Invoke(SetValueP, r); + function GetFrequency: real := InvokeReal(()->sl.TickFrequency); + procedure SetFrequencyP(r: real) := sl.TickFrequency := r; + procedure SetFrequency(r: real) := Invoke(SetFrequencyP, r); + protected + procedure CreatePXY(x,y: real; min, max, val, freq: real; width: real); + begin + Init0(new Slider,width,x,y); + sl.ValueChanged += procedure(o, e) -> ValueChangedP; + sl.TickPlacement := System.Windows.Controls.Primitives.TickPlacement.BottomRight; + sl.Minimum := min; + sl.Maximum := max; + sl.Value := val; + if freq<=0 then + sl.TickFrequency := (max-min)/10 + else sl.TickFrequency := freq; + sl.Foreground := Brushes.Black; end; - tb.KeyDown += procedure (o, e) -> begin - if not ((e.Key >= Key.D0) and (e.Key <= Key.D9)) then - e.Handled := True; + procedure CreateP(min, max, val, freq: real) := CreatePXY(-1,-1,min, max, val, freq, 0); + + procedure ValueChangedP := if ValueChanged <> nil then ValueChanged; + public + ValueChanged: procedure; + constructor Create(min, max, val: real; freq: real := 0) := Invoke(CreateP, min, max, val, freq); + constructor Create(x,y: real; min, max, val: real; freq: real := 0; width: real := 0) := Invoke(CreatePXY, x,y,min, max, val, freq, width); + property Minimum: real read GetMinimum write SetMinimum; + property Maximum: real read GetMaximum write SetMaximum; + property Value: real read GetValue write SetValue; + property Frequency: real read GetFrequency write SetFrequency; + end; + + CheckBoxWPF = class(ClickableControlWPF) + private + property cb: CheckBox read element as CheckBox; + protected + procedure CreatePXY(x,y: real; text: string; width: real); + begin + Init0(new CheckBox,width,x,y); + cb.Content := text; + cb.Click += ClickP; end; - {tb.TextInput += procedure (o,e) -> begin - Print(e.Text); - if not ((e.Key>=Key.D0) and (e.Key<=Key.D9)) then - e.Handled := True; - end;} - end; - - property Value: integer read GetValue write SetValue; - property FontSize: real read InvokeReal(()->tb.FontSize) write Invoke(procedure(t: real) -> tb.FontSize := t, value); -end; - -TextBoxWithBlockT = class(CommonControl) -private - l: TextBlock; -protected - function tb: GTextBox := (element as StackPanel).Children[1] as GTextBox; - procedure BTextChanged(sender: Object; e: TextChangedEventArgs); - begin - if Click <> nil then - Click; - end; - - function GetText: string := InvokeString(()->tb.Text); - procedure SetTextP(t: string) := tb.Text := t; - procedure SetText(t: string) := Invoke(SetTextP, t); - procedure CreateP(BlockTxt, Txt: string; w: real); - begin - var sp := new StackPanel; - element := sp; - sp.Orientation := Orientation.Horizontal; - sp.HorizontalAlignment := HorizontalAlignment.Stretch; - l := new TextBlock(); - l.Text := BlockTxt; - sp.Children.Add(l); - var tb := new GTextBox; - tb.Width := 100; - tb.VerticalAlignment := VerticalAlignment.Stretch; - tb.Margin := new Thickness(0, 0, 0, GlobalHMargin); - sp.Children.Add(tb); - Text := Txt; - if w > 0 then - Width := w; - tb.TextChanged += BTextChanged; - ActivePanel.Children.Add(sp); + procedure CreateP(text: string) := CreatePXY(-1,-1,text,0); + public + constructor Create(text: string) := Invoke(CreateP, text); + constructor Create(x,y: real; text: string; width: real := 0) := Invoke(CreatePXY, x,y,text,width); + + property Text: string read InvokeString(()->cb.Content as string) write Invoke(procedure(t: string) -> cb.Content := t, value); + property IsChecked: boolean read InvokeBoolean(()->cb.IsChecked.Value) write Invoke(procedure(t: boolean) -> cb.IsChecked := t, value); end; -public - event Click: procedure; - constructor Create(BlockTxt: string; Txt: string := ''; w: real := 0); - begin - Invoke(CreateP, BlockTxt, Txt, w); + RadioButtonWPF = class(ClickableControlWPF) + private + property rb: RadioButton read element as RadioButton; + protected + procedure CreatePXY(x,y: real; text: string; width: real); + begin + Init0(new RadioButton,width,x,y); + rb.Content := text; + rb.Click += ClickP; + end; + procedure CreateP(text: string) := CreatePXY(-1,-1,text,0); + public + constructor Create(text: string) := Invoke(CreateP, text); + constructor Create(x,y: real; text: string; width: real := 0) := Invoke(CreatePXY, x,y,text,width); + + property Text: string read InvokeString(()->rb.Content as string) write Invoke(procedure(t: string) -> rb.Content := t, value); + property IsChecked: boolean read InvokeBoolean(()->rb.IsChecked.Value) write Invoke(procedure(t: boolean) -> rb.IsChecked := t, value); + end; + + StatusBarWPF = class(CommonControlWPF) + private + property sb: GStatusBar read element as GStatusBar; + procedure SetTextP(text: string) := (sb.Items[0] as StatusBarItem).Content := text; + procedure SetTextPI(i: integer; text: string) := (sb.Items[i] as StatusBarItem).Content := text; + protected + procedure CreateP(height: real; itemWidth: real); + begin + element := new GStatusBar; + element.Focusable := False; + element.Height := height; + DockPanel.SetDock(sb, Dock.Bottom); + MainDockPanel.children.Insert(0, sb); + + var sbi := new StatusBarItem(); + sbi.Content := ''; + if itemWidth > 0 then + sbi.Width := itemWidth; + sb.Items.Add(sbi); + + // последняя фиктивная панель - для заполнения + sbi := new StatusBarItem(); + sbi.Content := ''; + sb.Items.Add(sbi); + end; + procedure AddItemP(text: string; itemWidth: real); + begin + var sbi := new StatusBarItem(); + sbi.Content := text; + if itemWidth > 0 then + sbi.Width := itemWidth; + sb.Items.Insert(sb.Items.Count-1,sbi); + end; + public + constructor Create(height: real := 24; itemWidth: real := 0) := Invoke(CreateP,height,itemWidth); + procedure AddText(text: string; itemWidth: real := 0) := Invoke(AddItemP,text,itemWidth); + + property Text: string read InvokeString(()->(sb.Items[0] as StatusBarItem).Content as string) + write Invoke(SetTextP,value); + property ItemText[i: integer]: string read InvokeString(()->(sb.Items[0] as StatusBarItem).Content as string) + write Invoke(SetTextPI,i,value); end; - property Text: string read GetText write SetText; - property FontSize: real read InvokeReal(()->tb.FontSize) write Invoke(procedure(t: real) -> begin tb.FontSize := t; l.FontSize := t; end, value); -end; + {WebBrowserWPF = class(CommonControlWPF) + private + property wb: WebBrowser read element as WebBrowser; + procedure CreatePXY(x,y,w,h: real); + begin + element := new WebBrowser; + //element.Focusable := False; + //DockPanel.SetDock(wb, Dock.Bottom); + MainDockPanel.children.Insert(0, wb); - ///!# -ListBoxT = class(CommonControl) -protected - function tb: GListBox := element as GListBox; - procedure CreateP(w, h: real); - begin - element := new GListBox; - element.HorizontalAlignment := HorizontalAlignment.Stretch; - element.Margin := new Thickness(0, 0, 0, GlobalHMargin); - if w > 0 then - Width := w; - Height := h; - ActivePanel.Children.Add(tb); - end; - - procedure AddP(s: string); - begin - var lbi := new ListBoxItem(); - lbi.Content := s; - tb.Items.Add(lbi); - end; - - procedure SortP := tb.Items.SortDescriptions.Add(new SortDescription('Content', ListSortDirection.Ascending)); - procedure SortPDescending := tb.Items.SortDescriptions.Add(new SortDescription('Content', ListSortDirection.Descending)); -public - event Click: procedure; - constructor Create(w: real := 0; h: real := 200):= Invoke(CreateP, w, h); -procedure Sort := Invoke(SortP); - procedure SortDescending := Invoke(SortPDescending); - procedure Add(s: string) := Invoke(AddP, s); - property FontSize: real read InvokeReal(()->tb.FontSize) write Invoke(procedure(t: real) -> tb.FontSize := t, value); - property Count: integer read InvokeInteger(()->tb.Items.Count); - property SelectedIndex: integer read InvokeInteger(()->tb.SelectedIndex) write Invoke(procedure(t: integer) -> tb.SelectedIndex := t, value); - property SelectedText: string read InvokeString(()->tb.SelectedItem as string) write Invoke(procedure(t: string) -> tb.SelectedItem := t, value); -end; + //wb.Height := h; + wb.Navigate('http://yandex.ru'); + //wb.Source := new System.Uri('http://yandex.ru',System.UriKind.Absolute); + end; + public + constructor Create(x,y,w,h: real) := Invoke(CreatePXY,x,y,w,h); + end;} -SliderT = class(CommonControl) -private - function sl: Slider := element as Slider; - function GetMinimum: real := InvokeReal(()->sl.Minimum); - procedure SetMinimumP(r: real) := sl.Minimum := r; - procedure SetMinimum(r: real) := Invoke(SetMinimumP, r); - function GetMaximum: real := InvokeReal(()->sl.Maximum); - procedure SetMaximumP(r: real) := sl.Maximum := r; - procedure SetMaximum(r: real) := Invoke(SetMaximumP, r); - function GetValue: real := InvokeReal(()->sl.Value); - procedure SetValueP(r: real) := sl.Value := r; - procedure SetValue(r: real) := Invoke(SetValueP, r); - function GetFrequency: real := InvokeReal(()->sl.TickFrequency); - procedure SetFrequencyP(r: real) := sl.TickFrequency := r; - procedure SetFrequency(r: real) := Invoke(SetFrequencyP, r); -protected - procedure CreateP(min, max, val: real); - begin - element := new Slider; - sl.ValueChanged += procedure(o, e) -> ValueChangedP; - sl.TickPlacement := System.Windows.Controls.Primitives.TickPlacement.BottomRight; - sl.Minimum := min; - sl.Maximum := max; - sl.Value := val; - sl.Foreground := Brushes.Black; - ActivePanel.Children.Add(sl); - end; - - procedure ValueChangedP := if ValueChanged <> nil then ValueChanged; -public - ValueChanged: procedure; - constructor Create(min, max, val: real); - begin - Invoke(CreateP, min, max, val); - end; - - property Minimum: real read GetMinimum write SetMinimum; - property Maximum: real read GetMaximum write SetMaximum; - property Value: real read GetValue write SetValue; - property Frequency: real read GetFrequency write SetFrequency; -end; +{-----------------------------------------------------} +// Для каждого контрола - пара функций. +// Функция без координат и ширины рассчитана на создание внутри вертикальной StackPanel (LeftPanel, RightPanel) +// Panel - вспомогательная, нужна только для создания LeftPanel, RightPanel +function Button(Txt: string; fontSize: real := 12): ButtonWPF; +function Button(x, y: real; Txt: string; width: real := 0; fontSize: real := 12): ButtonWPF; + +function TextBlock(Txt: string; fontSize: real := 12): TextBlockWPF; +function TextBlock(x, y: real; Txt: string; width: real := 0; fontSize: real := 12): TextBlockWPF; + +function IntegerBlock(message: string; initValue: integer := 0; fontSize: real := 12): IntegerBlockWPF; +function IntegerBlock(x, y: real; message: string; width: real := 0; initValue: integer := 0; fontSize: real := 12): IntegerBlockWPF; + +function RealBlock(message: string; initValue: real := 0; fontSize: real := 12): RealBlockWPF; +function RealBlock(x, y: real; message: string; width: real := 0; initValue: real := 0; fontSize: real := 12): RealBlockWPF; + +function TextBox(text: string := ''): TextBoxWPF; +function TextBox(x, y: real; text: string := ''; width: real := 0): TextBoxWPF; + +function IntegerBox(max: integer := 10): IntegerBoxWPF; +function IntegerBox(min,max: integer): IntegerBoxWPF; +function IntegerBox(x, y: real; min,max: integer; width: real := 0): IntegerBoxWPF; + +function ListBox(height: real := 150): ListBoxWPF; +function ListBox(x,y: real; width: real; height: real := 150): ListBoxWPF; + +function Slider(): SliderWPF; +function Slider(min,max: real; val: real := real.MinValue; freq: real := 0): SliderWPF; +function Slider(x,y: real; min,max: real; width: real := 0; val: real := real.MinValue; freq: real := 0): SliderWPF; + +function LeftPanel(width: real := 150; c: Color := PanelsColor; InternalMargin: real := 10): PanelWPF; +function RightPanel(width: real := 150; c: Color := PanelsColor; InternalMargin: real := 10): PanelWPF; + +function StatusBar(height: real := 24; itemWidth: real := 0): StatusBarWPF; -function Button(Txt: string; fontSize: real := 12): ButtonT; -function Button(x, y: integer; Txt: string; fontSize: real := 12): ButtonT; -function TextBlock(Txt: string; fontSize: real := 12): TextBlockT; -function TextBlock(x, y: real; Txt: string; fontSize: real := 12): TextBlockT; -function IntegerBlock(message: string; fontSize: real := 12; initValue: integer := 0): IntegerBlockT; -function RealBlock(message: string; fontSize: real := 12; initValue: real := 0): RealBlockT; -function TextBox(Txt: string := ''; w: real := 0): TextBoxT; -function ListBox(w: real := 0; h: real := 200): ListBoxT; -function IntegerBox(w: real := 0): IntegerBoxT; -function Slider(min: real := 0; max: real := 10; val: real := 0): SliderT; procedure EmptyBlock(sz: integer := 16); +function Window: WindowTypeWPF; + implementation uses GraphWPF; @@ -386,57 +576,16 @@ uses System.Windows.Controls; uses System.Windows.Controls.Primitives; uses System.Windows.Media.Imaging; -var - StatusBarPanel: StatusBar; - LeftPanel, RightPanel, TopPanel, BottomPanel: Panel; - -procedure AddPanel(var pp: StackPanel; wh: real; d: Dock; c: Color; Margin: real := 10); -begin - if pp <> nil then - exit; - var bb := new Border(); - bb.Background := new SolidColorBrush(c); - var p := new StackPanel; - bb.Child := p; - //bb.Children.Add(p); - p.Margin := new System.Windows.Thickness(Margin); - if (d = Dock.Left) or (d = Dock.Right) then - begin - p.Orientation := Orientation.Vertical; - bb.Width := wh; - end - else - begin - p.Orientation := Orientation.Horizontal; - bb.Height := wh; - end; - p.Background := new SolidColorBrush(c); - DockPanel.SetDock(bb, d); - //MainDockPanel.children.Insert(MainDockPanel.children.Count-1,bb); - MainDockPanel.children.Insert(0, bb); - //MainDockPanel.children.Add(bb); - pp := p; - ActivePanel := p; -end; - -procedure AddRightPanel(Width: real; c: Color; Margin: real) := Invoke(AddPanel, RightPanel, Width, Dock.Right, c, Margin); - -procedure AddLeftPanel(Width: real; c: Color; Margin: real) := Invoke(AddPanel, LeftPanel, Width, Dock.Left, c, Margin); - -procedure AddTopPanel(Height: real; c: Color; Margin: real) := Invoke(AddPanel, TopPanel, Height, Dock.Top, c, Margin); - -procedure AddBottomPanel(Height: real; c: Color; Margin: real) := Invoke(AddPanel, BottomPanel, Height, Dock.Bottom, c, Margin); +function Window: WindowTypeWPF := GraphWPF.Window; procedure AddStatusBarP(Height: real); begin - if StatusBarPanel <> nil then - exit; - var sb := new StatusBar; - sb.Height := 24; + {var sb := new StatusBar; + sb.Height := Height; DockPanel.SetDock(sb, Dock.Bottom); // Всегда первая - MainDockPanel.children.Insert(0, sb); - StatusBarPanel := sb; + MainDockPanel.children.Insert(0, sb);} + //StatusBarPanel := sb; {var sbi := new StatusBarItem(); sbi.Content := 'sdghj'; sb.Items.Add(sbi); @@ -445,27 +594,47 @@ begin sb.Items.Add(sbi);} end; -procedure AddStatusBar(Height: real) := Invoke(AddStatusBarP, Height); +function Button(Txt: string; fontSize: real): ButtonWPF := ButtonWPF.Create(Txt,fontSize); +function Button(x, y: real; Txt: string; width: real; fontSize: real): ButtonWPF := ButtonWPF.Create(x, y, Txt, width, fontSize); -function Button(Txt: string; fontSize: real): ButtonT := ButtonT.Create(Txt,fontSize); +function TextBlock(Txt: string; fontSize: real): TextBlockWPF := TextBlockWPF.Create(Txt, fontSize); +function TextBlock(x, y: real; Txt: string; width: real; fontSize: real): TextBlockWPF := TextBlockWPF.Create(x, y, Txt, width, fontSize); -function Button(x, y: integer; Txt: string; fontSize: real): ButtonT := ButtonT.Create(x, y, Txt,fontSize); +function IntegerBlock(message: string; initValue: integer; fontSize: real): IntegerBlockWPF := IntegerBlockWPF.Create(message, initValue, fontSize); +function IntegerBlock(x, y: real; message: string; width: real; initValue: integer; fontSize: real): IntegerBlockWPF := IntegerBlockWPF.Create(x,y,message,width,initValue,fontSize); -function TextBlock(Txt: string; fontsize: real): TextBlockT := TextBlockT.Create(Txt, fontsize); +function RealBlock(message: string; initValue: real; fontSize: real): RealBlockWPF := RealBlockWPF.Create(message, initValue, fontSize); +function RealBlock(x, y: real; message: string; width: real; initValue: real; fontSize: real): RealBlockWPF := RealBlockWPF.Create(x,y,message,width,initValue,fontSize); -function TextBlock(x, y: real; Txt: string; fontsize: real): TextBlockT := TextBlockT.Create(x, y, Txt, fontsize); +function TextBox(text: string): TextBoxWPF := TextBoxWPF.Create(text); +function TextBox(x, y: real; text: string; width: real): TextBoxWPF := TextBoxWPF.Create(x,y,text,width); -function IntegerBlock(message: string; fontsize: real; initValue: integer): IntegerBlockT := IntegerBlockT.Create(message, fontsize, initValue); +function IntegerBox(max: integer): IntegerBoxWPF := IntegerBoxWPF.Create(0,max); +function IntegerBox(min,max: integer): IntegerBoxWPF := IntegerBoxWPF.Create(min,max); +function IntegerBox(x, y: real; min,max: integer; width: real) := IntegerBoxWPF.Create(x,y,min,max,width); -function RealBlock(message: string; fontsize: real; initValue: real): RealBlockT := RealBlockT.Create(message, fontsize, initValue); +function ListBox(height: real): ListBoxWPF := ListBoxWPF.Create(height); +function ListBox(x,y: real; width: real; height: real): ListBoxWPF := ListBoxWPF.Create(x,y,width,height); -function TextBox(Txt: string; w: real): TextBoxT := TextBoxT.Create(Txt, w); +function Slider: SliderWPF := SliderWPF.Create(0, 10, 0, 0); +function Slider(min, max, val, freq: real): SliderWPF; +begin + if val = real.MinValue then + val := min; + Result := SliderWPF.Create(min, max, val, freq); +end; +function Slider(x,y,min,max,width,val,freq: real): SliderWPF; +begin + if val = real.MinValue then + val := min; + Result := SliderWPF.Create(x, y, min, max, val, freq, width); +end; -function ListBox(w, h: real): ListBoxT := ListBoxT.Create(w, h); +function LeftPanel(width: real; c: Color; internalMargin: real) := new LeftPanelWPF(width,c,internalMargin); +function RightPanel(width: real; c: Color; internalMargin: real) := new RightPanelWPF(width,c,internalMargin); -function IntegerBox(w: real): IntegerBoxT := IntegerBoxT.Create(w); +function StatusBar(height: real; itemWidth: real): StatusBarWPF := new StatusBarWPF(height); -function Slider(min, max, val: real): SliderT := SliderT.Create(min, max, val); procedure EmptyBlock(sz: integer); begin @@ -476,7 +645,7 @@ end; procedure SetActivePanelInit; begin - ActivePanel := MainWindow.MainPanel.Children[0] as Panel + ActivePanel := MainWindow.MainPanel.Children[0] as GPanel end; begin diff --git a/bin/Lib/Graph3D.pas b/bin/Lib/Graph3D.pas index d5e028473..bc33b6b0a 100644 --- a/bin/Lib/Graph3D.pas +++ b/bin/Lib/Graph3D.pas @@ -3385,7 +3385,7 @@ function Pyramid(p: Point3D; Sides: integer; Height, Radius: real; m: Material): function PyramidWireFrame(x, y, z: real; Sides: integer; Height, Radius: real; Thickness: real; c: Color): PyramidTWireFrame := Inv(()->PyramidTWireFrame.Create(x, y, z, Sides, Radius, Height, thickness, c)); -function PyramidWireFrame(p: Point3D; Sides: integer; Height, Radius: real; Thickness: real; c: Color): PyramidTWireFrame := PyramidWireFrame(p.x, p.y, p.z, Sides, Radius, Height, thickness, c); +function PyramidWireFrame(p: Point3D; Sides: integer; Height, Radius: real; Thickness: real; c: Color): PyramidTWireFrame := PyramidWireFrame(p.x, p.y, p.z, Sides, Height, Radius, thickness, c); function Lego(x, y, z: real; Rows, Columns, Height: integer; m: Material): LegoT := Inv(()->LegoT.Create(x, y, z, Rows, Columns, Height, m)); diff --git a/bin/Lib/GraphWPF.pas b/bin/Lib/GraphWPF.pas index b050b74cb..251df112b 100644 --- a/bin/Lib/GraphWPF.pas +++ b/bin/Lib/GraphWPF.pas @@ -1931,6 +1931,7 @@ public begin host1 := new Canvas; host := new MyVisualHost(); + host1.ClipToBounds := True; host1.SizeChanged += (s,e) -> begin var sz := e.NewSize; diff --git a/bin/Lib/TwoPanelsWindow.pas b/bin/Lib/TwoPanelsWindow.pas new file mode 100644 index 000000000..186d9578e --- /dev/null +++ b/bin/Lib/TwoPanelsWindow.pas @@ -0,0 +1,109 @@ +unit TwoPanelsWindow; + +{$reference 'PresentationFramework.dll'} +{$reference 'WindowsBase.dll'} +{$reference 'PresentationCore.dll'} + +{$apptype windows} + +uses System.Windows.Controls; +uses System.Windows; +uses System.Windows.Data; +uses System.Reflection; +uses System.Collections.ObjectModel; + + +var app := new Application(); +var MainWindow := new Window; + +procedure InitWPF; +begin + MainWindow.Title := 'WPF'; + MainWindow.WindowStartupLocation := WindowStartupLocation.CenterScreen; + MainWindow.Width := 800; + MainWindow.Height := 600; + MainWindow.Show; +end; + +function GetProperties(t1: T): sequence of string; +begin + var props := t1.GetType.GetProperties; + Result := props.OrderBy(f->f.CustomAttributes.FirstOrDefault?.ToString ?? 'NoAttr').Select(f->f.Name); +end; + +var + LeftPanel: StackPanel; + RightPanel: DockPanel; + +procedure Init(); +begin + var dp := new DockPanel; + MainWindow.Content := dp; + + LeftPanel := new StackPanel(); + LeftPanel.Width := 150; + dp.Children.Add(LeftPanel); + + RightPanel := new DockPanel(); + dp.Children.Add(RightPanel); +end; + +type + ///!# + Button = class + private + btn := new System.Windows.Controls.Button; + procedure p; + begin + if Click<>nil then + Click; + end; + public + Click: procedure; + constructor (Content: string); + begin + LeftPanel.Children.Add(btn); + btn.HorizontalAlignment := HorizontalAlignment.Stretch; + btn.Margin := new Thickness(5); + btn.Content := Content; + btn.Click += procedure (sender: object; args: RoutedEventArgs) -> + begin + p; + end; + end; + end; + + ///!# + ListView = class + private + lv := new System.Windows.Controls.ListView; + public + constructor (); + begin + var gv := new GridView; + lv.View := gv; + RightPanel.Children.Add(lv); + end; + procedure Отобразить(data: sequence of T); + begin + var gv := lv.View as GridView; + var properties := GetProperties(data.First); + gv.Columns.Clear; + foreach var fld in properties do + begin + var col := new GridViewColumn; + col.Header := fld; + col.Width := 150; + col.DisplayMemberBinding := new Binding(fld); + gv.Columns.Add(col); + end; + lv.ItemsSource := data.Skip(1); + end; + end; + +initialization + InitWPF; + Init; +finalization + app.Run(); +end. \ No newline at end of file