Pārlūkot izejas kodu

script tool option (partially done)

johann 5 gadi atpakaļ
vecāks
revīzija
ab022e284d

+ 1 - 1
lazpaint/lazpaintinstance.pas

@@ -318,7 +318,7 @@ begin
   FImage := TLazPaintImage.Create;
   FImage.OnStackChanged:= @OnStackChanged;
   FImage.OnException := @OnFunctionException;
-  FToolManager := TToolManager.Create(FImage, self, nil, BlackAndWhite);
+  FToolManager := TToolManager.Create(FImage, self, nil, BlackAndWhite, FScriptContext);
   UseConfig(TIniFile.Create(''));
   FToolManager.OnPopup := @OnToolPopup;
   FToolManager.OnColorChanged:=@ToolColorChanged;

+ 10 - 10
lazpaint/lazpaintmainform.pas

@@ -21,9 +21,6 @@ uses
 
   laztablet, udarktheme, UScriptType;
 
-const
-  MinPenWidthValue = 10;
-
 type
   { TFMain }
 
@@ -699,6 +696,7 @@ type
     procedure ManagerTextureChanged(Sender: TObject);
     procedure ManagerShapeOptionChanged(Sender: TObject);
     procedure ManagerToleranceChanged(Sender: TObject);
+    procedure ManagerToolbarChanged(Sender: TObject);
   private
     { private declarations }
     FLayout: TMainFormLayout;
@@ -1007,6 +1005,7 @@ begin
   If Assigned(ToolManager) then
   begin
     if ToolManager.OnToolChanged = @ManagerToolChanged then ToolManager.OnToolChanged := nil;
+    if ToolManager.OnToolbarChanged = @ManagerToolbarChanged then ToolManager.OnToolbarChanged := nil;
     if ToolManager.OnTextureChanged = @ManagerTextureChanged then ToolManager.OnTextureChanged := nil;
     if ToolManager.OnEraserChanged = @ManagerEraserChanged then ToolManager.OnEraserChanged := nil;
     if ToolManager.OnPenWidthChanged = @ManagerPenWidthChanged then ToolManager.OnPenWidthChanged := nil;
@@ -1088,6 +1087,7 @@ begin
 
   ToolManager.SetCurrentToolType(ptHand);
   ToolManager.OnToolChanged  :=  @ManagerToolChanged;
+  ToolManager.OnToolbarChanged:=@ManagerToolbarChanged;
   ToolManager.OnTextureChanged := @ManagerTextureChanged;
   ToolManager.OnEraserChanged:=@ManagerEraserChanged;
   ToolManager.OnPenWidthChanged:= @ManagerPenWidthChanged;
@@ -1158,7 +1158,7 @@ begin
   LazPaintInstance.ShowTopmost(FTopMostInfo);
   if Position = poDefault then LazPaintInstance.RestoreMainWindowPosition;
 
-  FLayout.Arrange;
+  ToolManager.UpdateContextualToolbars;
   UpdateToolImage;
   UpdateToolBar;
   shouldArrangeOnResize := true;
@@ -2729,8 +2729,6 @@ procedure TFMain.ToolNoTextureExecute(Sender: TObject);
 begin
   try
     ToolManager.SetTexture(nil);
-    UpdateEditPicture;
-
   except
     on ex:Exception do
       LazPaintInstance.ShowError(RemoveTrail(ToolNoTexture.Hint),ex.Message);
@@ -3862,7 +3860,6 @@ begin
         newTex.FreeReference;
         newTex := nil;
         result := true;
-        UpdateEditPicture;
         Config.SetDefaultTextureDirectory(ExtractFilePath(texFilename));
       except
         on ex:Exception do
@@ -3980,11 +3977,9 @@ procedure TFMain.ManagerToolChanged(sender: TToolManager; ANewTool: TPaintToolTy
 begin
   if self.Visible then
   begin
-    FLayout.Arrange;
     PaintBox_PenPreview.Invalidate;
     Image.OnImageChanged.NotifyObservers;
     UpdateToolImage;
-    UpdateToolBar;
     UpdatePenWidthToolbar;
     UpdateCurveModeToolbar;
   end;
@@ -4367,7 +4362,7 @@ end;
 procedure TFMain.ManagerShapeOptionChanged(Sender: TObject);
 begin
   UpdateToolOptions;
-  FLayout.Arrange;
+  ToolManager.UpdateContextualToolbars;
 end;
 
 procedure TFMain.ManagerToleranceChanged(Sender: TObject);
@@ -4375,6 +4370,11 @@ begin
   UpdateToleranceToolbar;
 end;
 
+procedure TFMain.ManagerToolbarChanged(Sender: TObject);
+begin
+  if Assigned(FLayout) then FLayout.Arrange;
+end;
+
 procedure TFMain.UpdateStatusText;
 var s: string;
 begin

+ 29 - 55
lazpaint/maintoolbar.inc

@@ -101,7 +101,7 @@ begin
   SpinEdit_Tolerance.OnChange := @SpinEdit_ToleranceChange;
 
   SpinEdit_PenWidth.MinValue := 1;
-  SpinEdit_PenWidth.MaxValue := 9999;
+  SpinEdit_PenWidth.MaxValue := round(MaxPenWidth*10);
   SpinEdit_PenWidth.Increment := 10;
   SpinEdit_PenWidth.OnChange := @SpinEdit_PenWidthChange;
   SpinEdit_PenWidth.OnMouseMove := @SpinEdit_PenWidthMouseMove;
@@ -182,7 +182,7 @@ begin
   SpinEdit_ShapeAltitude.OnChange := @SpinEdit_ShapeAltitudeChange;
 
   SpinEdit_BrushSpacing.MinValue := 1;
-  SpinEdit_BrushSpacing.MaxValue := 99;
+  SpinEdit_BrushSpacing.MaxValue := MaxBrushSpacing;
   SpinEdit_BrushSpacing.Value := 1;
   SpinEdit_BrushSpacing.Increment := 1;
   SpinEdit_BrushSpacing.OnChange := @SpinEdit_BrushSpacingChange;
@@ -395,7 +395,8 @@ end;
 
 procedure TFMain.UpdateTextFontToolbar;
 begin
-  SpinEdit_TextSize.Value := ToolManager.TextFontSize;
+  if FInTextFont then exit;
+  SpinEdit_TextSize.Value := round(ToolManager.TextFontSize);
   UpdateTextSizeIncrement;
 end;
 
@@ -549,9 +550,16 @@ begin
 end;
 
 procedure TFMain.UpdateLineCapBar;
+var
+  newVisible: Boolean;
 begin
-  Panel_LineCap.Visible := Panel_CloseShape.Visible and not (toCloseShape in ToolManager.ShapeOptions) and
+  newVisible := Panel_CloseShape.Visible and not (toCloseShape in ToolManager.ShapeOptions) and
     (toDrawShape in ToolManager.ShapeOptions);
+  if newVisible <> Panel_LineCap.Visible then
+  begin
+    Panel_LineCap.Visible := newVisible;
+    if Assigned(FLayout) then FLayout.Arrange;
+  end;
 end;
 
 procedure TFMain.UpdateToolImage(AForceUpdate: boolean);
@@ -683,11 +691,12 @@ procedure TFMain.SpinEdit_TextSizeChange(Sender: TObject; AByUser: boolean);
 begin
   if AByUser and initialized and not FInTextFont then
   begin
-    if ToolManager.TextFontSize = SpinEdit_TextSize.Value then exit;
+    if round(ToolManager.TextFontSize) = SpinEdit_TextSize.Value then exit;
+    FInTextFont:= true;
     ToolManager.SetTextFont(ToolManager.TextFontName,
       SpinEdit_TextSize.Value, ToolManager.TextFontStyle);
     UpdateTextSizeIncrement;
-    UpdateEditPicture(True);
+    FInTextFont:= false;
     FActiveSpinEdit := SpinEdit_TextSize;
   end;
 end;
@@ -720,8 +729,7 @@ procedure TFMain.GridNb_SpinEditChange(Sender: TObject; AByUser: boolean);
 begin
   if not AByUser or not initialized then exit;
   FInGridNb := true;
-  if ToolManager.SetDeformationGridSize(Size(SpinEdit_GridNbX.Value+1,SpinEdit_GridNbY.Value+1)) then
-    image.OnImageChanged.NotifyObservers;
+  ToolManager.SetDeformationGridSize(Size(SpinEdit_GridNbX.Value+1,SpinEdit_GridNbY.Value+1));
   FInGridNb := false;
 end;
 
@@ -744,13 +752,7 @@ end;
 procedure TFMain.SpinEdit_TextOutlineWidthChange(Sender: TObject; AByUser: boolean);
 begin
   if AByUser and initialized then
-  begin
-     if ToolManager.TextOutlineWidth <> SpinEdit_TextOutlineWidth.Value/PenWidthFactor then
-     begin
-       ToolManager.SetTextOutline(ToolManager.TextOutline, SpinEdit_TextOutlineWidth.Value/PenWidthFactor);
-       UpdateEditPicture;
-     end;
-  end;
+    ToolManager.SetTextOutline(ToolManager.TextOutline, SpinEdit_TextOutlineWidth.Value/PenWidthFactor);
 end;
 
 procedure TFMain.SpinEdit_TextShadowXChange(Sender: TObject; AByUser: boolean);
@@ -858,11 +860,7 @@ procedure TFMain.ShowColorDialogForBack;
 begin
   ColorDialog1.Color := BGRAToColor(ToolManager.BackColor);
   if ColorDialog1.Execute then
-  begin
     ToolManager.BackColor := ColorToBGRA(ColorDialog1.Color,ToolManager.BackColor.alpha);
-    LazPaintInstance.ColorToFChooseColor;
-    UpdateEditPicture;
-  end;
 end;
 
 procedure TFMain.SpinEdit_BackOpacityChange(Sender: TObject; AByUser: boolean);
@@ -872,8 +870,6 @@ begin
     if ToolManager.BackColor.alpha = SpinEdit_BackOpacity.value then exit;
     with ToolManager.BackColor do
       ToolManager.BackColor := BGRA(red,green,blue,SpinEdit_BackOpacity.value);
-    LazPaintInstance.ColorToFChooseColor;
-    UpdateEditPicture;
   end;
 end;
 
@@ -908,7 +904,6 @@ begin
       ToolManager.ShapeOptions := ToolManager.ShapeOptions + [toAliasing]
     else
       ToolManager.ShapeOptions := ToolManager.ShapeOptions - [toAliasing];
-    UpdateEditPicture;
   end;
 end;
 
@@ -924,9 +919,7 @@ begin
      if Tool_DrawShapeBorder.Down then include(opt, toDrawShape) else exclude(opt, toDrawShape);
      if Tool_FillShape.Down then include(opt, toFillShape) else exclude(opt, toFillShape);
      ToolManager.ShapeOptions := opt;
-     ToolManager.UpdateContextualToolbars;
      FLayout.Arrange;
-     UpdateEditPicture;
   end;
 end;
 
@@ -942,9 +935,6 @@ begin
      if Tool_DrawShapeBorder.Down then include(opt, toDrawShape) else exclude(opt, toDrawShape);
      if Tool_FillShape.Down then include(opt, toFillShape) else exclude(opt, toFillShape);
      ToolManager.ShapeOptions := opt;
-     ToolManager.UpdateContextualToolbars;
-     FLayout.Arrange;
-     UpdateEditPicture;
   end;
 end;
 
@@ -958,8 +948,6 @@ begin
           ToolManager.ShapeOptions := ToolManager.ShapeOptions + [toCloseShape]
         else
           ToolManager.ShapeOptions := ToolManager.ShapeOptions - [toCloseShape];
-       FLayout.Arrange;
-       UpdateEditPicture;
      end;
   end;
 end;
@@ -1069,10 +1057,7 @@ begin
   begin
     newPS := TPenStyle(cb.ItemIndex);
     if newPS <> ToolManager.PenStyle then
-    begin
       ToolManager.PenStyle := newPS;
-      UpdateEditPicture;
-    end;
   end;
 end;
 
@@ -1130,28 +1115,19 @@ end;
 procedure TFMain.Tool_JoinBevelClick(Sender: TObject);
 begin
   if Tool_JoinBevel.Down then
-  begin
     ToolManager.JoinStyle := pjsBevel;
-    UpdateEditPicture;
-  end;
 end;
 
 procedure TFMain.Tool_JoinRoundClick(Sender: TObject);
 begin
   if Tool_JoinRound.Down then
-  begin
     ToolManager.JoinStyle := pjsRound;
-    UpdateEditPicture;
-  end;
 end;
 
 procedure TFMain.Tool_JoinMiterClick(Sender: TObject);
 begin
   if Tool_JoinMiter.Down then
-  begin
     ToolManager.JoinStyle := pjsMiter;
-    UpdateEditPicture;
-  end;
 end;
 
 procedure TFMain.SpinEdit_EraserChange(Sender: TObject; AByUser: boolean);
@@ -1338,29 +1314,31 @@ begin
 end;
 
 procedure TFMain.UpdatePenWidthFromSpinEdit;
+var
+  newWidth: single;
 begin
-  if round(ToolManager.PenWidth*PenWidthFactor) = max(SpinEdit_PenWidth.Value,MinPenWidthValue) then exit;
+  newWidth := max(SpinEdit_PenWidth.Value/PenWidthFactor, MinPenWidth);
+  if newWidth = ToolManager.PenWidth then exit;
   FInPenWidthChange:= true;
-  ToolManager.PenWidth := max(SpinEdit_PenWidth.Value,MinPenWidthValue)/PenWidthFactor;
+  ToolManager.PenWidth := newWidth;
   ShowPenPreview(True);
-  UpdateEditPicture;
   FInPenWidthChange:= false;
 end;
 
 procedure TFMain.SpinEdit_PenWidthExit(Sender: TObject);
 begin
-  if SpinEdit_PenWidth.Value < MinPenWidthValue then SpinEdit_PenWidth.Value := MinPenWidthValue;
+  if SpinEdit_PenWidth.Value < MinPenWidth*PenWidthFactor then SpinEdit_PenWidth.Value := MinPenWidth*PenWidthFactor;
 end;
 
 procedure TFMain.IncreasePenSize;
 begin
-  SpinEdit_PenWidth.Value := max(SpinEdit_PenWidth.Value+PenSizeDelta(1),MinPenWidthValue);
+  SpinEdit_PenWidth.Value := max(SpinEdit_PenWidth.Value+PenSizeDelta(1),MinPenWidth*PenWidthFactor);
   UpdatePenWidthFromSpinEdit;
 end;
 
 procedure TFMain.DecreasePenSize;
 begin
-  SpinEdit_PenWidth.Value := max(SpinEdit_PenWidth.Value-PenSizeDelta(-1),MinPenWidthValue);
+  SpinEdit_PenWidth.Value := max(SpinEdit_PenWidth.Value-PenSizeDelta(-1),MinPenWidth*PenWidthFactor);
   UpdatePenWidthFromSpinEdit;
 end;
 
@@ -1602,7 +1580,9 @@ procedure TFMain.Tool_TextFontClick(Sender: TObject);
 var topmostInfo: TTopMostInfo;
 begin
   FInTextFont := true;
-  FontDialog1.Font.Assign(ToolManager.GetTextFont);
+  FontDialog1.Font.Name := ToolManager.TextFontName;
+  FontDialog1.Font.Size := round(ToolManager.TextFontSize);
+  FontDialog1.Font.Style := ToolManager.TextFontStyle;
   FontDialog1.Font.Color := BGRAToColor(ToolManager.ForeColor);
   topmostInfo := LazPaintInstance.HideTopmost;
   if FontDialog1.Execute then
@@ -1661,13 +1641,7 @@ end;
 procedure TFMain.Tool_TextOutlineClick(Sender: TObject);
 begin
   if initialized then
-  begin
-     if ToolManager.TextOutline <> Tool_TextOutline.Down then
-     begin
-       ToolManager.SetTextOutline(Tool_TextOutline.Down, ToolManager.TextOutlineWidth);
-       UpdateEditPicture;
-     end;
-  end;
+    ToolManager.SetTextOutline(Tool_TextOutline.Down, ToolManager.TextOutlineWidth);
 end;
 
 procedure TFMain.ComboBox_BrushSelectDrawItem(Control: TWinControl;

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 527 - 67
lazpaint/tools/utool.pas


+ 15 - 9
lazpaint/tools/utooldeformationgrid.pas

@@ -30,12 +30,12 @@ type
     function DoToolMove({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; ptF: TPointF): Trect;
       override;
     function GetIsSelectingTool: boolean; override;
+    function DoToolUpdate(toolDest: TBGRABitmap): TRect; override;
   public
     function ToolKeyDown(var key: Word): TRect; override;
     function ToolUp: TRect; override;
     function GetContextualToolbars: TContextualToolbars; override;
     function Render(VirtualScreen: TBGRABitmap; {%H-}VirtualScreenWidth, {%H-}VirtualScreenHeight: integer; BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect; override;
-    procedure AfterGridSizeChange({%H-}NewNbX,{%H-}NewNbY: Integer); override;
     function ToolCommand(ACommand: TToolCommand): boolean; override;
     function ToolProvideCommand(ACommand: TToolCommand): boolean; override;
     destructor Destroy; override;
@@ -837,14 +837,6 @@ begin
   result := true;
 end;
 
-procedure TToolDeformationGrid.AfterGridSizeChange(NewNbX,NewNbY: Integer);
-begin
-  ReleaseGrid;
-  DeformationGrid := nil;
-  DeformationGridTexCoord := nil;
-  //grid will be created when needed
-end;
-
 function TToolDeformationGrid.ToolCommand(ACommand: TToolCommand): boolean;
 begin
   case ACommand of
@@ -1059,6 +1051,20 @@ begin
   Result:= false;
 end;
 
+function TToolDeformationGrid.DoToolUpdate(toolDest: TBGRABitmap): TRect;
+begin
+  if (deformationGridNbX <> Manager.DeformationGridNbX) or
+     (deformationGridNbY <> Manager.DeformationGridNbY) then
+  begin
+    ReleaseGrid;
+    DeformationGrid := nil;
+    DeformationGridTexCoord := nil;
+    Result:= OnlyRenderChange;
+  end
+  else
+    result := EmptyRect;
+end;
+
 function TToolDeformationGrid.Render(VirtualScreen: TBGRABitmap;
   VirtualScreenWidth, VirtualScreenHeight: integer; BitmapToVirtualScreen: TBitmapToVirtualScreenFunction): TRect;
 var curPt,rightPt,downPt: TPointF;

+ 10 - 11
lazpaint/uconfig.pas

@@ -211,7 +211,7 @@ type
     function DefaultToolTextShadow: boolean;
     procedure SetDefaultToolTextShadow(value: boolean);
     function DefaultToolTextFont: TFont;
-    procedure SetDefaultToolTextFont(AFont: TFont);
+    procedure SetDefaultToolTextFont(AName: string; ASize: single; AStyle: TFontStyles);
     function DefaultToolTextBlur: single;
     procedure SetDefaultToolTextBlur(value: single);
     function DefaultToolTextShadowOffsetX: integer;
@@ -893,17 +893,16 @@ begin
   result := tempFont;
 end;
 
-procedure TLazPaintConfig.SetDefaultToolTextFont(AFont: TFont);
+procedure TLazPaintConfig.SetDefaultToolTextFont(AName: string; ASize: single;
+  AStyle: TFontStyles);
 begin
-  tempFont.Assign(AFont);
-
-  iniOptions.WriteString('Tool','TextFontName',tempFont.Name);
-  iniOptions.WriteInteger('Tool','TextFontHeight',tempFont.Height);
-  iniOptions.WriteInteger('Tool','TextFontSize',tempFont.Size);
-  iniOptions.WriteBool('Tool','TextFontBold',fsBold in tempFont.Style);
-  iniOptions.WriteBool('Tool','TextFontItalic',fsItalic in tempFont.Style);
-  iniOptions.WriteBool('Tool','TextFontStrikeOut',fsStrikeOut in tempFont.Style);
-  iniOptions.WriteBool('Tool','TextFontUnderline',fsUnderline in tempFont.Style);
+  iniOptions.WriteString('Tool','TextFontName',AName);
+  iniOptions.WriteInteger('Tool','TextFontSize',round(ASize));
+  iniOptions.DeleteKey('Tool','TextFontHeight');
+  iniOptions.WriteBool('Tool','TextFontBold',fsBold in AStyle);
+  iniOptions.WriteBool('Tool','TextFontItalic',fsItalic in AStyle);
+  iniOptions.WriteBool('Tool','TextFontStrikeOut',fsStrikeOut in AStyle);
+  iniOptions.WriteBool('Tool','TextFontUnderline',fsUnderline in AStyle);
 end;
 
 function TLazPaintConfig.DefaultToolTextBlur: single;

+ 0 - 2
lazpaint/upalettetoolbar.pas

@@ -636,8 +636,6 @@ begin
       LazPaintInstance.ToolManager.BackColor := c;
     end else
         exit;
-    LazPaintInstance.UpdateToolbar;
-    LazPaintInstance.UpdateEditPicture(False);
   end;
 end;
 

+ 55 - 12
lazpaint/uscripttype.pas

@@ -31,10 +31,10 @@ type
   TInterpretationError = (ieTooManyClosingBrackets, ieEndingQuoteNotFound, ieOpeningBracketNotFound, ieClosingBracketNotFound,
                           ieConstantExpressionExpected, ieUnexpectedChar, ieInvalidNumber, ieInvalidColor, ieInvalidBoolean,
                           ieDuplicateIdentifier, ieUnexpectedOpeningBracketKind, ieUnexpectedClosingBracketKind,
-                          ieUnknownListType, ieMissingValue);
+                          ieUnknownListType, ieMissingValue, ieTooManyValues);
   TInterpretationErrors = set of TInterpretationError;
-  TScriptVariableType = (svtUndefined, svtFloat, svtInteger, svtBoolean, svtString, svtPixel, svtSubset,
-                         svtFloatList, svtIntList, svtBoolList, svtStrList, svtPixList);
+  TScriptVariableType = (svtUndefined, svtFloat, svtInteger, svtPoint, svtBoolean, svtString, svtPixel, svtSubset,
+                         svtFloatList, svtIntList, svtPointList, svtBoolList, svtStrList, svtPixList);
   TScriptFunctionExceptionHandler = procedure(AFunctionName: string; AException: Exception) of object;
 
   TParsedLitteral = record
@@ -44,6 +44,7 @@ type
     valueBool: boolean;
     valueStr: string;
     valuePixel: TBGRAPixel;
+    valuePoint: TPoint3D;
   end;
 
   TScalarVariable = record
@@ -51,6 +52,7 @@ type
     varType: TScriptVariableType;
     case TScriptVariableType of
       svtFloat: (valueFloat: double);
+      svtPoint: (valuePoint: TPoint3D);
       svtInteger: (valueInt: TScriptInteger);
       svtBoolean: (valueBool: boolean);
       svtPixel: (valuePix: TBGRAPixel);
@@ -58,15 +60,15 @@ type
   end;
 
 const
-  ScriptVariableListTypes : set of TScriptVariableType = [svtFloatList, svtIntList, svtBoolList, svtStrList, svtPixList];
-  ScriptScalarListTypes : set of TScriptVariableType = [svtFloatList, svtIntList, svtPixList];
-  ScriptScalarTypes : set of TScriptVariableType = [svtFloat, svtInteger, svtBoolean, svtPixel];
+  ScriptVariableListTypes : set of TScriptVariableType = [svtFloatList, svtIntList, svtPointList, svtBoolList, svtStrList, svtPixList];
+  ScriptScalarListTypes : set of TScriptVariableType = [svtFloatList, svtIntList, svtPointList, svtPixList];
+  ScriptScalarTypes : set of TScriptVariableType = [svtFloat, svtInteger, svtPoint, svtBoolean, svtPixel];
   ScalarListElementSize : array[svtFloatList..svtPixList] of NativeInt =
-    (sizeof(double), sizeof(TScriptInteger), 0, 0, sizeof(TBGRAPixel));
+    (sizeof(double), sizeof(TScriptInteger), sizeof(TPoint3D), 0, 0, sizeof(TBGRAPixel));
   ListElementType : array[svtFloatList..svtPixList] of TScriptVariableType =
-    (svtFloat, svtInteger, svtBoolean, svtString, svtPixel);
+    (svtFloat, svtInteger, svtPoint, svtBoolean, svtString, svtPixel);
   EmptyListExpression : array[svtFloatList..svtPixList] of string =
-    ('[~0.0]', '[~0]', '[~False]', '[~""]','[~#000]');
+    ('[~0.0]', '[~0]', '[(0.0,0.0)]', '[~False]', '[~""]','[~#000]');
   InterpretationErrorToStr: array[TInterpretationError] of string =
     ('Too many closing brackets', 'Ending quote not found',
      'Opening bracket not found', 'Closing bracket not found',
@@ -74,7 +76,7 @@ const
      'Invalid number', 'Invalid color', 'Invalid boolean',
      'Duplicate identifier', 'Unexpected opening bracket kind',
      'Unexpected closing bracket kind',
-     'Unknown list type', 'Missing value');
+     'Unknown list type', 'Missing value', 'Too many values');
 
 function ScriptQuote(const S: string): string;
 function ScriptUnquote(const S: string): string;
@@ -147,6 +149,13 @@ begin
   case AVarType of
     svtFloat: result := FloatToStrUS(double(AValue));
     svtInteger: result := IntToStr(TScriptInteger(AValue));
+    svtPoint: with TPoint3D(AValue) do
+              begin
+                if z <> EmptySingle then
+                  result := '(' + FloatToStrUS(x)+', '+FloatToStrUS(y)+', '+FloatToStrUS(z)+')'
+                else
+                  result := '(' + FloatToStrUS(x)+', '+FloatToStrUS(y)+')';
+              end;
     svtPixel: result := '#'+BGRAToStr(TBGRAPixel(AValue));
     svtBoolean: result := BoolToStr(Boolean(AValue),TrueToken,FalseToken);
   else raise exception.Create('Not a scalar type');
@@ -192,7 +201,7 @@ var
   valueFloat: double;
   valueBool: boolean;
   valuePixel: TBGRAPixel;
-  errPos: integer;
+  errPos,coordIndex,posComma: integer;
   missingFlag,errorFlag: boolean;
 begin
   result.valueType := svtUndefined;
@@ -273,7 +282,7 @@ begin
           if inBracket = 0 then IsPixel:= true;
         end
         else
-        if expr[cur] = ',' then break;
+        if (expr[cur] in[',','}']) and (inBracket = 0) then break;
       end;
     end;
     previousChar:= expr[cur];
@@ -337,6 +346,40 @@ begin
       result.valueType:= svtPixel;
       result.valuePixel := valuePixel;
     end;
+  end else
+  if (length(valueStr)>=2) and (valueStr[1] = '(') and (valueStr[length(valueStr)] = ')') then
+  begin
+    result.valuePoint:= Point3D(0,0,EmptySingle);
+    valueStr := trim(copy(valueStr,2,length(valueStr)-2));
+    coordIndex := 0;
+    while valueStr<>'' do
+    begin
+      if coordIndex >= 3 then
+      begin
+        errors := errors + [ieTooManyValues];
+        break;
+      end;
+      posComma := pos(',', valueStr);
+      if posComma > 0 then
+        val(copy(valueStr,1,posComma-1),valueFloat,errPos)
+      else
+        val(valueStr,valueFloat,errPos);
+      if errPos <> 0 then
+      begin
+        errors := errors + [ieInvalidNumber];
+        break;
+      end;
+      case coordIndex of
+        0: result.valuePoint.x := valueFloat;
+        1: result.valuePoint.y := valueFloat;
+        2: result.valuePoint.z := valueFloat;
+      end;
+      inc(coordIndex);
+      if posComma = 0 then valueStr := ''
+      else delete(valueStr, 1, posComma);
+    end;
+    if coordIndex >= 2 then
+      result.valueType:= svtPoint;
   end else
     errors := errors + [ieConstantExpressionExpected];
 end;

+ 66 - 0
scripts/lazpaint/tools.py

@@ -38,6 +38,24 @@ STATE_SHIFT = 'Shift'
 STATE_ALT = 'Alt'
 STATE_CTRL = 'Ctrl'
 
+ERASER_MODE_ALPHA = 'EraseAlpha'
+ERASER_MODE_SOFTEN = 'Soften'
+
+PEN_STYLE_SOLD = 'Solid'
+PEN_STYLE_DASH = 'Dash'
+PEN_STYLE_DOT = 'Dot'
+PEN_STYLE_DASH_DOT = 'DashDot'
+PEN_STYLE_DASH_DOT_DOT = 'DashDotDot'
+
+JOIN_STYLE_BEVEL = 'Bevel'
+JOIN_STYLE_MITER = 'Miter'
+JOIN_STYLE_ROUND = 'Round'
+
+SHAPE_OPTION_ALIASING = 'Aliasing'
+SHAPE_OPTION_DRAW_SHAPE = 'DrawShape'
+SHAPE_OPTION_FILL_SHAPE = 'FillShape'
+SHAPE_OPTION_CLOSE_SHAPE = 'CloseShape'
+
 KEY_UNKNOWN = 'Unknown'
 KEY_BACKSPACE = 'Backspace'
 KEY_TAB = 'Tab'
@@ -140,3 +158,51 @@ def keys(keys, state=[]):
 def write(text):
   command.send("ToolWrite", Text=text)
 
+def set_pen_color(color):
+  command.send("ToolSetPenColor", Color=color)
+
+def set_back_color(color):
+  command.send("ToolSetBackColor", Color=color)
+
+def get_pen_color():
+  return str_to_RGBA(command.send("ToolGetPenColor?"))
+
+def get_back_color():
+  return str_to_RGBA(command.send("ToolGetBackColor?"))
+
+def set_eraser_mode(mode):
+  command.send('ToolSetEraserMode', Mode=mode)
+
+def get_eraser_mode():
+  return command.send('ToolGetEraserMode?')
+
+def set_eraser_alpha(alpha):
+  command.send('ToolSetEraserAlpha', Alpha=alpha)
+
+def get_eraser_alpha():
+  return command.send('ToolGetEraserAlpha?')
+
+def set_pen_width(width):
+  command.send('ToolSetPenWidth', Width=width)
+
+def get_pen_width():
+  return command.send('ToolGetPenWidth?')
+
+def set_pen_style(style):
+  command.send('ToolSetPenStyle', Style=style)
+
+def get_pen_style():
+  return command.send('ToolGetPenStyle?')
+
+def set_join_style(style):
+  command.send('ToolSetJoinStyle', Style=style)
+
+def get_join_style():
+  return command.send('ToolGetJoinStyle?')
+
+def set_shape_options(options):
+  command.send('ToolSetShapeOptions', Options=options)
+
+def get_shape_options():
+  return command.send('ToolGetShapeOptions?')
+

+ 6 - 1
scripts/test_tools.py

@@ -1,17 +1,22 @@
-from lazpaint import tools, image, layer
+from lazpaint import tools, image, layer, colors
 
 image.new(800, 600)
 
 tools.choose(tools.PEN)
+tools.set_pen_color(colors.RED)
+tools.set_back_color(colors.ORANGE)
 tools.mouse( (50,50) )
 tools.mouse( [(50,100, 0.5), (100,100, 0.5)], [tools.STATE_RIGHT] )
 
 tools.choose(tools.ELLIPSE)
 tools.mouse( [(150,50), (250,150)], [tools.STATE_RIGHT] )
+tools.set_pen_color(colors.YELLOW)
+tools.set_back_color(colors.BLUE)
 tools.keys(tools.KEY_RETURN)
 
 tools.choose(tools.TEXT)
 tools.mouse( [(50,150), (450,350)] )
+tools.set_pen_color(colors.BLACK)
 tools.write("Hello\nworld")
 
 layer.new()

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels