diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 4ee87340f..e89249dd0 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 = "4"; public const string Build = "2"; - public const string Revision = "2026"; + public const string Revision = "2027"; 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 d7a8d7df4..68f3441ca 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%MINOR%=4 -%REVISION%=2026 %COREVERSION%=2 +%REVISION%=2027 +%MINOR%=4 %MAJOR%=3 diff --git a/Localization/StringResourcesLanguage.cs b/Localization/StringResourcesLanguage.cs index 732247b9d..44ad30ccf 100644 --- a/Localization/StringResourcesLanguage.cs +++ b/Localization/StringResourcesLanguage.cs @@ -53,21 +53,24 @@ namespace PascalABCCompiler string name = Path.Combine(di.FullName, ".LanguageName"); if (File.Exists(name)) { - StreamReader sr = new StreamReader(name, System.Text.Encoding.GetEncoding(1251)); - string lname = sr.ReadLine(); - string twoLetterISO = sr.ReadLine(); - string LCID = sr.ReadLine(); - if (!sr.EndOfStream && sr.ReadLine() == "default") - { - DefaultLanguage = lname; - DefaultTwoLetterISO = twoLetterISO; + using (StreamReader sr = new StreamReader(name, System.Text.Encoding.GetEncoding(1251))) + { + string lname = sr.ReadLine(); + string twoLetterISO = sr.ReadLine(); + string LCID = sr.ReadLine(); + if (lname == null || twoLetterISO == null || LCID == null) + continue; + if (!sr.EndOfStream && sr.ReadLine() == "default") + { + DefaultLanguage = lname; + DefaultTwoLetterISO = twoLetterISO; + } + AccessibleLanguagesHashtable.Add(lname, di.FullName+Path.DirectorySeparatorChar/*"\\"*/); + AccessibleTwoLetterISOHashtable.Add(lname, twoLetterISO); + AccessibleLCIDHashtable.Add(twoLetterISO, LCID); + accessibleLanguages.Add(lname); + twoLetterISOLanguages.Add(twoLetterISO); } - sr.Close(); - AccessibleLanguagesHashtable.Add(lname, di.FullName+Path.DirectorySeparatorChar/*"\\"*/); - AccessibleTwoLetterISOHashtable.Add(lname, twoLetterISO); - AccessibleLCIDHashtable.Add(twoLetterISO, LCID); - accessibleLanguages.Add(lname); - twoLetterISOLanguages.Add(twoLetterISO); } } /*StreamReader sr = new StreamReader(configFileName, System.Text.Encoding.GetEncoding(1251)); diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index fe8478f14..4b260692d 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.4.2.2026' +!define VERSION '3.4.2.2027' diff --git a/TestSuite/CompilationSamples/GraphWPF.pas b/TestSuite/CompilationSamples/GraphWPF.pas index 54ac66e24..8a99d0352 100644 --- a/TestSuite/CompilationSamples/GraphWPF.pas +++ b/TestSuite/CompilationSamples/GraphWPF.pas @@ -349,9 +349,9 @@ procedure Invoke(d: ()->()); //>> Процедуры покадровой анимации # GraphWPF FrameBasedAnimation functions // ----------------------------------------------------- /// Начинает анимацию, основанную на кадре. Перед рисованием каждого кадра содержимое окна стирается, затем вызывается процедура Draw -procedure BeginFrameBasedAnimation(Draw: procedure; frate: integer := 60); +procedure BeginFrameBasedAnimation(Draw: procedure; frate: integer := 61); /// Начинает анимацию, основанную на кадре Перед рисованием каждого кадра содержимое окна стирается, затем вызывается процедура Draw с параметром, равным номеру кадра -procedure BeginFrameBasedAnimation(Draw: procedure(frame: integer); frate: integer := 60); +procedure BeginFrameBasedAnimation(Draw: procedure(frame: integer); frate: integer := 61); /// Завершает анимацию, основанную на кадре procedure EndFrameBasedAnimation; @@ -1521,7 +1521,7 @@ procedure SystemOnResize(sender: Object; e: SizeChangedEventArgs) := var OnDraw: procedure := nil; var OnDraw1: procedure(frame: integer) := nil; -var FrameRate := 60; // кадров в секунду. Можно меньше! +var FrameRate := 61; // кадров в секунду. Можно меньше! var LastUpdatedTime := new System.TimeSpan(integer.MinValue); var FrameNum := 0; @@ -1566,7 +1566,7 @@ begin //CountVisuals := 0; OnDraw := nil; OnDraw1 := nil; - FrameRate := 60; + FrameRate := 61; end; var mre := new ManualResetEvent(false); diff --git a/TestSuite/CompilationSamples/WPFObjects.pas b/TestSuite/CompilationSamples/WPFObjects.pas index 134a8cb10..b6a590be1 100644 --- a/TestSuite/CompilationSamples/WPFObjects.pas +++ b/TestSuite/CompilationSamples/WPFObjects.pas @@ -52,6 +52,7 @@ type GBrush = System.Windows.Media.Brush; /// Тип стиля шрифта FontStyle = (Normal,Bold,Italic,BoldItalic); + Alignment = GraphWPF.Alignment; var host: Canvas; @@ -141,8 +142,8 @@ type // ----------------------------------------------------- //>> Класс ObjectWPF # Class ObjectWPF // ----------------------------------------------------- - /// Перечислимый тип выравнивания текста в свойстве Text или Number - Alignment = (LeftTop,CenterTop,RightTop,LeftCenter,Center,RightCenter,LeftBottom,CenterBottom,RightBottom); + // Перечислимый тип выравнивания текста в свойстве Text или Number + //Alignment = (LeftTop,CenterTop,RightTop,LeftCenter,Center,RightCenter,LeftBottom,CenterBottom,RightBottom); ///!# /// Базовый класс графических объектов ObjectWPF = class @@ -183,7 +184,7 @@ type /// Прямоугольник графического объекта property Bounds: GRect read Invoke&(()->begin Result := new GRect(transl.X,transl.Y,gr.Width,gr.Height); end); /// Текст внутри графического объекта - property Text: string read InvokeString(()->t.Text) write Invoke(procedure->t.Text := value); + property Text: string read InvokeString(()->t.Text) write Invoke(procedure->t.Text := value); virtual; /// Целое число, выводимое в центре графического объекта. Используется свойство Text property Number: integer read Text.ToInteger(0) write Text := Value.ToString; private @@ -200,7 +201,7 @@ type Alignment.RightTop,Alignment.RightCenter,Alignment.RightBottom: t.HorizontalAlignment := HorizontalAlignment.Right; end; end; - procedure AddChildP(ch: ObjectWPF); + procedure AddChildP(ch: ObjectWPF; al: Alignment); procedure DeleteChildP(ch: ObjectWPF); function GetInternalGeometry: Geometry; virtual := nil; public @@ -220,10 +221,10 @@ type write Invoke(procedure -> if value then ob.Visibility := Visibility.Visible else ob.Visibility := Visibility.Hidden); /// Выравнивание текста внутри графического объекта property TextAlignment: Alignment write Invoke(WTA,Value); - /// Размер текста внутри графического объекта - property FontSize: real read InvokeReal(()->t.FontSize) write Invoke(procedure->t.FontSize := value); + /// Размер шрифта текста внутри графического объекта + property FontSize: real read InvokeReal(()->t.FontSize) write Invoke(procedure->t.FontSize := value); virtual; /// Имя шрифта текста внутри графического объекта - property FontName: string write Invoke(procedure->t.FontFamily := new FontFamily(value)); + property FontName: string write Invoke(procedure->t.FontFamily := new FontFamily(value)); virtual; /// Цвет шрифта текста внутри графического объекта property FontColor: Color read Invoke&(()->(t.Foreground as SolidColorBrush).Color) @@ -318,7 +319,7 @@ type procedure AnimScale(a: real; sec: real := 1) := Invoke(AnimScaleP,a,sec); /// Добавляет к графическому объекту дочерний - procedure AddChild(ch: ObjectWPF); + procedure AddChild(ch: ObjectWPF; al: Alignment := Alignment.LeftTop); /// Удаляет из графического объекта дочерний procedure DeleteChild(ch: ObjectWPF); begin @@ -473,8 +474,7 @@ type function WithText(txt: string; size: real := 16; fontname: string := 'Arial'; c: GColor := Colors.Black): CircleWPF := inherited WithText(txt,size,fontname,c) as CircleWPF; /// Декоратор поворота объекта - function WithRotate(da: real): CircleWPF - := inherited WithRotate(da) as CircleWPF; + function WithRotate(da: real): CircleWPF := inherited WithRotate(da) as CircleWPF; end; // ----------------------------------------------------- @@ -502,8 +502,7 @@ type function WithText(txt: string; size: real := 16; fontname: string := 'Arial'; c: GColor := Colors.Black): RectangleWPF := inherited WithText(txt,size,fontname,c) as RectangleWPF; /// Декоратор поворота объекта - function WithRotate(da: real): RectangleWPF - := inherited WithRotate(da) as RectangleWPF; + function WithRotate(da: real): RectangleWPF := inherited WithRotate(da) as RectangleWPF; end; // ----------------------------------------------------- @@ -536,6 +535,7 @@ type // ----------------------------------------------------- /// Класс графических объектов "Прямоугольник со скругленными краями" RoundRectWPF = class(BoundedObjectWPF) + function Element := ob as System.Windows.Shapes.Rectangle; procedure InitOb2(x,y,w,h,r: real; c: GColor); begin var rr := new Rectangle(); @@ -543,7 +543,7 @@ type rr.RadiusY := r; InitOb1(x,y,w,h,c,rr); end; - function GetInternalGeometry: Geometry; override := (ob as Shape).RenderedGeometry; + function GetInternalGeometry: Geometry; override := Element.RenderedGeometry; public /// Создает прямоугольник со скругленными краями размера (w,h) с радиусом скругления r заданного цвета с координатами левого верхнего угла (x,y) constructor (x,y,w,h,r: real; c: GColor) := Invoke(InitOb2,x,y,w,h,r,c); @@ -557,14 +557,12 @@ type function WithText(txt: string; size: real := 16; fontname: string := 'Arial'; c: GColor := Colors.Black): RoundRectWPF := inherited WithText(txt,size,fontname,c) as RoundRectWPF; /// Декоратор поворота объекта - function WithRotate(da: real): RoundRectWPF - := inherited WithRotate(da) as RoundRectWPF; + function WithRotate(da: real): RoundRectWPF := inherited WithRotate(da) as RoundRectWPF; /// Радиус скругления property RoundRadius: real read InvokeReal(()->(ob as Rectangle).RadiusX) write begin - var ob1 := ob; - Invoke(procedure->begin var r := ob1 as Rectangle; r.RadiusX := value; r.Radiusy := value end); + Invoke(procedure->begin var r := Self.Element; r.RadiusX := value; r.Radiusy := value end); end; end; @@ -600,6 +598,75 @@ type := inherited WithRotate(da) as RoundSquareWPF; end; + MyText = class(FrameworkElement) + public + text: string; + sz: real; + ft: FormattedText; + name: string; + c: Color; + bc: Color := EmptyColor; + constructor (txt,name: string; sz: real; col: Color); + begin + text := txt; Self.sz := sz; Self.name := name; Self.c := col; + RecreateFormText; + end; + procedure RecreateFormText; + begin + ft := new FormattedText(text,new System.Globalization.CultureInfo('ru-ru'), + System.Windows.FlowDirection.LeftToRight, + new Typeface(name), sz, new SolidColorBrush(c)); + Width := ft.Width; + Height := ft.Height; + end; + procedure OnRender(dc: DrawingContext); override; + begin + if bc<>EmptyColor then + dc.DrawRectangle(new SolidColorBrush(bc),nil,Rect(0,0,Width,Height)); + dc.DrawText(ft,new Point(0,0)); + end; + end; + +// ----------------------------------------------------- +//>> Класс TextWPF # Class TextWPF +// ----------------------------------------------------- + /// Класс графических объектов "Текст" + TextWPF = class(ObjectWPF) + private + function Element := ob as MyText; + + procedure InitOb2(x,y: real; txt: string; c: GColor); + begin + var rr := new MyText(txt,'Arial',16,c); + InitOb(x,y,rr.Width,rr.Height,rr); + end; + function GetInternalGeometry: Geometry; override; + begin + var r := Rect(0,0,Width,Height); + Result := new RectangleGeometry(r); + end; + public + /// Создает прямоугольник размера (w,h) заданного цвета с координатами левого верхнего угла (x,y) + constructor (x,y: real; txt: string; c: GColor := Colors.Black) := Invoke(InitOb2,x,y,txt,c); + /// Размер шрифта + property FontSize: real read InvokeReal(()->Self.Element.sz) write + Invoke(procedure->begin Self.Element.sz := value; Self.Element.RecreateFormText; Width := Self.Element.Width; Height := Self.Element.Height; ob.InvalidateVisual; end); override; + /// Имя шрифта + property FontName: string read Element.name + write Invoke(procedure->begin Self.Element.name := value; Self.Element.RecreateFormText; Width := Self.Element.Width; Height := Self.Element.Height; ob.InvalidateVisual end); + /// Цвет шрифта + property Color: GColor read Invoke&(()->Element.C) + write Invoke(()->begin Self.Element.C := value; Self.Element.RecreateFormText; ob.InvalidateVisual end); override; + /// Цвет фона + property BackgroundColor: GColor read Invoke&(()->Element.bc) + write Invoke(()->begin Self.Element.bc := value; Self.Element.RecreateFormText; ob.InvalidateVisual end); + /// Текст графического объекта + property Text: string read InvokeString(()->Element.Text) + write Invoke(procedure->begin Self.Element.Text := value; Self.Element.RecreateFormText; ; Width := Self.Element.Width; Height := Self.Element.Height; ob.InvalidateVisual end); override; + /// Декоратор поворота объекта + function WithRotate(da: real): TextWPF := inherited WithRotate(da) as TextWPF; + end; + // ----------------------------------------------------- //>> Класс LineWPF # Class LineWPF // ----------------------------------------------------- @@ -790,6 +857,7 @@ type StarWPF = class(RegularPolygonWPF) private rint: real; + function Element := ob as System.Windows.Shapes.Polygon; procedure InitOb2(x,y,r,rint: real; n: integer; c: GColor); begin InitOb1(x-r,y-r,2*r,2*r,c,CreatePolygon(r,rint,n),false); @@ -890,6 +958,7 @@ type Result := (ob as System.Windows.Shapes.Polygon).Points.Select(p->p).ToArray; end; public + function Element := ob as System.Windows.Shapes.Polygon; /// Создает многоугольник заданного цвета с координатами вершин, заданными массивом точек pp constructor (pp: array of Point; c: GColor) := Invoke(InitOb2,pp,c); /// Массив вершин @@ -947,15 +1016,15 @@ type procedure InitOb2(x,y: real; fname: string); begin var b := CreateBitmapImage(fname); - Rest(x,y,b.Width,b.Height,b); + Rest(x,y,b.PixelWidth,b.PixelHeight,b); end; function GetInternalGeometry: Geometry; override; begin var r := Rect(0,0,Width,Height); - Println(r); 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) @@ -968,8 +1037,7 @@ type function WithText(txt: string; size: real := 16; fontname: string := 'Arial'; c: GColor := Colors.Black): PictureWPF := inherited WithText(txt,size,fontname,c) as PictureWPF; /// Декоратор поворота объекта - function WithRotate(da: real): PictureWPF - := inherited WithRotate(da) as PictureWPF; + function WithRotate(da: real): PictureWPF := inherited WithRotate(da) as PictureWPF; end; // ----------------------------------------------------- @@ -1023,8 +1091,13 @@ procedure __InitModule__; procedure __FinalizeModule__; //{{{--doc: Конец секции 2 }}} +procedure BeginFrameBasedAnimation(Draw: procedure; frate: integer := 61); + implementation +procedure BeginFrameBasedAnimation(Draw: procedure; frate: integer) := GraphWPF.BeginFrameBasedAnimation(Draw,frate); + + 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 RandomColor := RGB(PABCSystem.Random(256), PABCSystem.Random(256), PABCSystem.Random(256)); @@ -1082,11 +1155,11 @@ begin host.Children.Add(ob.can) end; -procedure ObjectWPF.AddChild(ch: ObjectWPF); +procedure ObjectWPF.AddChild(ch: ObjectWPF; al: Alignment); begin if not Objects.l.Contains(ch) then raise new Exception('Добавляемый объект уже является дочерним'); - Invoke(AddChildP,ch); + Invoke(AddChildP,ch,al); end; function ObjectWPF.Intersects(ob: ObjectWPF): boolean; @@ -1094,7 +1167,6 @@ begin Result := ObjectsIntersect(Self,ob); end; - procedure ObjectWPF.InitOb(x,y,w,h: real; o: FrameworkElement; SetWH: boolean); begin can := new Canvas; @@ -1118,6 +1190,7 @@ begin (gr.Width,gr.Height) := (w,h); t := new TextBlock(); + t.FontFamily := new FontFamily('Arial'); t.VerticalAlignment := VerticalAlignment.Center; t.HorizontalAlignment := HorizontalAlignment.Center; @@ -1130,8 +1203,17 @@ begin FontSize := 16; end; -procedure ObjectWPF.AddChildP(ch: ObjectWPF); +procedure ObjectWPF.AddChildP(ch: ObjectWPF; al: Alignment); begin + if (al=Alignment.RightTop) or (al=Alignment.RightCenter) or (al=Alignment.RightBottom) then + ch.Left := Width-ch.Width + else if (al=Alignment.CenterTop) or (al=Alignment.Center) or (al=Alignment.CenterBottom) then + ch.Left := (Width-ch.Width)/2; + if (al=Alignment.RightBottom) or (al=Alignment.CenterBottom) or (al=Alignment.LeftBottom) then + ch.Top := Height-ch.Height + else if (al=Alignment.RightCenter) or (al=Alignment.Center) or (al=Alignment.LeftCenter) then + ch.Top := (Height-ch.Height)/2; + ChildrenWPF.Add(ch); Objects.Destroy(ch); can.Children.Add(ch.can); diff --git a/VisualPascalABCNET/Form1.cs b/VisualPascalABCNET/Form1.cs index b3e005d2b..8819b5f58 100644 --- a/VisualPascalABCNET/Form1.cs +++ b/VisualPascalABCNET/Form1.cs @@ -220,7 +220,9 @@ namespace VisualPascalABC DesignerUseable = false; //DebuggerVisible = false; } - PascalABCCompiler.StringResourcesLanguage.LoadDefaultConfig(); + + PascalABCCompiler.StringResourcesLanguage.LoadDefaultConfig(); + //if (PascalABCCompiler.StringResourcesLanguage.AccessibleLanguages.Count > 0) // PascalABCCompiler.StringResourcesLanguage.CurrentLanguageName = PascalABCCompiler.StringResourcesLanguage.AccessibleLanguages[0];