├── Pics ├── for.png ├── funcs.png ├── math.png ├── while.png ├── PicEx1.png ├── Search.png ├── imports.png ├── lambda.png ├── Assignment.png ├── ButtonsTop.png ├── RightClick.png ├── TicTacToe.png ├── iterables.png ├── BigExamplePic.png ├── ColorfulEx1.png ├── comprehension.png ├── if-else-elif.png ├── short-if-else.png ├── BigExampleText.png ├── GuessingGamePic.png ├── break-continue.png ├── BlackAndWhiteEx1.png ├── GuessingGameText.png └── print-return-None.png ├── GraphicIDE ├── Resources │ ├── pi.png │ ├── None.png │ ├── bug.png │ ├── copy.png │ ├── dot.png │ ├── list.png │ ├── max.png │ ├── min.png │ ├── open.png │ ├── pass.png │ ├── play.png │ ├── plus.png │ ├── save.png │ ├── self.png │ ├── sum.png │ ├── yarn.png │ ├── Arrow.png │ ├── Trash.png │ ├── boolXY.png │ ├── console.png │ ├── divmod.png │ ├── filter.png │ ├── float12.png │ ├── hastag.png │ ├── int1234.png │ ├── lockImg.png │ ├── paste.png │ ├── printer.png │ ├── red_X.png │ ├── rename.png │ ├── round.png │ ├── ruler.png │ ├── search.png │ ├── truck.png │ ├── tuple.png │ ├── Settings.png │ ├── emptyDict.png │ ├── emptyList.png │ ├── emptySet.png │ ├── keyboard.png │ ├── lightbulb.png │ ├── emptyTuple.png │ ├── forArrowDown.png │ ├── forArrowUp.png │ ├── light_play.png │ ├── whileArrowUp.png │ ├── whiteArrow.png │ ├── shortArrowRed.png │ ├── whileArrowDown.png │ ├── shortArrowGreen.png │ └── brightnessBarSymbol.png ├── GlobalSuppressions.cs ├── Program.cs ├── Classes │ ├── example.text │ ├── MyMath.cs │ ├── MyImages.cs │ ├── History.cs │ ├── BrushesAndPens.cs │ ├── Start.cs │ ├── Settings.cs │ ├── PythonFuncs.cs │ ├── Helpers.cs │ ├── DrawScreen.cs │ ├── Console.cs │ ├── Tabs.cs │ ├── Prediction.cs │ ├── Form1.cs │ └── KeyInput.cs ├── GraphicIDE.csproj ├── Form1.Designer.cs ├── Form1.resx └── Properties │ ├── Resources.resx │ └── Resources.Designer.cs ├── LICENSE.txt ├── GraphicIDE.sln ├── .github └── workflows │ └── deploy-GraphicIDE.yml ├── .gitattributes ├── README.md └── .gitignore /Pics/for.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/for.png -------------------------------------------------------------------------------- /Pics/funcs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/funcs.png -------------------------------------------------------------------------------- /Pics/math.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/math.png -------------------------------------------------------------------------------- /Pics/while.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/while.png -------------------------------------------------------------------------------- /Pics/PicEx1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/PicEx1.png -------------------------------------------------------------------------------- /Pics/Search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/Search.png -------------------------------------------------------------------------------- /Pics/imports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/imports.png -------------------------------------------------------------------------------- /Pics/lambda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/lambda.png -------------------------------------------------------------------------------- /Pics/Assignment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/Assignment.png -------------------------------------------------------------------------------- /Pics/ButtonsTop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/ButtonsTop.png -------------------------------------------------------------------------------- /Pics/RightClick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/RightClick.png -------------------------------------------------------------------------------- /Pics/TicTacToe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/TicTacToe.png -------------------------------------------------------------------------------- /Pics/iterables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/iterables.png -------------------------------------------------------------------------------- /Pics/BigExamplePic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/BigExamplePic.png -------------------------------------------------------------------------------- /Pics/ColorfulEx1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/ColorfulEx1.png -------------------------------------------------------------------------------- /Pics/comprehension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/comprehension.png -------------------------------------------------------------------------------- /Pics/if-else-elif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/if-else-elif.png -------------------------------------------------------------------------------- /Pics/short-if-else.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/short-if-else.png -------------------------------------------------------------------------------- /Pics/BigExampleText.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/BigExampleText.png -------------------------------------------------------------------------------- /Pics/GuessingGamePic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/GuessingGamePic.png -------------------------------------------------------------------------------- /Pics/break-continue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/break-continue.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/pi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/pi.png -------------------------------------------------------------------------------- /Pics/BlackAndWhiteEx1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/BlackAndWhiteEx1.png -------------------------------------------------------------------------------- /Pics/GuessingGameText.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/GuessingGameText.png -------------------------------------------------------------------------------- /Pics/print-return-None.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/Pics/print-return-None.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/None.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/None.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/bug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/bug.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/copy.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/dot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/dot.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/list.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/max.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/min.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/min.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/open.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/pass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/pass.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/play.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/plus.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/save.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/self.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/self.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/sum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/sum.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/yarn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/yarn.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/Arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/Arrow.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/Trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/Trash.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/boolXY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/boolXY.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/console.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/divmod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/divmod.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/filter.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/float12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/float12.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/hastag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/hastag.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/int1234.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/int1234.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/lockImg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/lockImg.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/paste.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/paste.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/printer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/printer.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/red_X.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/red_X.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/rename.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/round.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/ruler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/ruler.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/search.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/truck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/truck.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/tuple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/tuple.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/Settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/Settings.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/emptyDict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/emptyDict.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/emptyList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/emptyList.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/emptySet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/emptySet.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/keyboard.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/lightbulb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/lightbulb.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/emptyTuple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/emptyTuple.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/forArrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/forArrowDown.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/forArrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/forArrowUp.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/light_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/light_play.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/whileArrowUp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/whileArrowUp.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/whiteArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/whiteArrow.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/shortArrowRed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/shortArrowRed.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/whileArrowDown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/whileArrowDown.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/shortArrowGreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/shortArrowGreen.png -------------------------------------------------------------------------------- /GraphicIDE/Resources/brightnessBarSymbol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AharonSambol/GraphicIDE/HEAD/GraphicIDE/Resources/brightnessBarSymbol.png -------------------------------------------------------------------------------- /GraphicIDE/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | // This file is used by Code Analysis to maintain SuppressMessage 2 | // attributes that are applied to this project. 3 | // Project-level suppressions either have no target or are given 4 | // a specific target and scoped to a namespace, type, member, etc. 5 | 6 | using System.Diagnostics.CodeAnalysis; 7 | 8 | [assembly: SuppressMessage("Style", "IDE0042:Deconstruct variable declaration", Justification = "", Scope = "member", Target = "~M:GraphicIDE.Form1.OnMouseClick(System.Windows.Forms.MouseEventArgs)")] 9 | -------------------------------------------------------------------------------- /GraphicIDE/Program.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE 2 | { 3 | internal static class Program 4 | { 5 | /// 6 | /// The main entry point for the application. 7 | /// 8 | [STAThread] 9 | static void Main() 10 | { 11 | // To customize application configuration such as set high DPI settings or default font, 12 | // see https://aka.ms/applicationconfiguration. 13 | ApplicationConfiguration.Initialize(); 14 | Application.SetCompatibleTextRenderingDefault(false); 15 | Application.Run(new Form1()); 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/example.text: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | a = [1.5, 3**5, math.sqrt(6/(3+2))] 4 | if a is None: 5 | pass 6 | elif len(a) > 3: 7 | arr = [x ** 2 for x in a if x % 2 == 0] 8 | else: 9 | while sum(a) < 10: 10 | a += [1] 11 | for x in a: 12 | print(x if x > 0 else "negative") 13 | if x > y: 14 | break 15 | 16 | 17 | 18 | 19 | name = input("enter name") 20 | a = hash("wow") 21 | d, m = divmod(35, 2) 22 | x = round(34.5) 23 | mx = max(my_list) 24 | mn = min(my_list) 25 | f = filter(ar, fn) 26 | i = int(x) 27 | f = float(x) 28 | s = str(x) 29 | b = bool(x) 30 | l = list(x) 31 | t = tuple(x) 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /GraphicIDE/Classes/MyMath.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | public static class MyMath { 3 | public static float Abs(float num) => num > 0 ? num : -num; 4 | public static float Max(float num1, float num2) => num1 > num2 ? num1 : num2; 5 | public static int Max(int num1, int num2) => num1 > num2 ? num1 : num2; 6 | public static float Min(float num1, float num2) => num1 < num2 ? num1 : num2; 7 | public static int Min(int num1, int num2) => num1 < num2 ? num1 : num2; 8 | public static (float, float) MaxMin(float num1, float num2) => num1 > num2 ? (num1, num2) : (num2, num1); 9 | public static (int, int) MaxMin(int num1, int num2) => num1 > num2 ? (num1, num2) : (num2, num1); 10 | } -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /GraphicIDE.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.2.32616.157 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphicIDE", "GraphicIDE\GraphicIDE.csproj", "{923CD49F-2E28-48DC-AAA4-93BE798CED6B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {923CD49F-2E28-48DC-AAA4-93BE798CED6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {923CD49F-2E28-48DC-AAA4-93BE798CED6B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {923CD49F-2E28-48DC-AAA4-93BE798CED6B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {923CD49F-2E28-48DC-AAA4-93BE798CED6B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {BDCCF987-E698-435E-B13B-5C13F712EBF4} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /.github/workflows/deploy-GraphicIDE.yml: -------------------------------------------------------------------------------- 1 | name: "Deploy GraphicIDE" 2 | 3 | on: 4 | push: 5 | tags: 6 | - "GraphicIDE/v*" 7 | 8 | env: 9 | PROJECT_PATH: GraphicIDE/GraphicIDE.csproj 10 | 11 | jobs: 12 | deploy: 13 | runs-on: windows-latest 14 | steps: 15 | - uses: actions/checkout@v2 16 | 17 | - uses: actions/setup-dotnet@v1 18 | with: 19 | dotnet-version: 6.0.x 20 | 21 | - run: dotnet restore ${{ env.PROJECT_PATH }} 22 | 23 | - run: dotnet build ${{ env.PROJECT_PATH }} -c Release --no-restore 24 | 25 | - run: dotnet publish ${{ env.PROJECT_PATH }} -c Release --self-contained -r win-x64 -p:PublishSingleFile=true --no-build 26 | 27 | - uses: actions/create-release@v1 28 | id: create_release 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | with: 32 | tag_name: ${{ github.ref }} 33 | release_name: ${{ github.ref }} 34 | 35 | - uses: csexton/release-asset-action@v2 36 | with: 37 | github-token: ${{ secrets.GITHUB_TOKEN }} 38 | pattern: GraphicIDE/bin/Release/net6.0-windows/win-x64/publish/*.exe 39 | release-url: ${{ steps.create_release.outputs.upload_url }} 40 | -------------------------------------------------------------------------------- /GraphicIDE/GraphicIDE.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0-windows 6 | enable 7 | true 8 | enable 9 | true 10 | true 11 | win-x64 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | True 23 | True 24 | Resources.resx 25 | 26 | 27 | 28 | 29 | 30 | ResXFileCodeGenerator 31 | Resources.Designer.cs 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /GraphicIDE/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.SuspendLayout(); 32 | // 33 | // Form1 34 | // 35 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 36 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 37 | this.ClientSize = new System.Drawing.Size(800, 450); 38 | this.Name = "Form1"; 39 | this.Text = "Form1"; 40 | this.Paint += new System.Windows.Forms.PaintEventHandler(DrawScreen.Form1_Paint); 41 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(KeyInput.Form1_KeyDown); 42 | this.Resize += new(this.Resize_Event); 43 | this.Move += new(this.Move_Event); 44 | 45 | this.ResumeLayout(false); 46 | 47 | } 48 | 49 | #endregion 50 | 51 | } 52 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/MyImages.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class MyImages { 4 | public static readonly Bitmap 5 | whileArrowDownImg = new(Resources.whileArrowDown), 6 | whileArrowUpImg = new(Resources.whileArrowUp), 7 | forArrowDownImg = new(Resources.forArrowDown), 8 | forArrowUpImg = new(Resources.forArrowUp), 9 | emptyDictImg = new(Resources.emptyDict), 10 | emptyListImg = new(Resources.emptyList), 11 | emptyTupleImg = new(Resources.emptyTuple), 12 | lightmodeImg = new(Resources.brightnessBarSymbol), 13 | shortArrowG = new(Resources.shortArrowGreen), 14 | shortArrowR = new(Resources.shortArrowRed), 15 | keyboardImg = new(Resources.keyboard), 16 | settingsImg = new(Resources.Settings), 17 | printerImg = new(Resources.printer), 18 | consoleImg = new(Resources.console), 19 | hashtagImg = new(Resources.hastag), 20 | searchImg = new(Resources.search), 21 | renameImg = new(Resources.rename), 22 | returnImg = new(Resources.Arrow), 23 | play3dImg = new(Resources.play1), 24 | divmodImg = new(Resources.divmod), 25 | filterImg = new(Resources.filter), 26 | arrowImg = new(Resources.whiteArrow), 27 | floatImg = new(Resources.float12), 28 | rulerImg = new(Resources.ruler), 29 | roundImg = new(Resources.round), 30 | truckImg = new(Resources.truck), 31 | pasteImg = new(Resources.paste), 32 | tupleImg = new(Resources.tuple), 33 | debugImg = new(Resources.bug), 34 | trashImg = new(Resources.Trash), 35 | lockImg = new(Resources.lockImg), 36 | boolImg = new(Resources.boolXY), 37 | listImg = new(Resources.list), 38 | playImg = new(Resources.play), 39 | copyImg = new(Resources.copy), 40 | noneImg = new(Resources.None), 41 | plusImg = new(Resources.plus), 42 | saveImg = new(Resources.save), 43 | openImg = new(Resources.open), 44 | passImg = new(Resources.pass), 45 | intImg = new(Resources.int1234), 46 | dotImg = new(Resources.dot), 47 | sumImg = new(Resources.sum), 48 | maxImg = new(Resources.max), 49 | minImg = new(Resources.min), 50 | strImg = new(Resources.yarn), 51 | xImg = new(Resources.red_X); 52 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /GraphicIDE/Form1.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | text/microsoft-resx 50 | 51 | 52 | 2.0 53 | 54 | 55 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 56 | 57 | 58 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 59 | 60 | -------------------------------------------------------------------------------- /GraphicIDE/Classes/History.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class History { 4 | // todo each list should only have one cursorPos, selectedLine 5 | private const int historyAmount = 100; 6 | private static Stack 7 | history = new(historyAmount), 8 | future = new(historyAmount); 9 | 10 | public static void CtrlY(){ 11 | if(future.IsEmpty()){ return; } 12 | var changes = future.Pop(); 13 | (int, int) lastCursor = CursorPos.ToTuple(); 14 | (int, int)? lastSelect = selectedLine; 15 | for (int i=0; i < changes.Count; i++) { 16 | var (typ, line, change, cursor, select) = changes[i]; 17 | changes[i] = changes[i] with { cursor = lastCursor, select = lastSelect }; 18 | lastCursor = cursor; 19 | lastSelect = select; 20 | switch (typ){ 21 | case ChangeType.del: 22 | linesText.RemoveAt(line); 23 | break; 24 | case ChangeType.add: 25 | linesText.Insert(line, change); 26 | break; 27 | case ChangeType.change: 28 | changes[i] = changes[i] with { change = linesText[line] }; 29 | linesText[line] = change; 30 | break; 31 | } 32 | } 33 | changes.Reverse(); 34 | history.Push(changes); 35 | CursorPos.ChangeBoth(lastCursor); 36 | selectedLine = lastSelect; 37 | nonStatic.Invalidate(); 38 | } 39 | public static void CtrlZ(){ 40 | if(history.IsEmpty()){ return; } 41 | var changes = history.Pop(); 42 | (int, int) lastCursor = CursorPos.ToTuple(); 43 | (int, int)? lastSelect = selectedLine; 44 | for (int i=0; i < changes.Count; i++) { 45 | var (typ, line, change, cursor, select) = changes[i]; 46 | changes[i] = changes[i] with { cursor = lastCursor, select = lastSelect }; 47 | lastCursor = cursor; 48 | lastSelect = select; 49 | switch (typ){ 50 | case ChangeType.del: 51 | linesText.Insert(line, change); 52 | break; 53 | case ChangeType.add: 54 | linesText.RemoveAt(line); 55 | break; 56 | case ChangeType.change: 57 | changes[i] = changes[i] with { change = linesText[line] }; 58 | linesText[line] = change; 59 | break; 60 | } 61 | } 62 | changes.Reverse(); 63 | future.Push(changes); 64 | CursorPos.ChangeBoth(lastCursor); 65 | selectedLine = lastSelect; 66 | nonStatic.Invalidate(); 67 | } 68 | public static void AddChange(List val){ 69 | history.Push(val); 70 | future.Empty(); 71 | unsavedButton!.Show(); 72 | Prediction.Predict(); 73 | } 74 | public static void AddChange(Change val) => AddChange(new List(){ val }); 75 | } 76 | public record struct Change( 77 | ChangeType typ, int line, string change, 78 | (int line, int col) cursor, (int line, int col)? select 79 | ); 80 | public enum ChangeType { del, add, change } 81 | class Stack{ 82 | private List?[] stack; 83 | private int pos, size; 84 | 85 | public Stack(int size){ 86 | stack = new List?[size]; 87 | pos = size - 1; 88 | this.size = size; 89 | } 90 | public void Push(List val){ 91 | pos = (pos+1) % size; 92 | stack[pos] = val; 93 | } 94 | public List Pop(){ 95 | if(IsEmpty()){ throw new Exception(); } 96 | var val = stack[pos]; 97 | stack[pos] = null; 98 | pos = pos == 0 ? size - 1 : pos - 1; 99 | return val!; 100 | } 101 | public List Peek(){ 102 | if(IsEmpty()){ throw new Exception(); } 103 | var val = stack[pos]; 104 | return val!; 105 | } 106 | public bool IsEmpty() => stack[pos] is null; 107 | public void Empty() => stack[pos] = null; 108 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/BrushesAndPens.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class BrushesAndPens{ 4 | private static readonly float[] dashes = new[] { 5f, 2f }; 5 | public static readonly Color 6 | sumColor = Color.FromArgb(255, 255, 255, 255), 7 | lenColor = Color.FromArgb(255, 215, 206, 180), 8 | hashColor = Color.FromArgb(255, 072, 158, 095), 9 | forBlue = Color.FromArgb(255, 095, 129, 199), 10 | listRed = Color.FromArgb(255, 157, 059, 052), 11 | redOpaqe = Color.FromArgb(100, 255, 000, 000), 12 | blueOpaqe = Color.FromArgb(100, 075, 180, 245), 13 | lightGray = Color.FromArgb(080, 200, 200, 200), 14 | keyOrange = Color.FromArgb(255, 245, 190, 080), 15 | greenOpaqe = Color.FromArgb(100, 000, 255, 000), 16 | mathPurple = Color.FromArgb(255, 164, 128, 207), 17 | truckColor = Color.FromArgb(255, 089, 025, 025), 18 | whileOrange = Color.FromArgb(255, 223, 146, 082), 19 | truckIColor = Color.FromArgb(255, 137, 024, 026), 20 | tabBarColor = Color.FromArgb(255, 100, 100, 100), 21 | orangeOpaqe = Color.FromArgb(100, 250, 200, 093), 22 | divmodColor = Color.FromArgb(255, 216, 170, 240), 23 | opaqeForBlue = Color.FromArgb(050, 095, 129, 199), 24 | shortIfElseG = Color.FromArgb(255, 096, 202, 105), 25 | shortIfElseR = Color.FromArgb(255, 171, 038, 020), 26 | lblue = Color.FromArgb(255, 145, 178, 221), 27 | opaqekeyOrange = Color.FromArgb(050, 245, 190, 080), 28 | opaqeMathPurple = Color.FromArgb(050, 164, 128, 207); 29 | public static readonly SolidBrush 30 | lblueBrush = new(lblue), 31 | forBlueB = new(forBlue), 32 | keyOrangeB = new(keyOrange), 33 | mathPurpleB = new(mathPurple), 34 | truckIBrush = new(truckIColor), 35 | tabBarBrush = new(tabBarColor), 36 | shortIfElseGB = new(shortIfElseG), 37 | shortIfElseRB = new(shortIfElseR), 38 | yellowB = new(Color.Wheat), 39 | whiteBrush = new(Color.White), 40 | blackBrush = new(Color.Black), 41 | curserBrush = new(Color.WhiteSmoke), 42 | smokeWhiteBrush = new(Color.WhiteSmoke), 43 | redBrush = new(Color.FromArgb(255, 200, 049, 045)), 44 | intBrush = new(Color.FromArgb(255, 207, 255, 182)), 45 | timeBrush = new(Color.FromArgb(255, 100, 100, 100)), 46 | textBrush = new(Color.FromArgb(255, 160, 160, 160)), 47 | titleBrush = new(Color.FromArgb(255, 150, 150, 160)), 48 | sandyBrush = new(Color.FromArgb(255, 189, 169, 119)), 49 | greenBrush = new(Color.FromArgb(255, 110, 255, 130)), 50 | selectBrush = new(Color.FromArgb(100, 000, 100, 255)), 51 | stringBrush = new(Color.FromArgb(255, 255, 204, 116)), 52 | predictionBrush = new(Color.FromArgb(100, 160, 160, 160)), 53 | parenthesiesBrush = new(Color.FromArgb(255, 076, 175, 104)); 54 | public static SolidBrush curTextBrush = textBrush; 55 | public static readonly Pen 56 | redDashed = new(redOpaqe, 5) { DashPattern = dashes }, 57 | blueDashed = new(blueOpaqe, 5) { DashPattern = dashes }, 58 | greenDashed = new(greenOpaqe, 5) { DashPattern = dashes }, 59 | orangeDashed = new(orangeOpaqe, 5) { DashPattern = dashes }, 60 | whiteP = new(Color.Gray, 4), 61 | yellowP = new(Color.Wheat, 5), 62 | orangeP = new(Color.FromArgb(255, 233, 166, 109), 5), 63 | sumP = new(sumColor, 2), 64 | lenP = new(lenColor, 2), 65 | hashP = new(hashColor, 2), 66 | listP = new(listRed, 2), 67 | tupleP = new(lblue, 2), 68 | lblueP = new(lblue, 4), 69 | redListP = new(listRed, 5), 70 | forBlueP = new(forBlue, 4), 71 | divmodP = new(divmodColor, 2), 72 | redOpaqeP = new(redOpaqe, 5), 73 | blueOpaqeP = new(blueOpaqe, 5), 74 | keyOrangeP = new(keyOrange, 5), 75 | greenOpaqeP = new(greenOpaqe, 5), 76 | truckP = new(truckColor, 4), 77 | mathPurpleP = new(mathPurple, 5), 78 | whileOrangeP = new(whileOrange, 4), 79 | orangeOpaqeP = new(orangeOpaqe, 5), 80 | shortIfElseGP = new(shortIfElseG, 4), 81 | intFuncP = new(Color.FromArgb(255, 154, 232, 213), 2), 82 | strFuncP = new(Color.FromArgb(255, 130, 185, 131), 2), 83 | boolFuncP = new(Color.FromArgb(255, 189, 015, 000), 2), 84 | shortIfElseRP = new(shortIfElseR, 4), 85 | loopColorB = new(Color.FromArgb(255, 132, 211, 230), 6), 86 | loopColorG = new(Color.FromArgb(255, 132, 230, 161), 6), 87 | loopColorY = new(Color.FromArgb(255, 230, 227, 132), 6), 88 | loopColorP = new(Color.FromArgb(255, 227, 132, 230), 6); 89 | public static (int pos, Pen[] pens) loopColors = (0, new[]{loopColorB, loopColorG, loopColorP, loopColorY}); 90 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/Start.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class Start{ 4 | public static Button RunBtn() { 5 | Button btn = MakeButton(TAB_HEIGHT - 6, TAB_HEIGHT - 6, play3dImg, streatch: false); 6 | btn.Click += new EventHandler(PythonFuncs.ExecuteBtn!); 7 | buttonsOnScreen.Add((btn, (size) => new(3 + size.w - TAB_HEIGHT - 10, 3))); 8 | toolTip.SetToolTip(btn, "run"); 9 | return btn; 10 | } 11 | public static Button SettingsBtn() { 12 | Button btn = MakeButton(TAB_HEIGHT, TAB_HEIGHT, settingsImg, streatch: true); 13 | btn.Click += new EventHandler((_,_) => ToggleSettings()); 14 | nonStatic.Controls.Add(btn); 15 | buttonsOnScreen.Add((btn, (size) => new(size.w - 2 * (btn.Size.Width + 10), 0))); 16 | toolTip.SetToolTip(btn, "settings"); 17 | return btn; 18 | } 19 | public static Button TabBtn() { 20 | Button btn = MakeButton(TAB_HEIGHT, TAB_HEIGHT, plusImg, streatch: true); 21 | btn.Click += new EventHandler(AddTabEvent!); 22 | buttonsOnScreen.Add((btn, (size) => new(size.w - 3 * (btn.Size.Width + 10), 0))); 23 | toolTip.SetToolTip(btn, "new function\\tab"); 24 | return btn; 25 | } 26 | public static Button RenameTabBtn() { 27 | Button btn = MakeButton(TAB_HEIGHT, TAB_HEIGHT, renameImg, streatch: true); 28 | btn.Click += new EventHandler((_,_) => PromptRenameTab()); 29 | nonStatic.Controls.Add(btn); 30 | buttonsOnScreen.Add((btn, (size) => new(size.w - 4 * (btn.Size.Width + 10), 0))); 31 | toolTip.SetToolTip(btn, "rename function"); 32 | return btn; 33 | } 34 | public static Button TrashBtn() { 35 | Button btn = MakeButton(TAB_HEIGHT - 4, TAB_HEIGHT - 4, trashImg, streatch: true); 36 | btn.Click += new EventHandler((_,_) => DeleteFunc(curFunc.name)); 37 | nonStatic.Controls.Add(btn); 38 | buttonsOnScreen.Add((btn, (size) => new(2 + size.w - 5 * (TAB_HEIGHT + 10), 2))); 39 | toolTip.SetToolTip(btn, "delete function"); 40 | return btn; 41 | } 42 | public static Button SaveBtn() { 43 | Button btn = MakeButton(TAB_HEIGHT - 4, TAB_HEIGHT - 4, saveImg, streatch: true); 44 | btn.Click += new EventHandler((_,_) => Save(IsAltlPressed())); 45 | nonStatic.Controls.Add(btn); 46 | buttonsOnScreen.Add((btn, (size) => new(2 + size.w - 6 * (TAB_HEIGHT + 10), 2))); 47 | toolTip.SetToolTip(btn, "save file"); 48 | return btn; 49 | } 50 | public static Button OpenBtn() { 51 | Button btn = MakeButton(TAB_HEIGHT, TAB_HEIGHT, openImg, streatch: true); 52 | btn.Click += new EventHandler((_,_) => Open()); 53 | nonStatic.Controls.Add(btn); 54 | buttonsOnScreen.Add((btn, (size) => new(size.w - 7 * (TAB_HEIGHT + 10), 0))); 55 | toolTip.SetToolTip(btn, "open file"); 56 | return btn; 57 | } 58 | public static Button? unsavedButton; 59 | public static Button UnsavedButton() { 60 | unsavedButton = MakeButton(TAB_HEIGHT/2, TAB_HEIGHT/2, dotImg, streatch: true); 61 | buttonsOnScreen.Add((unsavedButton, (size) => new(5, size.h - unsavedButton.Size.Height - 5))); 62 | toolTip.SetToolTip(unsavedButton, "unsaved"); 63 | return unsavedButton; 64 | } 65 | public static void AddConsole() { 66 | var (height, width) = (screenHeight, screenWidth); 67 | int consolePos = height - (height / 4); 68 | Bitmap img = new(width, height - consolePos); 69 | var func = new Function(".console") { 70 | displayImage = img, 71 | }; 72 | console = new Window(func) { 73 | pos = (0, consolePos), 74 | size = (width, height - consolePos), 75 | asPlainText = true, 76 | txtBrush = textBrush, 77 | }; 78 | nameToFunc[func.name] = console.function; 79 | } 80 | public static Button MakeExecTimeDisplay(){ 81 | var w = MeasureWidth(executedTime, boldFont); 82 | var h = txtHeight; 83 | Bitmap bm = new(w, h); 84 | using(var g = Graphics.FromImage(bm)){ 85 | g.DrawString(executedTime, boldFont, timeBrush, 0, 0); 86 | } 87 | execTimeBtn = MakeButton(w, h, bm, streatch: false); 88 | execTimeBtn.Click += new EventHandler((object? s, EventArgs e) => ToggleTimeBtn()); 89 | buttonsOnScreen.Add((execTimeBtn, ETBCalcPos)); 90 | return execTimeBtn; 91 | } 92 | public static Button MakeButton(int w, int h, Bitmap img, bool streatch){ 93 | Button btn = new() { 94 | Size = new(w, h), 95 | BackColor = Color.Transparent, 96 | BackgroundImage = img, 97 | FlatStyle = FlatStyle.Flat, 98 | BackgroundImageLayout = streatch ? ImageLayout.Stretch : ImageLayout.Zoom, 99 | }; 100 | btn.FlatAppearance.BorderSize = 0; 101 | btn.FlatAppearance.BorderColor = Color.White; 102 | btn.FlatAppearance.MouseOverBackColor = lightGray; 103 | nonStatic.Controls.Add(btn); 104 | return btn; 105 | } 106 | 107 | public static async void FocusTB(){ 108 | await Task.Delay(100); 109 | textBox.Focus(); 110 | } 111 | 112 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/Settings.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class Settings { 4 | public static Menu? settingsScreen; 5 | public static Menu? staticSettingsScreen; 6 | public static string? savePath; 7 | public static void ToggleSettings(){ 8 | int size = 80, gap = 10; 9 | 10 | bool addToControls = true; 11 | if(staticSettingsScreen is null){ 12 | MakeFirstSettingsScreen(); 13 | addToControls = false; 14 | } 15 | 16 | int sizeH = size * 2 + gap * 3; 17 | int sizeW = size * 3 + gap * 4; 18 | (int X, int Y) location = (screenWidth/2 - sizeW/2, screenHeight/2 - sizeH/2); 19 | Rectangle bgPos = new(location.X, location.Y, sizeW, sizeH); 20 | 21 | foreach(var button in staticSettingsScreen!.Value.buttons) { 22 | button.btn.Location = button.getPos(location); 23 | if(addToControls){ 24 | nonStatic.Controls.Add(button.btn); 25 | } 26 | button.btn.BringToFront(); 27 | } 28 | 29 | settingsScreen = new(bgPos, staticSettingsScreen!.Value.bgColor, staticSettingsScreen.Value.buttons); 30 | visibleMenues.Add((Menu)settingsScreen); 31 | BlockMouse(staticSettingsScreen!.Value.buttons[0].btn, settingsScreen); 32 | nonStatic.Invalidate(); 33 | } 34 | private static void MakeFirstSettingsScreen(){ 35 | int size = 80, gap = 10; 36 | 37 | Button bg = MakeButton(40, 40, new(1, 1), streatch: false); 38 | bg.FlatAppearance.MouseOverBackColor = Color.Transparent; 39 | bg.MouseDown += new MouseEventHandler((object? _, MouseEventArgs e) => { 40 | if(e.Button == MouseButtons.Right){ 41 | RightClick(); 42 | } else { 43 | DisposeMenu(ref settingsScreen); 44 | } 45 | }); 46 | 47 | Button lightmode = MakeButton(size, size, lightmodeImg, streatch: false); 48 | Func<(int X, int Y), Point> lightmodeGetPos = (pos) => new(pos.X + gap, pos.Y + gap); 49 | lightmode.Click += new EventHandler((_,_) => { 50 | DisposeMenu(ref settingsScreen); 51 | MessageBox.Show("no."); 52 | }); 53 | toolTip.SetToolTip(lightmode, "light-mode"); 54 | 55 | staticSettingsScreen = new(new(0,0,1,1), smokeWhiteBrush, new(){ 56 | (bg, (_)=>new(0,0)), 57 | (lightmode, lightmodeGetPos), 58 | }); 59 | } 60 | public static void Save(bool isShift){ 61 | if(savePath is not null && !isShift){ 62 | SaveAsync(); 63 | return; 64 | } 65 | using(SaveFileDialog save = new SaveFileDialog()){ 66 | save.FileName = "AnAwsomeProgram.py"; 67 | save.Filter = "Python File | *.py | Text File | *.txt"; 68 | if (save.ShowDialog() == DialogResult.OK){ 69 | savePath = Path.GetFullPath(save.FileName); 70 | SaveAsync(); 71 | } 72 | } 73 | } 74 | public static void Open(){ 75 | using(OpenFileDialog openFileDialog = new OpenFileDialog()){ 76 | openFileDialog.FileName = "AnAwsomeProgram.py"; 77 | openFileDialog.Filter = "Python File | *.py | Text File | *.txt"; 78 | if (openFileDialog.ShowDialog() == DialogResult.OK){ 79 | try{ 80 | var filePath = openFileDialog.FileName; 81 | var fileStream = openFileDialog.OpenFile(); 82 | string fileContent; 83 | using (StreamReader reader = new StreamReader(fileStream)){ 84 | fileContent = reader.ReadToEnd(); 85 | } 86 | var funcs = fileContent.Split("\r\ndef"); 87 | if(funcs[0].StartsWith("def")){ 88 | funcs[0] = funcs[0].Substring(3); 89 | } 90 | foreach(var func in funcs) { 91 | var lines = func.Split(new string[]{"\r\n", "\n"}, StringSplitOptions.None); 92 | if(func.Equals(funcs[^1])){ 93 | var newFunc = NewFunc(lines[0].Trim().TrimEnd(':')); 94 | for (int i=1; i < lines.Length; i++) { 95 | if(!lines[i].StartsWith("\t") && !lines[i].StartsWith(" ")){ 96 | newFunc.linesText = lines[1..i].Select((x)=>x.Replace("\t", " ").Substring(4)).ToList(); 97 | var main = nameToFunc[".Main"]; 98 | main.linesText = lines[i..].Select((x)=>x.Replace("\t", " ")).ToList(); 99 | (main.curLine, main.curCol) = (0, -1); 100 | break; 101 | } 102 | } 103 | ChangeTab(curWindow.tabButtons[^1], curWindow); 104 | } else { 105 | var newFunc = NewFunc(lines[0].Trim().TrimEnd(':')); 106 | newFunc.linesText = lines[1..].Select((x)=>x.Replace("\t", " ").Substring(4)).ToList(); 107 | } 108 | } 109 | } catch (Exception){} 110 | } 111 | } 112 | } 113 | private static async void SaveAsync(){ 114 | await File.WriteAllTextAsync(savePath!, GetPythonStr()); 115 | unsavedButton!.Hide(); 116 | } 117 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/PythonFuncs.cs: -------------------------------------------------------------------------------- 1 | using IronPython; 2 | using IronPython.Hosting; 3 | using Microsoft.Scripting; 4 | using Microsoft.Scripting.Runtime; 5 | using Microsoft.Scripting.Hosting; 6 | using Microsoft.Scripting.Hosting.Providers; 7 | 8 | namespace GraphicIDE; 9 | 10 | public static class PythonFuncs{ 11 | public static string? errLink = null; 12 | public static PythonAst ToAST() { 13 | StringBuilder theScript = new(); 14 | if(!curFunc.name.StartsWith(".")){ 15 | theScript.Append("def ").Append(curFunc.name).AppendLine(":"); 16 | foreach(var line in linesText) { 17 | theScript.Append(" ").AppendLine(line); 18 | } 19 | } else { 20 | foreach(var line in linesText) { 21 | theScript.AppendLine(line); 22 | } 23 | } 24 | var engine = Python.CreateEngine(); 25 | 26 | ScriptSource source = engine.CreateScriptSourceFromString( 27 | theScript.ToString(), 28 | SourceCodeKind.InteractiveCode 29 | ); 30 | 31 | SourceUnit unit = HostingHelpers.GetSourceUnit(source); 32 | Parser p = Parser.CreateParser( 33 | new CompilerContext(unit, new PythonCompilerOptions(), ErrorSink.Default), 34 | new PythonOptions() 35 | ); 36 | 37 | return p.ParseFile(false); 38 | } 39 | public static void ExecuteBtn(object from, EventArgs e) { 40 | Execute(); 41 | textBox.Focus(); 42 | } 43 | public static async void Execute() { 44 | Settings.Save(false); 45 | if(Settings.savePath is null){ return; } 46 | 47 | // ? to show that it's running 48 | console.function.displayImage = new(1, 1); 49 | nonStatic.Refresh(); 50 | 51 | Func<((string txt, ConsoleTxtType typ)[], string, string)> func = () => { 52 | ProcessStartInfo psi = new ProcessStartInfo("cmd", $"/c python { Settings.savePath }") { 53 | UseShellExecute = false, 54 | RedirectStandardOutput = true, 55 | RedirectStandardError = true, 56 | }; 57 | 58 | Process? p = Process.Start(psi); 59 | string output = p!.StandardOutput.ReadToEnd(); 60 | string err = p!.StandardError.ReadToEnd(); 61 | p.WaitForExit(); 62 | 63 | var exec = $"Execute Time: { (int)((p.ExitTime - p.StartTime).TotalMilliseconds) } ms"; 64 | Func MakeLink = (str) => @"https://www.google.com/search?q=Python" + WebUtility.UrlEncode(" " + str.TrimEnd().Split('\n')[^1]); 65 | if(!output.Equals("") && !err.Equals("")){ 66 | return (new[]{ 67 | (output, ConsoleTxtType.text), (err, ConsoleTxtType.error) 68 | }, exec, MakeLink(err)); 69 | } else if(!err.Equals("")){ 70 | return (new[]{ (err, ConsoleTxtType.error)}, exec, MakeLink(err)); 71 | } else if(!output.Equals("")){ 72 | return (new[]{ (output, ConsoleTxtType.text)}, exec, ""); 73 | } 74 | return (new (string, ConsoleTxtType)[0], exec, ""); 75 | 76 | }; 77 | Task<((string txt, ConsoleTxtType typ)[] txt, string time, string link)> t = Task.Run(func); 78 | 79 | while(!(t.IsCanceled || t.IsCompleted || t.IsCompletedSuccessfully || t.IsFaulted)){ 80 | await Task.Delay(100); 81 | } 82 | executedTime = t.Result.time; 83 | consoleTxt = t.Result.txt; 84 | errLink = t.Result.link; 85 | RefreshTimeBtn(); 86 | ShowConsole(); 87 | } 88 | public static string GetPythonStr(){ 89 | StringBuilder theScript = new(), main = new(); 90 | foreach(var func in nameToFunc.Values) { 91 | if(func.name.Equals(".Main")){ 92 | foreach(var line in func.linesText) { 93 | main.AppendLine(line); 94 | } 95 | } else if(func.name.Equals(".console")){ 96 | continue; 97 | } else { 98 | bool changed = false; 99 | theScript.Append("def ").Append(func.name).Append(":\n"); 100 | foreach(var line in func.linesText) { 101 | if(!changed && !line.Trim().Equals("")){ 102 | changed = true; 103 | } 104 | theScript.Append(" ").AppendLine(line); 105 | } 106 | if(!changed){ 107 | theScript.AppendLine(" pass"); 108 | } 109 | } 110 | } 111 | theScript.Append("\n\n").Append(main); 112 | return theScript.ToString(); 113 | } 114 | } 115 | 116 | public class MyEvtArgs: EventArgs { 117 | public T Value { get; private set; } 118 | public MyEvtArgs(T value) { 119 | this.Value = value; 120 | } 121 | } 122 | public class EventRaisingStreamWriter: StreamWriter { 123 | public event EventHandler> StringWritten = null!; 124 | public EventRaisingStreamWriter(Stream s) : base(s) { } 125 | private void LaunchEvent(string txtWritten) { 126 | // invoke just calls it. so this checks if its null and then calls it 127 | StringWritten?.Invoke(this, new MyEvtArgs(txtWritten)); 128 | } 129 | public override void Write(string? value) { 130 | base.Write(value); 131 | LaunchEvent(value!); 132 | } 133 | public override void Write(bool value) { 134 | base.Write(value); 135 | LaunchEvent(value.ToString()); 136 | } 137 | // here override all writing methods... 138 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/Helpers.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class Helpers { 4 | public static Dictionary fontToPipeSize = new(); 5 | public static readonly Graphics nullGraphics = Graphics.FromImage(new Bitmap(1,1)); 6 | 7 | public static Point GetScreenPos(){ 8 | return Form1.nonStatic.RectangleToScreen(Form1.nonStatic.ClientRectangle).Location; 9 | } 10 | public static int GetHeight(){ 11 | return Form1.nonStatic.RectangleToScreen(Form1.nonStatic.ClientRectangle).Height; 12 | } 13 | public static int GetWidth(){ 14 | return Form1.nonStatic.RectangleToScreen(Form1.nonStatic.ClientRectangle).Width; 15 | } 16 | public static void ChangeOffsetTo(int i){ 17 | curWindow.offset = Math.Clamp( 18 | i, Form1.txtHeight - curWindow.function.displayImage!.Height, 0 19 | ); 20 | } 21 | public static void FirstChangeFontSize(int size){ 22 | Form1.boldFont = new(FontFamily.GenericMonospace, size, FontStyle.Bold); 23 | Form1.indentW = MeasureWidth(" ", Form1.boldFont); 24 | Form1.qWidth = MeasureWidth("¿ ?", Form1.boldFont); 25 | Form1.qHeight = MeasureHeight("¿?", Form1.boldFont); 26 | Form1.upSideDownW = MeasureWidth("¿", Form1.boldFont); 27 | Form1.txtHeight = MeasureHeight( 28 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`~!@#$%^&*()-_=+[]{};:'\"\\/?", 29 | Form1.boldFont 30 | ); 31 | Form1.fromW = MeasureWidth("from ", Form1.boldFont); 32 | Form1.colW = MeasureWidth(": ", Form1.boldFont); 33 | Form1.nonStatic.Invalidate(); 34 | } 35 | public static float imgSize = 1; 36 | public static void ChangeFontSize(int size){ 37 | imgSize += size / 7f; 38 | } 39 | public static string PythonOperatorToString(PythonOperator po) => po switch{ 40 | PythonOperator.In => "in", 41 | PythonOperator.Is => "is", 42 | PythonOperator.IsNot => "is not", 43 | PythonOperator.Not => "not", 44 | PythonOperator.NotIn => "not in", 45 | PythonOperator.LessThan => "<", 46 | PythonOperator.GreaterThan => ">", 47 | PythonOperator.LessThanOrEqual => "<=", 48 | PythonOperator.GreaterThanOrEqual => ">=", 49 | PythonOperator.Equal => "==", 50 | PythonOperator.NotEqual => "!=", 51 | PythonOperator.Add => "+", 52 | PythonOperator.Subtract => "-", 53 | PythonOperator.Multiply => "*", 54 | PythonOperator.Divide => "/", 55 | PythonOperator.FloorDivide => "//", 56 | PythonOperator.Power => "**", 57 | PythonOperator.Mod => "%", 58 | PythonOperator.BitwiseAnd => "&", 59 | PythonOperator.BitwiseOr => "|", 60 | PythonOperator.Xor => "^", 61 | PythonOperator.LeftShift => "<<", 62 | PythonOperator.RightShift => ">>", 63 | PythonOperator.Negate => "-", 64 | PythonOperator.None => "None", 65 | PythonOperator.Invert => "~", 66 | PythonOperator.Pos => "+", 67 | PythonOperator.TrueDivide => "???? what is true divide???", 68 | _ => "??I missed one???" 69 | }; 70 | public static BM_Middle MakeTxtBM(string txt, Brush? brush = null) { 71 | var width = MeasureWidth(txt, Form1.boldFont); 72 | var height = MeasureHeight(txt, Form1.boldFont); 73 | var res = new Bitmap(width, height); 74 | brush = txt switch { 75 | "True" => greenBrush, 76 | "False" => redBrush, 77 | _ => brush ?? textBrush 78 | }; 79 | var g = Graphics.FromImage(res); 80 | g.DrawString(txt, Form1.boldFont, brush, 0, 0); 81 | return new(res, (int)(height / 2)); 82 | } 83 | public static bool IsNumeric(char val) => val == '_' || char.IsLetter(val) || char.IsDigit(val); 84 | public static bool IsAltNumeric(char val) => char.IsLower(val) || char.IsDigit(val); 85 | public static int MeasureWidth(string st, Font ft) { 86 | if(st.Contains('\n')) { 87 | return st.Split("\n").Select( 88 | (line) => MeasureWidth(line, Form1.boldFont) 89 | ).Max(); 90 | } 91 | // used || so that trailing\leading spaces get included too 92 | // you might wonder why theres an "a" in here... me too... it just doesn't work without it... 93 | st = $"|a{st}|"; 94 | return (int)(nullGraphics.MeasureString(st, ft).Width - CachedWidthOfPipes(ft)); 95 | } 96 | public static float CachedWidthOfPipes(Font ft){ 97 | if(fontToPipeSize.TryGetValue(ft, out float res)){ 98 | return res; 99 | } 100 | float w = nullGraphics.MeasureString("|", ft).Width * 2; 101 | fontToPipeSize[ft] = w; 102 | return w; 103 | } 104 | public static int MeasureHeight(string st, Font ft) => (int)nullGraphics.MeasureString(st, ft).Height; 105 | 106 | public static bool IsShiftPressed() => (Form1.ModifierKeys & Keys.Shift) == Keys.Shift; 107 | public static bool IsCapsPressed() => (Form1.ModifierKeys & Keys.CapsLock) == Keys.CapsLock; 108 | public static bool IsAltlPressed() => (Form1.ModifierKeys & Keys.Alt) == Keys.Alt; 109 | public static bool IsCtrlPressed() => (Form1.ModifierKeys & Keys.Control) == Keys.Control; 110 | 111 | public static bool IsBefore((int line, int col) one, (int line, int col) two) { 112 | return one.line < two.line || (one.line == two.line && one.col < two.col); 113 | } 114 | public static bool InBetween((int line, int col) cur, (int line, int col) one, (int line, int col) two) { 115 | var (first, last) = IsBefore(one, two) ? (one, two) : (two, one); 116 | return IsBefore(cur, last) && IsBefore(first, cur); 117 | } 118 | 119 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GraphicIDE 2 | 3 | At the dawn of time, cavemen wrote their programs using TextUserInterface IDEs, which displayed their code in black and white (much like the rest of the world back then). 4 | As humanity evolved, we got GraphicUserInterface IDEs and more importantly, ***Syntax Highlighting***. 5 | Not only do we get to pretend to be artists while programming, syntax highlighting also makes code a lot easier to understand at a glance, and in turn makes programming a lot easier. 6 | 7 | So now I pose the question - What's next? Is syntax highlighting the best we'll ever get or can we continue to evolve? 8 | No, I don't think Scratch is the answer. (I do however think it's a great tool for learning) 9 | 10 | So I did the only logical step: 11 | 12 | black & white -> colors -> Pictures! 13 | 14 | What if instead of making my text colorful it turned it into pictures? 15 | 16 | Boring: 17 | 18 | ![plot](./Pics/BlackAndWhiteEx1.png) 19 | 20 | Normal: 21 | 22 | ![plot](./Pics/ColorfulEx1.png) 23 | 24 | Better?: 25 | 26 | ![plot](./Pics/PicEx1.png) 27 | 28 | 29 | So I made a Python IDE which transforms your code into pictures for it to be easier to read at a glance (and some other features I feel are missing in other IDEs). 30 | 31 | Why? 32 | 33 | * It's a fun and interesting project 34 | * I wanted to open this door and see where it might lead, maybe there is some in between sweet spot 35 | * I think this might be good for making visualizations or maybe teaching? 36 | * I like pictures more than colorful text 37 | * I was bored... 38 | 39 | 40 | I've decided to make this project mainly as a proof of concept and to see if it's actually plausible. So as of now, in my opinion, it's a bit over the top. Since it's a proof of concept, many of the things are not completely polished. 41 | 42 | Please keep these things in mind while looking at the project. 43 | 44 | 45 | 46 | 47 | # Examples 48 | 49 | ### Assignment 50 | ![plot](./Pics/Assignment.png) 51 | 52 | ### Math 53 | ![plot](./Pics/math.png) 54 | 55 | ### If Elif Else 56 | ![plot](./Pics/if-else-elif.png) 57 | 58 | ### While 59 | ![plot](./Pics/while.png) 60 | 61 | ### For 62 | ![plot](./Pics/for.png) 63 | 64 | ### Imports 65 | ![plot](./Pics/imports.png) 66 | 67 | ### Iterables 68 | ![plot](./Pics/iterables.png) 69 | 70 | ### Break Continue 71 | ![plot](./Pics/break-continue.png) 72 | 73 | The color before the break\continue indicates which loop it corresponds to 74 | 75 | ### Short If Else 76 | ![plot](./Pics/short-if-else.png) 77 | 78 | ### Print, Return, None 79 | ![plot](./Pics/print-return-None.png) 80 | 81 | ### Comprehension 82 | ![plot](./Pics/comprehension.png) 83 | 84 | ### Lambda 85 | ![plot](./Pics/lambda.png) 86 | 87 | ### Some Built-in Functions 88 | ![plot](./Pics/funcs.png) 89 | 90 | 91 | 92 | ## Guessing game 93 | ![plot](./Pics/GuessingGameText.png) 94 | ![plot](./Pics/GuessingGamePic.png) 95 | 96 | 97 | ## Random (just to show the graphics) 98 | ![plot](./Pics/BigExampleText.png) 99 | ![plot](./Pics/BigExamplePic.png) 100 | 101 | 102 | 103 | I found that having it turn your code into pictures as you're typing was confusing and annoying (also hard to program) so instead I opted for a simpler solution - Each function will go in it's own tab, the tab you're editing will be displayed normally but the other tabs will be displayed as pictures (you can also toggle the current tab between text and picture by pressing *insert*). 104 | 105 | 106 | 107 | 108 | # The Rest of the IDE 109 | 110 | Now that you've seen most of the graphics let's move on to the rest of the IDE. 111 | I decided to not use the built in textbox but rather make my own from scratch. You might wonder - Why?? 112 | 113 | * At the start I was making it display the pictures as you typed, and since you can't have both text and pictures in a text box I needed to make my own. 114 | 115 | * I was always interested in how textboxes work, so instead of researching it like a normal person I just made my own. 116 | 117 | 118 | So I had to program everything - typing, moving the caret, cut/copy/paste, ctrl z/y, selecting with the mouse, scrolling, and much much more. Or in other words, don't be too surprised if something doesn't work properly... 119 | 120 | 121 | 122 | ## Exceptions 123 | I know this probably has never happened to you but sometimes when you run your code, you are greeted with an exception, such as ```ZeroDivisionError: division by zero``` 124 | 125 | Now the obvious next step is to Google the exception, to make this *agonizing* task simpler I've made a button which will do just that for you. 126 | 127 | ![plot](./Pics/Search.png) 128 | 129 | 130 | 131 | ## Basic functionalities 132 | I've also added the basic features of any IDE, which you can access with the buttons at the top right: 133 | 134 | ![plot](./Pics/ButtonsTop.png) 135 | 136 | open file [ctrl + O], save [ctrl + S], delete tab (and the function), rename function [ctrl + R], add function [ctrl + N], settings (right now only has lightmode), run [ctrl + Space or middleMouseButton] 137 | 138 | 139 | 140 | ## Timer 141 | There is a nice little timer at the bottom which will tell you how long your code took to execute. If this bothers you you can simply click on it to hide it. 142 | 143 | 144 | 145 | ## Right Click 146 | If you right click you will find this little menu: 147 | 148 | ![plot](./Pics/RightClick.png) 149 | 150 | (from top left to right) Copy [Ctrl + C], Paste [Ctrl + V], Run, Search (will Google whatever you have selected), Cmd (opens the cmd), Rename (!DOESN'T WORK YET!) 151 | 152 | To close it just click anywhere else 153 | 154 | 155 | 156 | ## Predictions 157 | As you code you will be offered predictions (which as of now are pretty terrible). 158 | To accept them press Tab. 159 | To select a different one use up/down arrow keys. 160 | To ignore just keep typing or use left/right arrow keys. 161 | 162 | 163 | 164 | ## Other Shortcuts 165 | Duplicate [Ctrl + D] 166 | Cut [Ctrl + X] 167 | Select All [Ctrl + A] 168 | Undo [Ctrl + Z] 169 | Redo [Ctrl + Y] 170 | Toggle Console [Ctrl + ~] 171 | Make Font Bigger [Ctrl + +] 172 | Make Font Smaller [Ctrl + -] 173 | Comment out chunk [Ctrl + /] 174 | 175 | 176 | # Usage 177 | Download the latest release from the releases tab and run the exe. 178 | 179 | Make sure you have Python installed on your computer. 180 | 181 | The screen should be split into two, on the left is .Main this is the part of your program which will be run, on the right side there is func() this is an example function you can write. No need to write: 182 | ```python 183 | def func(): 184 | ``` 185 | or indent in the functions. 186 | You can now write your program in .Main and for any function just make a new Tab and write it there. 187 | 188 | The reason you aren't seeing pictures but rather just normal text is because the tab you are focused on shows text as to not be annoying to write. To get it to display pictures either click on a different tab (the one on the right) or press `insert` 189 | 190 | Finally run the program, it might ask you to save it first. 191 | 192 | 193 | # Missing Features (coming soon?) 194 | 195 | In no particular order: 196 | 197 | Make it work on linux\mac cuz as of now it only works on windows (I think) 198 | 199 | Auto save 200 | 201 | Scroll horizontal 202 | 203 | Refactoring 204 | 205 | Being able to stop execution 206 | 207 | Debugger 208 | 209 | Comments, and even letting you make little drawings in the comments 210 | 211 | A file system 212 | 213 | Syntax Highlighting for the text 214 | 215 | ### missing python features 216 | 217 | classes, annotations, decorators, generators, del, global, assert, yield\yeild from, with, try-catch-else-finally, raise, else clause on for-loop, f-strings, * operator, and probably other things I forgot about 218 | 219 | And a bunch of builtin functions that don't have special pictures yet -------------------------------------------------------------------------------- /GraphicIDE/Classes/DrawScreen.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class DrawScreen{ 4 | public const int WINDOW_LEFT_GAP = 6; 5 | public static bool skipDrawNewScreen = false; 6 | private static readonly Font titleFont = new(FontFamily.GenericMonospace, 35, FontStyle.Bold); 7 | public static void DrawPicScreen() { 8 | if(curFunc.isPic) { 9 | DrawTextScreen(); 10 | nonStatic.Invalidate(); 11 | curFunc.isPic = false; 12 | } else { 13 | try { 14 | loopColors.pos = 0; 15 | var bm_ = MakeImg(PythonFuncs.ToAST()); 16 | 17 | if(bm_ is BM_Middle bm) { 18 | bm.Img = new(bm.Img, (int)(bm.Img.Width * imgSize), (int)(bm.Img.Height * imgSize)); 19 | if(!curFunc.name.StartsWith(".")){ 20 | int w = MeasureWidth(curFunc.name, titleFont); 21 | int h = MeasureHeight(curFunc.name, titleFont); 22 | Bitmap newBm = new(Max(bm.Img.Width, w), bm.Img.Height + h); 23 | using(var g = Graphics.FromImage(newBm)){ 24 | g.DrawImage(bm.Img, 0, h); 25 | g.DrawString(curFunc.name, titleFont, titleBrush, 0, 0); 26 | } 27 | bm = new(newBm, 0); 28 | } 29 | #region resize to fit screen 30 | if(bm.Img.Height > curWindow.size.height || bm.Img.Width > curWindow.size.width){ 31 | (float newWidth, float newHeight) = (bm.Img.Width, bm.Img.Height); 32 | if(newWidth > curWindow.size.width - 2 * WINDOW_LEFT_GAP){ 33 | newWidth = curWindow.size.width - 2 * WINDOW_LEFT_GAP; 34 | newHeight /= (bm.Img.Width / newWidth); 35 | } 36 | if(newHeight > curWindow.size.height - TAB_HEIGHT){ 37 | newHeight = curWindow.size.height - TAB_HEIGHT; 38 | newWidth /= (bm.Img.Height / newHeight); 39 | } 40 | bm = new(new(bm.Img, (int)newWidth, (int)newHeight), 0); 41 | } 42 | #endregion 43 | 44 | curFunc.displayImage = bm.Img; 45 | skipDrawNewScreen = true; 46 | nonStatic.Invalidate(); 47 | curFunc.isPic = true; 48 | } 49 | } catch (Exception){} 50 | } 51 | } 52 | public static void DrawTextScreen(bool withCurser = true) { 53 | if(skipDrawNewScreen) { 54 | skipDrawNewScreen = false; 55 | return; 56 | } 57 | curFunc.isPic = false; 58 | 59 | LinkedList bitmaps = new(); 60 | int totalWidth = 0; 61 | int end = 0; 62 | for(int i = 0; i < linesText.Count; i++) { 63 | var lineText = linesText[i]; 64 | int width = MeasureWidth(lineText, boldFont); 65 | totalWidth = Max(totalWidth, width); 66 | 67 | Bitmap bm = new(width, txtHeight); 68 | var g = Graphics.FromImage(bm); 69 | g.DrawString(lineText, boldFont, curTextBrush, 0, 0); 70 | 71 | if(i == CursorPos.line && withCurser) { 72 | var before = CursorPos.col == -1 ? "": linesText[i][..(CursorPos.col + 1)]; 73 | g.FillRectangle( 74 | curserBrush, 75 | MeasureWidth(before, boldFont) - 3, 76 | txtHeight/5, 1, txtHeight/5*3 77 | ); 78 | } 79 | 80 | if(selectedLine is (int, int) sl && withCurser) { 81 | if((i < sl.line && i > CursorPos.line) || (i > sl.line && i < CursorPos.line)) { 82 | g.FillRectangle( 83 | selectBrush, 0, 0, 84 | MeasureWidth(lineText, boldFont), txtHeight 85 | ); 86 | } else if(i == sl.line || i == CursorPos.line) { 87 | int cCol = CursorPos.col, sCol = sl.col; 88 | if(i == sl.line) { 89 | cCol = i == CursorPos.line ? CursorPos.col : (i > CursorPos.line ? -1 : lineText.Length - 1); 90 | } else { 91 | sCol = i > sl.line ? -1 : lineText.Length - 1; 92 | } 93 | var (smaller, bigger) = cCol < sCol ? (cCol, sCol) : (sCol, cCol); 94 | var startS = smaller == -1 ? 0 : MeasureWidth(linesText[i][..(smaller + 1)], boldFont); 95 | 96 | var endS = MeasureWidth(linesText[i][..Min(linesText[i].Length, bigger + 1)], boldFont); 97 | g.FillRectangle(selectBrush, startS, 0, endS - startS, txtHeight); 98 | } 99 | } 100 | end += bm.Height; 101 | bitmaps.AddLast(bm); 102 | } 103 | Bitmap newBitMap = new(Min(totalWidth, (int)curWindow.size.width - WINDOW_LEFT_GAP * 2), end); 104 | var gr = Graphics.FromImage(newBitMap); 105 | end = 0; 106 | foreach(var item in bitmaps) { 107 | gr.DrawImage(item, 0, end); 108 | end += item.Height; 109 | } 110 | newBitMap = new(newBitMap, (int)(newBitMap.Width * imgSize), (int)(newBitMap.Height * imgSize)); 111 | curFunc.displayImage = newBitMap; 112 | } 113 | public static void Form1_Paint(object? sender, PaintEventArgs e) { 114 | foreach(var window in windows.AsEnumerable().Reverse()) { 115 | var itemHeight = (int)window.size.height - TAB_HEIGHT; 116 | var drawPosY = window.pos.y + TAB_HEIGHT; 117 | if(window.function.name.Equals(".console")){ 118 | itemHeight = (int)window.size.height; 119 | drawPosY = window.pos.y; 120 | } 121 | if((int)window.size.width > 0 && itemHeight > 0){ 122 | // ? draw the img 123 | Bitmap bm = new((int)window.size.width, itemHeight); 124 | using(var g = Graphics.FromImage(bm)){ 125 | g.Clear(Color.Black); // ? make back black 126 | Bitmap img = window.function.displayImage!; 127 | if(window.function.isPic){ 128 | g.DrawImage(img, bm.Width/2-img.Width/2, 0); 129 | } else { 130 | g.DrawImage(img, 0, window.offset); 131 | } 132 | } 133 | e.Graphics.DrawImage(bm, window.pos.x + WINDOW_LEFT_GAP, drawPosY); 134 | // ? draw frame 135 | e.Graphics.DrawRectangle(new(Color.White, 2), window.pos.x-2, window.pos.y-2, window.size.width+2, window.size.height+2); 136 | } 137 | } 138 | // ? prompt 139 | if(visablePrompt is Prompt p){ 140 | e.Graphics.DrawImage( 141 | p.bm, 142 | (int)(screenWidth / 2 - p.bm.Width / 2), 143 | (int)(screenHeight / 2 - p.bm.Height + p.tb.Height / 2 + 20) 144 | ); 145 | } 146 | // ? prediction display 147 | if(predictionMenu is (Bitmap, string[]) pm){ 148 | e.Graphics.DrawImage( 149 | pm.bm, 150 | curWindow.pos.x + WINDOW_LEFT_GAP + MeasureWidth(linesText[CursorPos.line][..(CursorPos.col+1)], boldFont), 151 | curWindow.pos.y + TAB_HEIGHT + txtHeight * CursorPos.line 152 | ); 153 | } 154 | 155 | // ? right click menu 156 | foreach(var menu in visibleMenues) { 157 | e.Graphics.FillRectangle(menu.bgColor, menu.bgPos); 158 | } 159 | // ? tab bar 160 | e.Graphics.FillRectangle(tabBarBrush, 0, 0, screenWidth, TAB_HEIGHT); 161 | } 162 | } -------------------------------------------------------------------------------- /GraphicIDE/Classes/Console.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | public static class Console { 3 | public static (string txt, ConsoleTxtType typ)[] consoleTxt = new[]{("", ConsoleTxtType.text)}; 4 | public static Window console = null!; 5 | public static string executedTime = "-------"; 6 | public static bool isConsoleVisible = false; 7 | public static Button? closeConsoleBtn, openConsoleBtn, errOpenButton, execTimeBtn; 8 | public static readonly Func<(int w, int h), Point> 9 | ETBCalcPos = (size) => new(size.w - execTimeBtn!.Width - 35 /*open console btn size*/ - 20, size.h - execTimeBtn!.Height - 5), 10 | CCBCalcPos = (_) => new((int)(console.pos.x + console.size.width) - closeConsoleBtn!.Width - 10, (int)console.pos.y + 10), 11 | EOBCalcPos = (_) => new((int)(console.pos.x + console.size.width) - errOpenButton!.Width - 10, (int)console.pos.y + 40), 12 | OCBCalcPos = (size) => new(size.w - openConsoleBtn!.Width - 10, size.h - openConsoleBtn.Height - 5); 13 | 14 | public static void ShowConsole() { 15 | int idx = nonStatic.Controls.IndexOf(openConsoleBtn); 16 | if(idx != -1) { 17 | buttonsOnScreen.Remove(buttonsOnScreen.Find((x)=>x.btn.Equals(openConsoleBtn!))); 18 | nonStatic.Controls[idx].Dispose(); 19 | } 20 | openConsoleBtn = null; 21 | 22 | var (height, width) = (screenHeight, screenWidth); 23 | 24 | int consolePos = height - (height / 4); 25 | console.pos.y = consolePos; 26 | console.size.height = height - consolePos; 27 | console.size.width = width; 28 | Bitmap img = new(width, height); 29 | using(var g = Graphics.FromImage(img)) { 30 | int end = 5; 31 | console.function.linesText = new(); 32 | foreach(var item in consoleTxt) { 33 | console.function.linesText.AddRange(item.txt.Split('\n')); 34 | if(item.typ == ConsoleTxtType.text) { 35 | g.DrawString(item.txt, boldFont, textBrush, 0, end); 36 | end += MeasureHeight(item.txt, boldFont); 37 | if(errOpenButton is not null) { 38 | buttonsOnScreen.Remove(buttonsOnScreen.Find((x)=>x.btn.Equals(errOpenButton))); 39 | nonStatic.Controls[nonStatic.Controls.IndexOf(errOpenButton)].Dispose(); 40 | errOpenButton = null; 41 | } 42 | } else { 43 | g.DrawString(item.txt, boldFont, redBrush, 0, end); 44 | end += MeasureHeight(item.txt, boldFont); 45 | if(errOpenButton is null) { 46 | errOpenButton = new() { 47 | Size = new(20, 20), 48 | BackColor = Color.Transparent, 49 | BackgroundImage = searchImg, 50 | FlatStyle = FlatStyle.Flat, 51 | BackgroundImageLayout = ImageLayout.Zoom, 52 | }; 53 | errOpenButton.Location = EOBCalcPos((0, 0)); 54 | errOpenButton.FlatAppearance.BorderSize = 0; 55 | errOpenButton.FlatAppearance.BorderColor = Color.White; 56 | errOpenButton.FlatAppearance.MouseOverBackColor = lightGray; 57 | errOpenButton.Click += new EventHandler(OpenErrLink!); 58 | nonStatic.Controls.Add(errOpenButton); 59 | buttonsOnScreen.Add((errOpenButton, EOBCalcPos)); 60 | toolTip.SetToolTip(errOpenButton, "Google exception"); 61 | } 62 | } 63 | } 64 | } 65 | console.function.displayImage = img; 66 | isConsoleVisible = true; 67 | 68 | if(closeConsoleBtn is null) { 69 | closeConsoleBtn = new() { 70 | Size = new(20, 20), 71 | BackColor = Color.Transparent, 72 | BackgroundImage = xImg, 73 | FlatStyle = FlatStyle.Flat, 74 | BackgroundImageLayout = ImageLayout.Zoom, 75 | }; 76 | closeConsoleBtn.Location = CCBCalcPos((0, 0)); 77 | closeConsoleBtn.FlatAppearance.BorderSize = 0; 78 | closeConsoleBtn.FlatAppearance.BorderColor = Color.White; 79 | closeConsoleBtn.FlatAppearance.MouseOverBackColor = lightGray; 80 | closeConsoleBtn.Click += new EventHandler(HideConsole!); 81 | nonStatic.Controls.Add(closeConsoleBtn); 82 | buttonsOnScreen.Add((closeConsoleBtn, CCBCalcPos)); 83 | toolTip.SetToolTip(closeConsoleBtn, "close console"); 84 | } 85 | if(!windows[0].Equals(console)){ 86 | windows.Add(windows[0]); windows[0] = console; 87 | } 88 | nonStatic.Invalidate(); 89 | } 90 | public static void HideConsole(object? sender, EventArgs e) { 91 | isConsoleVisible = false; 92 | int idx = nonStatic.Controls.IndexOf(closeConsoleBtn); 93 | if(idx != -1) { 94 | buttonsOnScreen.Remove(buttonsOnScreen.Find((x)=>x.btn.Equals(closeConsoleBtn!))); 95 | nonStatic.Controls[idx].Dispose(); 96 | } 97 | closeConsoleBtn = null; 98 | idx = nonStatic.Controls.IndexOf(errOpenButton); 99 | if(idx != -1) { 100 | buttonsOnScreen.Remove(buttonsOnScreen.Find((x)=>x.btn.Equals(errOpenButton!))); 101 | nonStatic.Controls[idx].Dispose(); 102 | } 103 | errOpenButton = null; 104 | 105 | if(openConsoleBtn is null) { 106 | MakeOpenConsoleBtn(); 107 | } 108 | windows.Remove(console); 109 | nonStatic.Invalidate(); 110 | } 111 | public static void MakeOpenConsoleBtn() { 112 | openConsoleBtn = new() { 113 | Size = new(35, 35), 114 | BackColor = Color.Transparent, 115 | BackgroundImage = consoleImg, 116 | FlatStyle = FlatStyle.Flat, 117 | BackgroundImageLayout = ImageLayout.Zoom, 118 | }; 119 | openConsoleBtn.Location = OCBCalcPos((screenWidth, screenHeight)); 120 | openConsoleBtn.FlatAppearance.BorderSize = 0; 121 | openConsoleBtn.FlatAppearance.BorderColor = Color.White; 122 | openConsoleBtn.FlatAppearance.MouseOverBackColor = lightGray; 123 | openConsoleBtn.Click += new EventHandler((object? s, EventArgs e) => ShowConsole()); 124 | nonStatic.Controls.Add(openConsoleBtn); 125 | buttonsOnScreen.Add((openConsoleBtn, OCBCalcPos)); 126 | toolTip.SetToolTip(openConsoleBtn, "open console"); 127 | } 128 | public static void RefreshTimeBtn(){ 129 | int h = MeasureHeight(executedTime, boldFont); 130 | int w = MeasureWidth(executedTime, boldFont); 131 | Bitmap bm = new(w, h); 132 | using(var g = Graphics.FromImage(bm)){ 133 | g.DrawString(executedTime, boldFont, timeBrush, 0, 0); 134 | } 135 | execTimeBtn!.Size = new(w, h); 136 | execTimeBtn!.Location = ETBCalcPos((screenWidth, screenHeight)); 137 | execTimeBtn!.BackgroundImage = bm; 138 | } 139 | public static void ToggleTimeBtn(){ 140 | if(execTimeBtn!.BackgroundImage is null){ 141 | RefreshTimeBtn(); 142 | } else { 143 | execTimeBtn!.BackgroundImage = null; 144 | } 145 | } 146 | public static void ToggleConsole() { 147 | if(isConsoleVisible) { HideConsole(null, new()); } else { ShowConsole(); } 148 | } 149 | public static void RefreshConsole() { 150 | if(isConsoleVisible) { ShowConsole(); } else { HideConsole(null, new()); } 151 | } 152 | 153 | public static void OpenErrLink(object? sender, EventArgs e) { 154 | if(PythonFuncs.errLink is not null) { 155 | Process.Start(new ProcessStartInfo("cmd", $"/c start {PythonFuncs.errLink}") { CreateNoWindow = true }); 156 | } 157 | } 158 | } 159 | public enum ConsoleTxtType { text, error } 160 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | launch.json 6 | tasks.json 7 | # User-specific files 8 | *.rsuser 9 | *.suo 10 | *.user 11 | *.userosscache 12 | *.sln.docstates 13 | 14 | # User-specific files (MonoDevelop/Xamarin Studio) 15 | *.userprefs 16 | 17 | # Mono auto generated files 18 | mono_crash.* 19 | 20 | # Build results 21 | [Dd]ebug/ 22 | [Dd]ebugPublic/ 23 | [Rr]elease/ 24 | [Rr]eleases/ 25 | x64/ 26 | x86/ 27 | [Ww][Ii][Nn]32/ 28 | [Aa][Rr][Mm]/ 29 | [Aa][Rr][Mm]64/ 30 | bld/ 31 | [Bb]in/ 32 | [Oo]bj/ 33 | [Oo]ut/ 34 | [Ll]og/ 35 | [Ll]ogs/ 36 | 37 | # Visual Studio 2015/2017 cache/options directory 38 | .vs/ 39 | # Uncomment if you have tasks that create the project's static files in wwwroot 40 | #wwwroot/ 41 | 42 | # Visual Studio 2017 auto generated files 43 | Generated\ Files/ 44 | 45 | # MSTest test Results 46 | [Tt]est[Rr]esult*/ 47 | [Bb]uild[Ll]og.* 48 | 49 | # NUnit 50 | *.VisualState.xml 51 | TestResult.xml 52 | nunit-*.xml 53 | 54 | # Build Results of an ATL Project 55 | [Dd]ebugPS/ 56 | [Rr]eleasePS/ 57 | dlldata.c 58 | 59 | # Benchmark Results 60 | BenchmarkDotNet.Artifacts/ 61 | 62 | # .NET Core 63 | project.lock.json 64 | project.fragment.lock.json 65 | artifacts/ 66 | 67 | # ASP.NET Scaffolding 68 | ScaffoldingReadMe.txt 69 | 70 | # StyleCop 71 | StyleCopReport.xml 72 | 73 | # Files built by Visual Studio 74 | *_i.c 75 | *_p.c 76 | *_h.h 77 | *.ilk 78 | *.meta 79 | *.obj 80 | *.iobj 81 | *.pch 82 | *.pdb 83 | *.ipdb 84 | *.pgc 85 | *.pgd 86 | *.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *_wpftmp.csproj 94 | *.log 95 | *.vspscc 96 | *.vssscc 97 | .builds 98 | *.pidb 99 | *.svclog 100 | *.scc 101 | 102 | # Chutzpah Test files 103 | _Chutzpah* 104 | 105 | # Visual C++ cache files 106 | ipch/ 107 | *.aps 108 | *.ncb 109 | *.opendb 110 | *.opensdf 111 | *.sdf 112 | *.cachefile 113 | *.VC.db 114 | *.VC.VC.opendb 115 | 116 | # Visual Studio profiler 117 | *.psess 118 | *.vsp 119 | *.vspx 120 | *.sap 121 | 122 | # Visual Studio Trace Files 123 | *.e2e 124 | 125 | # TFS 2012 Local Workspace 126 | $tf/ 127 | 128 | # Guidance Automation Toolkit 129 | *.gpState 130 | 131 | # ReSharper is a .NET coding add-in 132 | _ReSharper*/ 133 | *.[Rr]e[Ss]harper 134 | *.DotSettings.user 135 | 136 | # TeamCity is a build add-in 137 | _TeamCity* 138 | 139 | # DotCover is a Code Coverage Tool 140 | *.dotCover 141 | 142 | # AxoCover is a Code Coverage Tool 143 | .axoCover/* 144 | !.axoCover/settings.json 145 | 146 | # Coverlet is a free, cross platform Code Coverage Tool 147 | coverage*.json 148 | coverage*.xml 149 | coverage*.info 150 | 151 | # Visual Studio code coverage results 152 | *.coverage 153 | *.coveragexml 154 | 155 | # NCrunch 156 | _NCrunch_* 157 | .*crunch*.local.xml 158 | nCrunchTemp_* 159 | 160 | # MightyMoose 161 | *.mm.* 162 | AutoTest.Net/ 163 | 164 | # Web workbench (sass) 165 | .sass-cache/ 166 | 167 | # Installshield output folder 168 | [Ee]xpress/ 169 | 170 | # DocProject is a documentation generator add-in 171 | DocProject/buildhelp/ 172 | DocProject/Help/*.HxT 173 | DocProject/Help/*.HxC 174 | DocProject/Help/*.hhc 175 | DocProject/Help/*.hhk 176 | DocProject/Help/*.hhp 177 | DocProject/Help/Html2 178 | DocProject/Help/html 179 | 180 | # Click-Once directory 181 | publish/ 182 | 183 | # Publish Web Output 184 | *.[Pp]ublish.xml 185 | *.azurePubxml 186 | # Note: Comment the next line if you want to checkin your web deploy settings, 187 | # but database connection strings (with potential passwords) will be unencrypted 188 | *.pubxml 189 | *.publishproj 190 | 191 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 192 | # checkin your Azure Web App publish settings, but sensitive information contained 193 | # in these scripts will be unencrypted 194 | PublishScripts/ 195 | 196 | # NuGet Packages 197 | *.nupkg 198 | # NuGet Symbol Packages 199 | *.snupkg 200 | # The packages folder can be ignored because of Package Restore 201 | **/[Pp]ackages/* 202 | # except build/, which is used as an MSBuild target. 203 | !**/[Pp]ackages/build/ 204 | # Uncomment if necessary however generally it will be regenerated when needed 205 | #!**/[Pp]ackages/repositories.config 206 | # NuGet v3's project.json files produces more ignorable files 207 | *.nuget.props 208 | *.nuget.targets 209 | 210 | # Microsoft Azure Build Output 211 | csx/ 212 | *.build.csdef 213 | 214 | # Microsoft Azure Emulator 215 | ecf/ 216 | rcf/ 217 | 218 | # Windows Store app package directories and files 219 | AppPackages/ 220 | BundleArtifacts/ 221 | Package.StoreAssociation.xml 222 | _pkginfo.txt 223 | *.appx 224 | *.appxbundle 225 | *.appxupload 226 | 227 | # Visual Studio cache files 228 | # files ending in .cache can be ignored 229 | *.[Cc]ache 230 | # but keep track of directories ending in .cache 231 | !?*.[Cc]ache/ 232 | 233 | # Others 234 | # ClientBin/ 235 | ~$* 236 | *~ 237 | *.dbmdl 238 | *.dbproj.schemaview 239 | *.jfm 240 | *.pfx 241 | *.publishsettings 242 | orleans.codegen.cs 243 | 244 | # Including strong name files can present a security risk 245 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 246 | #*.snk 247 | 248 | # Since there are multiple workflows, uncomment next line to ignore bower_components 249 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 250 | #bower_components/ 251 | 252 | # RIA/Silverlight projects 253 | Generated_Code/ 254 | 255 | # Backup & report files from converting an old project file 256 | # to a newer Visual Studio version. Backup files are not needed, 257 | # because we have git ;-) 258 | _UpgradeReport_Files/ 259 | Backup*/ 260 | UpgradeLog*.XML 261 | UpgradeLog*.htm 262 | ServiceFabricBackup/ 263 | *.rptproj.bak 264 | 265 | # SQL Server files 266 | *.mdf 267 | *.ldf 268 | *.ndf 269 | 270 | # Business Intelligence projects 271 | *.rdl.data 272 | *.bim.layout 273 | *.bim_*.settings 274 | *.rptproj.rsuser 275 | *- [Bb]ackup.rdl 276 | *- [Bb]ackup ([0-9]).rdl 277 | *- [Bb]ackup ([0-9][0-9]).rdl 278 | 279 | # Microsoft Fakes 280 | FakesAssemblies/ 281 | 282 | # GhostDoc plugin setting file 283 | *.GhostDoc.xml 284 | 285 | # Node.js Tools for Visual Studio 286 | .ntvs_analysis.dat 287 | node_modules/ 288 | 289 | # Visual Studio 6 build log 290 | *.plg 291 | 292 | # Visual Studio 6 workspace options file 293 | *.opt 294 | 295 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 296 | *.vbw 297 | 298 | # Visual Studio LightSwitch build output 299 | **/*.HTMLClient/GeneratedArtifacts 300 | **/*.DesktopClient/GeneratedArtifacts 301 | **/*.DesktopClient/ModelManifest.xml 302 | **/*.Server/GeneratedArtifacts 303 | **/*.Server/ModelManifest.xml 304 | _Pvt_Extensions 305 | 306 | # Paket dependency manager 307 | .paket/paket.exe 308 | paket-files/ 309 | 310 | # FAKE - F# Make 311 | .fake/ 312 | 313 | # CodeRush personal settings 314 | .cr/personal 315 | 316 | # Python Tools for Visual Studio (PTVS) 317 | __pycache__/ 318 | *.pyc 319 | 320 | # Cake - Uncomment if you are using it 321 | # tools/** 322 | # !tools/packages.config 323 | 324 | # Tabs Studio 325 | *.tss 326 | 327 | # Telerik's JustMock configuration file 328 | *.jmconfig 329 | 330 | # BizTalk build output 331 | *.btp.cs 332 | *.btm.cs 333 | *.odx.cs 334 | *.xsd.cs 335 | 336 | # OpenCover UI analysis results 337 | OpenCover/ 338 | 339 | # Azure Stream Analytics local run output 340 | ASALocalRun/ 341 | 342 | # MSBuild Binary and Structured Log 343 | *.binlog 344 | 345 | # NVidia Nsight GPU debugger configuration file 346 | *.nvuser 347 | 348 | # MFractors (Xamarin productivity tool) working folder 349 | .mfractor/ 350 | 351 | # Local History for Visual Studio 352 | .localhistory/ 353 | 354 | # BeatPulse healthcheck temp database 355 | healthchecksdb 356 | 357 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 358 | MigrationBackup/ 359 | 360 | # Ionide (cross platform F# VS Code tools) working folder 361 | .ionide/ 362 | 363 | # Fody - auto-generated XML schema 364 | FodyWeavers.xsd -------------------------------------------------------------------------------- /GraphicIDE/Classes/Tabs.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | public static class Tabs { 4 | public const int TAB_HEIGHT = 25, TAB_WIDTH = 80; 5 | public static Font tabFont = new(FontFamily.GenericMonospace, 10, FontStyle.Bold); 6 | public static readonly Dictionary nameToFunc = new(); 7 | public static Prompt? visablePrompt; 8 | public static Function curFunc = null!; 9 | public static Window curWindow = null!; 10 | public static void AddTabEvent(object? sender, EventArgs e) => PromptMakeNewTab(); 11 | private static Button AddTabToWindow(string name, Window window, bool isFirst=false){ 12 | Button btn = new() { 13 | Name = name, 14 | Text = name, 15 | BackColor = lightGray, 16 | Location = new((int)window.pos.x + window. tabsEnd, (int)window.pos.y), 17 | Size = new(TAB_WIDTH, TAB_HEIGHT), 18 | Font = tabFont, 19 | FlatStyle = FlatStyle.Flat, 20 | }; 21 | toolTip.SetToolTip(btn, name); 22 | btn.FlatAppearance.BorderColor = lightGray; 23 | btn.Click += new EventHandler((object? sender, EventArgs e) => ChangeTab(sender!, window)); 24 | 25 | window.tabButtons.Add(btn); 26 | nonStatic.Controls.Add(btn); 27 | window.tabsEnd += btn.Width + 10; 28 | if(window.Equals(curWindow) && !isFirst){ 29 | if(window.selectedTab is not null){ 30 | window.selectedTab.BackColor = window.selectedTab.FlatAppearance.BorderColor = lightGray; 31 | } 32 | btn.BackColor = btn.FlatAppearance.BorderColor = Color.DarkGray; 33 | window.selectedTab = btn; 34 | } 35 | return btn; 36 | } 37 | private static void AddTabSelect(string name, bool isFirst=false){ 38 | foreach(var window in windows) { 39 | if(window.function.name.Equals(".console")){ continue; } 40 | AddTabToWindow(name, window, isFirst); 41 | } 42 | } 43 | public static Window MakeNewWindow(Function func, (int width, int height) size, (int x, int y) pos){ 44 | Window window = new(func) { 45 | size = size, 46 | pos = pos, 47 | }; 48 | curWindow = window; 49 | foreach(var tab in nameToFunc.Keys) { 50 | var btn = AddTabToWindow(tab, window); 51 | if(tab.Equals(func.name)){ 52 | window.selectedTab = btn; 53 | btn.BackColor = btn.FlatAppearance.BorderColor = Color.DarkGray; 54 | } 55 | 56 | } 57 | windows.Add(window); 58 | return window; 59 | } 60 | public static Function NewFunc(string name, bool isfirst=false) { 61 | Function func = new(name); 62 | if(nameToFunc.ContainsKey(name)){ 63 | if(!DeleteFunc(name)){ 64 | return nameToFunc[name]; 65 | } 66 | } 67 | nameToFunc.Add(name, func); 68 | func.displayImage = new(screenWidth, screenHeight); 69 | AddTabSelect(name, isfirst); 70 | if(!isfirst){ ChangeTab(name, curWindow); } 71 | return func; 72 | } 73 | public static bool DeleteFunc(string name){ 74 | if(name.StartsWith(".")){ 75 | MessageBox.Show($"You cannot delete { name }"); 76 | return false; 77 | } 78 | 79 | DialogResult result = MessageBox.Show( 80 | $"Are you sure you want to delete `{ name }`?", 81 | "Warning", MessageBoxButtons.YesNo 82 | ); 83 | if(result == DialogResult.No){ return false; } 84 | 85 | nameToFunc.Remove(name, out var func); 86 | if(func is null){ return false; } 87 | var mainFunc = nameToFunc[".Main"]; 88 | if(func.Equals(curFunc)){ 89 | curFunc = mainFunc; 90 | } 91 | foreach(var window in windows) { 92 | var tabBtn = window.tabButtons.FindIndex((x) => x.Name.Equals(name)); 93 | if(tabBtn != -1){ 94 | var btn = window.tabButtons[tabBtn]; 95 | nonStatic.Controls.Remove(btn); 96 | window.tabButtons.Remove(btn); 97 | for (int i=tabBtn; i < window.tabButtons.Count; i++) { 98 | var otherB = window.tabButtons[i]; 99 | otherB.Location = new(otherB.Location.X - btn.Size.Width - 10, otherB.Location.Y); 100 | } 101 | window.tabsEnd -= btn.Size.Width + 10; 102 | } 103 | if(window.function.name.Equals(name)){ 104 | ChangeTab(window.tabButtons[^1], window); 105 | } 106 | } 107 | return true; 108 | } 109 | public static void ChangeTab(object sender, Window window){ 110 | if(window.selectedTab is not null){ 111 | window.selectedTab.BackColor = window.selectedTab.FlatAppearance.BorderColor = lightGray; 112 | } 113 | var clickedBtn = (Button)sender; 114 | window.selectedTab = clickedBtn; 115 | clickedBtn.BackColor = clickedBtn.FlatAppearance.BorderColor = Color.DarkGray; 116 | 117 | var prevWindow = curWindow; 118 | curWindow = window; 119 | ChangeTab(clickedBtn.Name, prevWindow: prevWindow); 120 | } 121 | public static void ChangeTab(string funcName, Window prevWindow, bool dontDraw=false) { 122 | var func = nameToFunc[funcName]; 123 | if(selectedLine is not null) { 124 | if(!IsShiftPressed()) { 125 | selectedLine = null; 126 | } 127 | } 128 | 129 | curFunc.curLine = CursorPos.line; 130 | curFunc.curCol = CursorPos.col; 131 | var actualWindow = curWindow; 132 | curWindow = prevWindow; 133 | if(!curFunc.isPic && !dontDraw) { DrawPicScreen(); } 134 | if(!curFunc.isPic && !dontDraw) { 135 | try { 136 | DrawTextScreen(false); nonStatic.Invalidate(); 137 | } catch(Exception) { } 138 | } 139 | curWindow = actualWindow; 140 | curTextBrush = curWindow.txtBrush; 141 | curFunc = func; 142 | curWindow.function = func; 143 | linesText = func.linesText; 144 | CursorPos.ChangeLine(func.curLine); 145 | CursorPos.ChangeCol(func.curCol); 146 | skipDrawNewScreen = false; 147 | textBox.Focus(); 148 | 149 | DrawTextScreen(); 150 | nonStatic.Invalidate(); 151 | } 152 | public static Prompt? newTabPrompt; 153 | public static void PromptMakeNewTab() { 154 | if(visablePrompt is not null){ return; } 155 | if(curFunc.name.Equals(".console")){ return; } 156 | 157 | TextBox textBox = new(){ 158 | Size = new(500, 40), 159 | Font = boldFont, 160 | }; 161 | textBox.Location = new( 162 | (int)(screenWidth / 2 - textBox.Width / 2), 163 | (int)(screenHeight / 2 - textBox.Height / 2) 164 | ); 165 | textBox.KeyDown += new KeyEventHandler(EnterNewTab!); 166 | nonStatic.Controls.Add(textBox); 167 | textBox.Focus(); 168 | 169 | var title = "New function:"; 170 | var titleW = MeasureWidth(title, boldFont); 171 | var titleH = MeasureHeight(title, boldFont); 172 | Bitmap bm = new(Max(textBox.Width, titleW) + 40, textBox.Height + titleH + 60); 173 | using(var g = Graphics.FromImage(bm)){ 174 | g.Clear(Color.LightGray); 175 | g.DrawString(title, boldFont, blackBrush, (int)(bm.Width / 2 - titleW / 2), 20); 176 | } 177 | 178 | Func<(int w, int h), Point> getPos = (size) => new( 179 | (int)(screenWidth / 2 + bm.Width / 2 - 40), 180 | (int)(screenHeight / 2 - bm.Height + textBox.Height / 2 + 30) 181 | ); 182 | Button cancel = MakeButton(30, 30, xImg, streatch: true); 183 | cancel.Location = getPos((screenWidth, screenHeight)); 184 | cancel.Click += new EventHandler((object? s, EventArgs e) => DisposePrompt(ref newTabPrompt)); 185 | buttonsOnScreen.Add((cancel, getPos)); 186 | 187 | visablePrompt = newTabPrompt = new(bm, textBox, cancel); 188 | nonStatic.Invalidate(); 189 | } 190 | private static Regex functionRegex = new(@"^\w+\s*\(\s*(\w+(\s*,\s*\w+)*\s*)?\)$", RegexOptions.Compiled); 191 | public static void EnterNewTab(object sender, KeyEventArgs e) { 192 | if(e.KeyCode == Keys.Enter) { 193 | var name = ((TextBox)sender).Text; 194 | if(!functionRegex.IsMatch(name)){ 195 | MessageBox.Show($"Function name is not valid"); 196 | return; 197 | } 198 | var func = NewFunc(name); 199 | curWindow.function = func; 200 | DisposePrompt(ref newTabPrompt); 201 | } else if(e.KeyCode == Keys.Escape) { 202 | DisposePrompt(ref newTabPrompt); 203 | } 204 | } 205 | public static Prompt? renamePrompt; 206 | public static void PromptRenameTab(){ 207 | if(visablePrompt is not null){ return; } 208 | if(curFunc.name.StartsWith('.')){ return; } 209 | 210 | TextBox textBox = new(){ 211 | Size = new(500, 40), 212 | Font = boldFont, 213 | }; 214 | textBox.Location = new( 215 | (int)(screenWidth / 2 - textBox.Width / 2), 216 | (int)(screenHeight / 2 - textBox.Height / 2) 217 | ); 218 | textBox.KeyDown += new KeyEventHandler(RenameTab!); 219 | nonStatic.Controls.Add(textBox); 220 | textBox.Focus(); 221 | 222 | var title = $"Rename `{ curFunc.name }` to:"; 223 | var titleW = MeasureWidth(title, boldFont); 224 | var titleH = MeasureHeight(title, boldFont); 225 | Bitmap bm = new(Max(textBox.Width, titleW) + 40, textBox.Height + titleH + 60); 226 | using(var g = Graphics.FromImage(bm)){ 227 | g.Clear(Color.LightGray); 228 | g.DrawString(title, boldFont, blackBrush, (int)(bm.Width / 2 - titleW / 2), 20); 229 | } 230 | 231 | Func<(int w, int h), Point> getPos = (size) => new( 232 | (int)(screenWidth / 2 + bm.Width / 2 - 40), 233 | (int)(screenHeight / 2 - bm.Height + textBox.Height / 2 + 30) 234 | ); 235 | Button cancel = MakeButton(30, 30, xImg, streatch: true); 236 | cancel.Location = getPos((screenWidth, screenHeight)); 237 | cancel.Click += new EventHandler((object? s, EventArgs e) => DisposePrompt(ref renamePrompt)); 238 | buttonsOnScreen.Add((cancel, getPos)); 239 | 240 | visablePrompt = renamePrompt = new(bm, textBox, cancel); 241 | nonStatic.Invalidate(); 242 | } 243 | private static void DisposePrompt(ref Prompt? prompt){ 244 | if(prompt is Prompt rp){ 245 | nonStatic.Controls.Remove(rp.tb); 246 | nonStatic.Controls.Remove(rp.cancel); 247 | buttonsOnScreen.Remove(buttonsOnScreen.Find((x) => x.btn.Equals(rp.cancel))); 248 | prompt = visablePrompt = null; 249 | rp.tb.Dispose(); 250 | rp.bm.Dispose(); 251 | rp.cancel.Dispose(); 252 | nonStatic.Invalidate(); 253 | } 254 | } 255 | public static void RenameTab(object sender, KeyEventArgs e){ 256 | if(e.KeyCode == Keys.Enter) { 257 | var name = renamePrompt!.Value.tb.Text; 258 | if(name.StartsWith(".")){ 259 | MessageBox.Show($"You cannot rename { name }"); 260 | renamePrompt!.Value.tb.Text = ""; 261 | return; 262 | } 263 | DisposePrompt(ref renamePrompt); 264 | nameToFunc.Remove(curFunc.name); 265 | nameToFunc[name] = curFunc; 266 | foreach(var window in windows) { 267 | foreach(var tab in window.tabButtons) { 268 | if(tab.Name.Equals(curFunc.name)){ 269 | tab.Name = name; 270 | tab.Text = name; 271 | } 272 | } 273 | } 274 | curFunc.name = name; 275 | } else if(e.KeyCode == Keys.Escape) { 276 | DisposePrompt(ref renamePrompt); 277 | } 278 | } 279 | } 280 | public record struct Prompt(Bitmap bm, TextBox tb, Button cancel); -------------------------------------------------------------------------------- /GraphicIDE/Classes/Prediction.cs: -------------------------------------------------------------------------------- 1 | namespace GraphicIDE; 2 | 3 | /* 4 | ? **************************************************************** 5 | ? This is a mess that I copied from a different one of my projects 6 | ? For now it works but definetly could use a cleanup... 7 | ? **************************************************************** 8 | */ 9 | 10 | public static class Prediction { 11 | private readonly static HashSet pyKeyWords = new(){ 12 | "and", "try", "with", "yield", "or", "for", "while", "return", "from", 13 | "as", "assert", "del", "pass", "except", "finally", "nonlocal", "global", 14 | "def", "class", "break", "continue", "if", "elif", "else", "else:", "lambda", "import", 15 | "None", "False", "not", "raise", "True", "is", "in", 16 | }; 17 | private readonly static string[] pyBuiltinFunctions = new[]{ 18 | "abs(", "delattr(", "hash(", "memoryview(", "set(", "all(", "dict(", "help(", "min(", "setattr(", 19 | "any(", "dir(", "hex(", "next(", "slice(", "ascii(", "divmod(", "id(", "object(", "sorted(", "bin(", 20 | "enumerate(", "input(", "oct(", "staticmethod(", "bool(", "eval(", "int(", "open(", "str(", 21 | "breakpoint(", "exec(", "isinstance(", "ord(", "sum(", "bytearray(", "filter(", "issubclass(", 22 | "pow(", "super(", "bytes(", "float(", "iter(", "print(", "tuple(", "callable(", "format(", "len(", 23 | "property(", "type(", "chr(", "frozenset(", "list(", "range(", "vars(", "classmethod(", "getattr(", 24 | "locals(", "repr(", "zip(", "compile(", "globals(", "map(", "reversed(", "complex(", 25 | "hasattr(", "max(", "round(" 26 | }, 27 | strBuiltinFunctions = new[]{ 28 | "capitalize(", "casefold(", "center(", "count(", "encode(", "endswith(", "expandtabs(", 29 | "find(", "format(", "format_map(", "index(", "isalnum(", "isalpha(", "isascii(", "isdecimal(", 30 | "isdigit(", "isidentifier(", "islower(", "isnumeric(", "isprintable(", "isspace(", "istitle(", 31 | "isupper(", "join(", "ljust(", "lower(", "lstrip(", "maketrans(", "partition(", "replace(", 32 | "rfind(", "rindex(", "rjust(", "rpartition(", "rsplit(", "rstrip(", "split(", "splitlines(", 33 | "startswith(", "strip(", "swapcase(", "title(", "translate(", "upper(", "zfill" 34 | }, 35 | lstBuiltinFunctions = new[]{ 36 | "append(", "clear(", "copy(", "count(", "extend(", "index(", "insert(", "pop(", 37 | "remove(", "reverse(", "sort" 38 | }, 39 | dictBuiltinFunctions = new[]{ 40 | "clear(", "copy(", "fromkeys(", "get(", "items(", "keys(", "pop(", "popitem(", 41 | "setdefault(", "update(", "values" 42 | }, 43 | setBuiltinFunctions = new[]{ 44 | "add(", "clear(", "copy(", "difference(", "difference_update(", "discard(", 45 | "intersection(", "intersection_update(", "isdisjoint(", "issubset(", "issuperset(", 46 | "pop(", "remove(", "symmetric_difference(", "symmetric_difference_update(", 47 | "union(", "update(" 48 | }; 49 | private static HashSet allKeyWords = new(); 50 | private static readonly Tri 51 | afterSpaceRecomendations = new(null), afterPeriodRecomendations = new(null); 52 | private static readonly Regex variableName = new(@"[a-zA-Z]\w*\(?", RegexOptions.Compiled); 53 | private const string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 54 | private static readonly Func IsStrLitteral = () 55 | => CountTillCursor('\'') % 2 != 0 56 | || CountTillCursor('"') % 2 != 0; 57 | private static readonly Func 58 | IsOpenBracket = (line, col) => col > -1 && linesText[line][col] == '(', 59 | IsPeriod = (line, col) => col > -1 && linesText[line][col] == '.', 60 | IsSpace = (line, col) => col > -1 && linesText[line][col] == ' ', 61 | IsLetter = (line, col) => col > -1 && letters.Contains(linesText[line][col]); 62 | public static void Start(){ 63 | foreach (string item in pyKeyWords){ 64 | if(item.Length > 2){ 65 | afterSpaceRecomendations.AddWord(item); 66 | } 67 | } 68 | foreach (string item in pyBuiltinFunctions ){ afterSpaceRecomendations.AddWord(item); allKeyWords.Add(item); } 69 | foreach (string item in strBuiltinFunctions ){ afterPeriodRecomendations.AddWord(item); allKeyWords.Add(item); } 70 | foreach (string item in lstBuiltinFunctions ){ afterPeriodRecomendations.AddWord(item); allKeyWords.Add(item); } 71 | foreach (string item in dictBuiltinFunctions){ afterPeriodRecomendations.AddWord(item); allKeyWords.Add(item); } 72 | foreach (string item in setBuiltinFunctions ){ afterPeriodRecomendations.AddWord(item); allKeyWords.Add(item); } 73 | foreach (string item in pyKeyWords) { allKeyWords.Add(item); } 74 | } 75 | 76 | private static void PosMinus1(ref int line, ref int col){ 77 | col--; 78 | if(col < -1){ 79 | line--; 80 | col = linesText[line].Length - 1; 81 | } 82 | } 83 | private static int CountTillCursor(char ch){ 84 | int count = 0; 85 | for (int i = 0; i < CursorPos.line; i++){ 86 | count += linesText[i].Count(x => x == ch); 87 | } 88 | return count + linesText[CursorPos.line][..CursorPos.col].Count(x => x == ch); 89 | } 90 | public static (bool period, string? word) GetPreviosWord(int toSkip=0){ 91 | // ? it's a mess, but it works... And I don't really want to write it from scratch... 92 | try{ 93 | if(IsStrLitteral()){ return (false, null); } 94 | (int l, int c) = CursorPos.ToTuple(); 95 | while(IsSpace(l, c)){ PosMinus1(ref l, ref c); } 96 | var end = (l, c); 97 | for(int x=0; x GetAllOptionsFromTree(Tri tree, string? prefix){ 115 | if(prefix is null || prefix.Equals("")){ return new(); } 116 | 117 | LinkedList<(Tri pos, Tri parent, string prefix)> allPosses = new(); 118 | GetAllPrefixes(tree, tree, prefix.ToCharArray(), new(), 0, allPosses); 119 | 120 | LinkedList ll = new(); 121 | foreach (var item in allPosses){ 122 | var (treePos, parent, prfx) = item; 123 | prfx = prfx.Remove(prfx.Length-1); 124 | StringBuilder sb = new(prfx); 125 | GetAllOptionsFromTree(sb, ll, treePos, parent); 126 | } 127 | return ll; 128 | } 129 | private static void GetAllOptionsFromTree(StringBuilder word, LinkedList ll, Tri tree, Tri parent){ 130 | word.Append(tree.Val); 131 | if(tree.IsWord){ 132 | ll.AddLast(word.ToString()); 133 | } 134 | foreach (var val in tree.children.Values){ 135 | GetAllOptionsFromTree(word, ll, val, tree); 136 | } 137 | word.Length--; 138 | } 139 | private static void GetAllPrefixes(Tri parent, Tri pos, char[] prefix, StringBuilder prfx, int i, LinkedList<(Tri, Tri, string)> ll){ 140 | if(i == prefix.Length){ 141 | ll.AddLast((pos, parent, prfx.ToString())); return; 142 | } 143 | var newParent = pos; 144 | foreach(char c in new char[]{ 145 | Char.ToUpper(prefix[i]), 146 | Char.ToLower(prefix[i]) 147 | } 148 | ){ 149 | if(pos.TryGetChild(c, out var newPos)){ 150 | prfx.Append(c); 151 | GetAllPrefixes(newParent, newPos!, prefix, prfx, i+1, ll); 152 | prfx.Length--; 153 | } 154 | } 155 | } 156 | 157 | public static string[]? GetPredictions(){ 158 | if(CursorPos.col == -1 && (CursorPos.line == 0 || linesText[CursorPos.line-1].Length == 0)){ return null; } 159 | var letter = CursorPos.col == -1 160 | ? linesText[CursorPos.line-1][^1] 161 | : linesText[CursorPos.line][CursorPos.col]; 162 | if (letters.Contains(letter)){ 163 | var (period, prefix) = GetPreviosWord(); 164 | return GetAllOptionsFromTree( 165 | period ? afterPeriodRecomendations : afterSpaceRecomendations, 166 | prefix 167 | ).Select(x => x.Substring(prefix!.Length)) 168 | .Where(x => !x.Equals("")) 169 | .ToArray(); 170 | } else if(letter == ' '){ 171 | return GetPreviosWord().word switch { 172 | "is" => new[]{ "not", "None", "not None" }, 173 | "in" => new[] { "range(", "range(len(", "enumerate(", "zip(" }, 174 | "not" => new[] { "in" }, 175 | "raise" => new[] { "Exception(" }, 176 | "except" => new[] { "Exception:" }, 177 | "def" => new[] { "__init__(self," }, 178 | "if" => new[] { "__name__ == \'__main__\':" }, 179 | "return" => new[] { "None", "True", "False" }, 180 | "lambda" => new[] { "x:", "num:", "x, y:", "num1, num2:" }, 181 | "for" => new[] { "i", "num", "_", "arr" }, 182 | _ => GetPreviosWord(1).word switch { 183 | "for" => new[]{ "in", "," }, 184 | "if" or "elif" => new[]{ "is", "in", "==", "!=", "is not", "not in", "% 2 == 0", "% 2 != 0"}, 185 | "and" or "or" or "while" => new[]{ ">", "<", "==", "!=", "<=", ">=", "is", "in"}, 186 | "from" => new[]{ "import" }, 187 | "import" => new[]{ "as" }, 188 | _ => null 189 | }, 190 | }; 191 | } 192 | return letter switch { 193 | '[' => new[]{"x for x in"}, 194 | '{' => new[]{"x for x in"}, 195 | '+' => new[]{ "= 1" }, 196 | '-' => new[]{ "= 1" }, 197 | _ => null 198 | }; 199 | } 200 | 201 | public static void Predict(){ 202 | var predictions = GetPredictions(); 203 | if(predictions is null || predictions.Length == 0){ 204 | predictionMenu = null; 205 | return; 206 | } 207 | MakePredictionMenu(predictions); 208 | nonStatic.Invalidate(); 209 | } 210 | 211 | public static (Bitmap bm, string[] predictions)? predictionMenu; 212 | private static void MakePredictionMenu(string[] predictions){ 213 | if(predictions.Length > 10){ 214 | predictions = predictions[..10]; 215 | } 216 | var (width, height) = (0, txtHeight * predictions.Length); 217 | foreach(var pred in predictions) { 218 | width = Max(width, MeasureWidth(pred, boldFont)); 219 | } 220 | 221 | predictionMenu = (new(width, height), predictions); 222 | RedrawPredictionMenu(); 223 | } 224 | public static void RedrawPredictionMenu(){ 225 | int end = 0; 226 | using(var g = Graphics.FromImage(predictionMenu!.Value.bm)){ 227 | g.Clear(Color.Gray); 228 | foreach(var pred in predictionMenu!.Value.predictions) { 229 | g.DrawString(pred, boldFont, blackBrush, 0, end); 230 | end += txtHeight; 231 | } 232 | } 233 | } 234 | } 235 | 236 | public class Tri { 237 | public char? Val { get; } 238 | public bool IsWord { get; set; } = false; 239 | public Dictionary children { get; } 240 | public Tri(char? val){ 241 | this.Val = val; 242 | children = new(); 243 | } 244 | public Tri AddChild(char val) => AddChild(new Tri(val)); 245 | public Tri AddChild(Tri child){ 246 | if(children.TryGetValue((char)child.Val!, out var oldChild)){ 247 | return oldChild; 248 | } 249 | children[(char)child.Val!] = child; 250 | return child; 251 | } 252 | public Tri GetChild(char val) => children[val]; 253 | public bool TryGetChild(char val, out Tri? res) => children.TryGetValue(val, out res); 254 | public void AddWord(string word, bool isVarName=false){ 255 | var tree = this; 256 | foreach (char c in word){ tree = tree.AddChild(c); } 257 | tree.IsWord = true; 258 | } 259 | } -------------------------------------------------------------------------------- /GraphicIDE/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\Arrow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\boolXY.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\brightnessBarSymbol.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\bug.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\console.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\Resources\copy.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Resources\divmod.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ..\Resources\dot.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | 146 | ..\Resources\emptyDict.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 147 | 148 | 149 | ..\Resources\emptyList.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 150 | 151 | 152 | ..\Resources\emptyTuple.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | ..\Resources\filter.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 156 | 157 | 158 | ..\Resources\float12.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 159 | 160 | 161 | ..\Resources\forArrowDown.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 162 | 163 | 164 | ..\Resources\forArrowUp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 165 | 166 | 167 | ..\Resources\hastag.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 168 | 169 | 170 | ..\Resources\int1234.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 171 | 172 | 173 | ..\Resources\keyboard.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 174 | 175 | 176 | ..\Resources\lightbulb.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 177 | 178 | 179 | ..\Resources\list.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 180 | 181 | 182 | ..\Resources\lockImg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 183 | 184 | 185 | ..\Resources\max.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 186 | 187 | 188 | ..\Resources\min.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 189 | 190 | 191 | ..\Resources\None.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 192 | 193 | 194 | ..\Resources\open.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 195 | 196 | 197 | ..\Resources\pass.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 198 | 199 | 200 | ..\Resources\paste.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 201 | 202 | 203 | ..\Resources\pi.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 204 | 205 | 206 | ..\Resources\light_play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 207 | 208 | 209 | ..\Resources\play.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 210 | 211 | 212 | ..\Resources\plus.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 213 | 214 | 215 | ..\Resources\printer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 216 | 217 | 218 | ..\Resources\red_X.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 219 | 220 | 221 | ..\Resources\rename.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 222 | 223 | 224 | ..\Resources\round.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 225 | 226 | 227 | ..\Resources\ruler.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 228 | 229 | 230 | ..\Resources\save.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 231 | 232 | 233 | ..\Resources\search.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 234 | 235 | 236 | ..\Resources\self.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 237 | 238 | 239 | ..\Resources\Settings.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 240 | 241 | 242 | ..\Resources\shortArrowGreen.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 243 | 244 | 245 | ..\Resources\shortArrowRed.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 246 | 247 | 248 | ..\Resources\sum.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 249 | 250 | 251 | ..\Resources\Trash.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 252 | 253 | 254 | ..\Resources\truck.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 255 | 256 | 257 | ..\Resources\tuple.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 258 | 259 | 260 | ..\Resources\whileArrowDown.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 261 | 262 | 263 | ..\Resources\whileArrowUp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 264 | 265 | 266 | ..\Resources\whiteArrow.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 267 | 268 | 269 | ..\Resources\yarn.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 270 | 271 | -------------------------------------------------------------------------------- /GraphicIDE/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace GraphicIDE.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GraphicIDE.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap Arrow { 67 | get { 68 | object obj = ResourceManager.GetObject("Arrow", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap boolXY { 77 | get { 78 | object obj = ResourceManager.GetObject("boolXY", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Drawing.Bitmap. 85 | /// 86 | internal static System.Drawing.Bitmap brightnessBarSymbol { 87 | get { 88 | object obj = ResourceManager.GetObject("brightnessBarSymbol", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Drawing.Bitmap. 95 | /// 96 | internal static System.Drawing.Bitmap bug { 97 | get { 98 | object obj = ResourceManager.GetObject("bug", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Drawing.Bitmap. 105 | /// 106 | internal static System.Drawing.Bitmap console { 107 | get { 108 | object obj = ResourceManager.GetObject("console", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | 113 | /// 114 | /// Looks up a localized resource of type System.Drawing.Bitmap. 115 | /// 116 | internal static System.Drawing.Bitmap copy { 117 | get { 118 | object obj = ResourceManager.GetObject("copy", resourceCulture); 119 | return ((System.Drawing.Bitmap)(obj)); 120 | } 121 | } 122 | 123 | /// 124 | /// Looks up a localized resource of type System.Drawing.Bitmap. 125 | /// 126 | internal static System.Drawing.Bitmap divmod { 127 | get { 128 | object obj = ResourceManager.GetObject("divmod", resourceCulture); 129 | return ((System.Drawing.Bitmap)(obj)); 130 | } 131 | } 132 | 133 | /// 134 | /// Looks up a localized resource of type System.Drawing.Bitmap. 135 | /// 136 | internal static System.Drawing.Bitmap dot { 137 | get { 138 | object obj = ResourceManager.GetObject("dot", resourceCulture); 139 | return ((System.Drawing.Bitmap)(obj)); 140 | } 141 | } 142 | 143 | /// 144 | /// Looks up a localized resource of type System.Drawing.Bitmap. 145 | /// 146 | internal static System.Drawing.Bitmap emptyDict { 147 | get { 148 | object obj = ResourceManager.GetObject("emptyDict", resourceCulture); 149 | return ((System.Drawing.Bitmap)(obj)); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized resource of type System.Drawing.Bitmap. 155 | /// 156 | internal static System.Drawing.Bitmap emptyList { 157 | get { 158 | object obj = ResourceManager.GetObject("emptyList", resourceCulture); 159 | return ((System.Drawing.Bitmap)(obj)); 160 | } 161 | } 162 | 163 | /// 164 | /// Looks up a localized resource of type System.Drawing.Bitmap. 165 | /// 166 | internal static System.Drawing.Bitmap emptyTuple { 167 | get { 168 | object obj = ResourceManager.GetObject("emptyTuple", resourceCulture); 169 | return ((System.Drawing.Bitmap)(obj)); 170 | } 171 | } 172 | 173 | /// 174 | /// Looks up a localized resource of type System.Drawing.Bitmap. 175 | /// 176 | internal static System.Drawing.Bitmap filter { 177 | get { 178 | object obj = ResourceManager.GetObject("filter", resourceCulture); 179 | return ((System.Drawing.Bitmap)(obj)); 180 | } 181 | } 182 | 183 | /// 184 | /// Looks up a localized resource of type System.Drawing.Bitmap. 185 | /// 186 | internal static System.Drawing.Bitmap float12 { 187 | get { 188 | object obj = ResourceManager.GetObject("float12", resourceCulture); 189 | return ((System.Drawing.Bitmap)(obj)); 190 | } 191 | } 192 | 193 | /// 194 | /// Looks up a localized resource of type System.Drawing.Bitmap. 195 | /// 196 | internal static System.Drawing.Bitmap forArrowDown { 197 | get { 198 | object obj = ResourceManager.GetObject("forArrowDown", resourceCulture); 199 | return ((System.Drawing.Bitmap)(obj)); 200 | } 201 | } 202 | 203 | /// 204 | /// Looks up a localized resource of type System.Drawing.Bitmap. 205 | /// 206 | internal static System.Drawing.Bitmap forArrowUp { 207 | get { 208 | object obj = ResourceManager.GetObject("forArrowUp", resourceCulture); 209 | return ((System.Drawing.Bitmap)(obj)); 210 | } 211 | } 212 | 213 | /// 214 | /// Looks up a localized resource of type System.Drawing.Bitmap. 215 | /// 216 | internal static System.Drawing.Bitmap hastag { 217 | get { 218 | object obj = ResourceManager.GetObject("hastag", resourceCulture); 219 | return ((System.Drawing.Bitmap)(obj)); 220 | } 221 | } 222 | 223 | /// 224 | /// Looks up a localized resource of type System.Drawing.Bitmap. 225 | /// 226 | internal static System.Drawing.Bitmap int1234 { 227 | get { 228 | object obj = ResourceManager.GetObject("int1234", resourceCulture); 229 | return ((System.Drawing.Bitmap)(obj)); 230 | } 231 | } 232 | 233 | /// 234 | /// Looks up a localized resource of type System.Drawing.Bitmap. 235 | /// 236 | internal static System.Drawing.Bitmap keyboard { 237 | get { 238 | object obj = ResourceManager.GetObject("keyboard", resourceCulture); 239 | return ((System.Drawing.Bitmap)(obj)); 240 | } 241 | } 242 | 243 | /// 244 | /// Looks up a localized resource of type System.Drawing.Bitmap. 245 | /// 246 | internal static System.Drawing.Bitmap lightbulb { 247 | get { 248 | object obj = ResourceManager.GetObject("lightbulb", resourceCulture); 249 | return ((System.Drawing.Bitmap)(obj)); 250 | } 251 | } 252 | 253 | /// 254 | /// Looks up a localized resource of type System.Drawing.Bitmap. 255 | /// 256 | internal static System.Drawing.Bitmap list { 257 | get { 258 | object obj = ResourceManager.GetObject("list", resourceCulture); 259 | return ((System.Drawing.Bitmap)(obj)); 260 | } 261 | } 262 | 263 | /// 264 | /// Looks up a localized resource of type System.Drawing.Bitmap. 265 | /// 266 | internal static System.Drawing.Bitmap lockImg { 267 | get { 268 | object obj = ResourceManager.GetObject("lockImg", resourceCulture); 269 | return ((System.Drawing.Bitmap)(obj)); 270 | } 271 | } 272 | 273 | /// 274 | /// Looks up a localized resource of type System.Drawing.Bitmap. 275 | /// 276 | internal static System.Drawing.Bitmap max { 277 | get { 278 | object obj = ResourceManager.GetObject("max", resourceCulture); 279 | return ((System.Drawing.Bitmap)(obj)); 280 | } 281 | } 282 | 283 | /// 284 | /// Looks up a localized resource of type System.Drawing.Bitmap. 285 | /// 286 | internal static System.Drawing.Bitmap min { 287 | get { 288 | object obj = ResourceManager.GetObject("min", resourceCulture); 289 | return ((System.Drawing.Bitmap)(obj)); 290 | } 291 | } 292 | 293 | /// 294 | /// Looks up a localized resource of type System.Drawing.Bitmap. 295 | /// 296 | internal static System.Drawing.Bitmap None { 297 | get { 298 | object obj = ResourceManager.GetObject("None", resourceCulture); 299 | return ((System.Drawing.Bitmap)(obj)); 300 | } 301 | } 302 | 303 | /// 304 | /// Looks up a localized resource of type System.Drawing.Bitmap. 305 | /// 306 | internal static System.Drawing.Bitmap open { 307 | get { 308 | object obj = ResourceManager.GetObject("open", resourceCulture); 309 | return ((System.Drawing.Bitmap)(obj)); 310 | } 311 | } 312 | 313 | /// 314 | /// Looks up a localized resource of type System.Drawing.Bitmap. 315 | /// 316 | internal static System.Drawing.Bitmap pass { 317 | get { 318 | object obj = ResourceManager.GetObject("pass", resourceCulture); 319 | return ((System.Drawing.Bitmap)(obj)); 320 | } 321 | } 322 | 323 | /// 324 | /// Looks up a localized resource of type System.Drawing.Bitmap. 325 | /// 326 | internal static System.Drawing.Bitmap paste { 327 | get { 328 | object obj = ResourceManager.GetObject("paste", resourceCulture); 329 | return ((System.Drawing.Bitmap)(obj)); 330 | } 331 | } 332 | 333 | /// 334 | /// Looks up a localized resource of type System.Drawing.Bitmap. 335 | /// 336 | internal static System.Drawing.Bitmap pi { 337 | get { 338 | object obj = ResourceManager.GetObject("pi", resourceCulture); 339 | return ((System.Drawing.Bitmap)(obj)); 340 | } 341 | } 342 | 343 | /// 344 | /// Looks up a localized resource of type System.Drawing.Bitmap. 345 | /// 346 | internal static System.Drawing.Bitmap play { 347 | get { 348 | object obj = ResourceManager.GetObject("play", resourceCulture); 349 | return ((System.Drawing.Bitmap)(obj)); 350 | } 351 | } 352 | 353 | /// 354 | /// Looks up a localized resource of type System.Drawing.Bitmap. 355 | /// 356 | internal static System.Drawing.Bitmap play1 { 357 | get { 358 | object obj = ResourceManager.GetObject("play1", resourceCulture); 359 | return ((System.Drawing.Bitmap)(obj)); 360 | } 361 | } 362 | 363 | /// 364 | /// Looks up a localized resource of type System.Drawing.Bitmap. 365 | /// 366 | internal static System.Drawing.Bitmap plus { 367 | get { 368 | object obj = ResourceManager.GetObject("plus", resourceCulture); 369 | return ((System.Drawing.Bitmap)(obj)); 370 | } 371 | } 372 | 373 | /// 374 | /// Looks up a localized resource of type System.Drawing.Bitmap. 375 | /// 376 | internal static System.Drawing.Bitmap printer { 377 | get { 378 | object obj = ResourceManager.GetObject("printer", resourceCulture); 379 | return ((System.Drawing.Bitmap)(obj)); 380 | } 381 | } 382 | 383 | /// 384 | /// Looks up a localized resource of type System.Drawing.Bitmap. 385 | /// 386 | internal static System.Drawing.Bitmap red_X { 387 | get { 388 | object obj = ResourceManager.GetObject("red_X", resourceCulture); 389 | return ((System.Drawing.Bitmap)(obj)); 390 | } 391 | } 392 | 393 | /// 394 | /// Looks up a localized resource of type System.Drawing.Bitmap. 395 | /// 396 | internal static System.Drawing.Bitmap rename { 397 | get { 398 | object obj = ResourceManager.GetObject("rename", resourceCulture); 399 | return ((System.Drawing.Bitmap)(obj)); 400 | } 401 | } 402 | 403 | /// 404 | /// Looks up a localized resource of type System.Drawing.Bitmap. 405 | /// 406 | internal static System.Drawing.Bitmap round { 407 | get { 408 | object obj = ResourceManager.GetObject("round", resourceCulture); 409 | return ((System.Drawing.Bitmap)(obj)); 410 | } 411 | } 412 | 413 | /// 414 | /// Looks up a localized resource of type System.Drawing.Bitmap. 415 | /// 416 | internal static System.Drawing.Bitmap ruler { 417 | get { 418 | object obj = ResourceManager.GetObject("ruler", resourceCulture); 419 | return ((System.Drawing.Bitmap)(obj)); 420 | } 421 | } 422 | 423 | /// 424 | /// Looks up a localized resource of type System.Drawing.Bitmap. 425 | /// 426 | internal static System.Drawing.Bitmap save { 427 | get { 428 | object obj = ResourceManager.GetObject("save", resourceCulture); 429 | return ((System.Drawing.Bitmap)(obj)); 430 | } 431 | } 432 | 433 | /// 434 | /// Looks up a localized resource of type System.Drawing.Bitmap. 435 | /// 436 | internal static System.Drawing.Bitmap search { 437 | get { 438 | object obj = ResourceManager.GetObject("search", resourceCulture); 439 | return ((System.Drawing.Bitmap)(obj)); 440 | } 441 | } 442 | 443 | /// 444 | /// Looks up a localized resource of type System.Drawing.Bitmap. 445 | /// 446 | internal static System.Drawing.Bitmap self { 447 | get { 448 | object obj = ResourceManager.GetObject("self", resourceCulture); 449 | return ((System.Drawing.Bitmap)(obj)); 450 | } 451 | } 452 | 453 | /// 454 | /// Looks up a localized resource of type System.Drawing.Bitmap. 455 | /// 456 | internal static System.Drawing.Bitmap Settings { 457 | get { 458 | object obj = ResourceManager.GetObject("Settings", resourceCulture); 459 | return ((System.Drawing.Bitmap)(obj)); 460 | } 461 | } 462 | 463 | /// 464 | /// Looks up a localized resource of type System.Drawing.Bitmap. 465 | /// 466 | internal static System.Drawing.Bitmap shortArrowGreen { 467 | get { 468 | object obj = ResourceManager.GetObject("shortArrowGreen", resourceCulture); 469 | return ((System.Drawing.Bitmap)(obj)); 470 | } 471 | } 472 | 473 | /// 474 | /// Looks up a localized resource of type System.Drawing.Bitmap. 475 | /// 476 | internal static System.Drawing.Bitmap shortArrowRed { 477 | get { 478 | object obj = ResourceManager.GetObject("shortArrowRed", resourceCulture); 479 | return ((System.Drawing.Bitmap)(obj)); 480 | } 481 | } 482 | 483 | /// 484 | /// Looks up a localized resource of type System.Drawing.Bitmap. 485 | /// 486 | internal static System.Drawing.Bitmap sum { 487 | get { 488 | object obj = ResourceManager.GetObject("sum", resourceCulture); 489 | return ((System.Drawing.Bitmap)(obj)); 490 | } 491 | } 492 | 493 | /// 494 | /// Looks up a localized resource of type System.Drawing.Bitmap. 495 | /// 496 | internal static System.Drawing.Bitmap Trash { 497 | get { 498 | object obj = ResourceManager.GetObject("Trash", resourceCulture); 499 | return ((System.Drawing.Bitmap)(obj)); 500 | } 501 | } 502 | 503 | /// 504 | /// Looks up a localized resource of type System.Drawing.Bitmap. 505 | /// 506 | internal static System.Drawing.Bitmap truck { 507 | get { 508 | object obj = ResourceManager.GetObject("truck", resourceCulture); 509 | return ((System.Drawing.Bitmap)(obj)); 510 | } 511 | } 512 | 513 | /// 514 | /// Looks up a localized resource of type System.Drawing.Bitmap. 515 | /// 516 | internal static System.Drawing.Bitmap tuple { 517 | get { 518 | object obj = ResourceManager.GetObject("tuple", resourceCulture); 519 | return ((System.Drawing.Bitmap)(obj)); 520 | } 521 | } 522 | 523 | /// 524 | /// Looks up a localized resource of type System.Drawing.Bitmap. 525 | /// 526 | internal static System.Drawing.Bitmap whileArrowDown { 527 | get { 528 | object obj = ResourceManager.GetObject("whileArrowDown", resourceCulture); 529 | return ((System.Drawing.Bitmap)(obj)); 530 | } 531 | } 532 | 533 | /// 534 | /// Looks up a localized resource of type System.Drawing.Bitmap. 535 | /// 536 | internal static System.Drawing.Bitmap whileArrowUp { 537 | get { 538 | object obj = ResourceManager.GetObject("whileArrowUp", resourceCulture); 539 | return ((System.Drawing.Bitmap)(obj)); 540 | } 541 | } 542 | 543 | /// 544 | /// Looks up a localized resource of type System.Drawing.Bitmap. 545 | /// 546 | internal static System.Drawing.Bitmap whiteArrow { 547 | get { 548 | object obj = ResourceManager.GetObject("whiteArrow", resourceCulture); 549 | return ((System.Drawing.Bitmap)(obj)); 550 | } 551 | } 552 | 553 | /// 554 | /// Looks up a localized resource of type System.Drawing.Bitmap. 555 | /// 556 | internal static System.Drawing.Bitmap yarn { 557 | get { 558 | object obj = ResourceManager.GetObject("yarn", resourceCulture); 559 | return ((System.Drawing.Bitmap)(obj)); 560 | } 561 | } 562 | } 563 | } 564 | -------------------------------------------------------------------------------- /GraphicIDE/Classes/Form1.cs: -------------------------------------------------------------------------------- 1 | global using static GraphicIDE.BrushesAndPens; 2 | global using static GraphicIDE.MyMath; 3 | global using static GraphicIDE.MyImages; 4 | global using static GraphicIDE.Helpers; 5 | global using static GraphicIDE.DrawScreen; 6 | global using static GraphicIDE.Start; 7 | global using static GraphicIDE.Tabs; 8 | global using static GraphicIDE.Console; 9 | global using static GraphicIDE.KeyInput; 10 | global using static GraphicIDE.History; 11 | global using static GraphicIDE.Settings; 12 | global using static GraphicIDE.Prediction; 13 | global using static GraphicIDE.AST; 14 | global using static GraphicIDE.PythonFuncs; 15 | global using static GraphicIDE.Form1; 16 | 17 | global using GraphicIDE.Properties; 18 | 19 | global using System.Text; 20 | global using System.Diagnostics; 21 | global using System.Net; 22 | global using IronPython.Compiler.Ast; 23 | global using IronPython.Compiler; 24 | global using System.Text.RegularExpressions; 25 | using System.Runtime.InteropServices; 26 | 27 | 28 | 29 | // todo git 30 | // todo add cheat sheat 31 | // todo group words in ctrl z 32 | // todo auto save 33 | // todo add in settings to change `history amount` (for ctrl+Z) 34 | // todo cache some of the textline images 35 | // todo only draw visable lines 36 | // todo capslock shortcuts 37 | // todo add little icon to list/set.. comprehension to signal which type it is 38 | // todo scroll horizontal 39 | // todo when renaming func rename all calls too 40 | // todo rename word 41 | // todo stop execution 42 | // todo drag selection 43 | // todo comments w drawing 44 | // todo comments 45 | // ? del, global, *, assert, yield\yeild from, with, formatStr, finally, for-else, annotations, decorators, generator(+comprehension) 46 | // --------------------------------------------------------------------------- 47 | // todo have file system on right so dont need to have all tabs open 48 | // todo syntax highlighting 49 | // todo add / move / resize windows 50 | // ? classes(+attributes) 51 | // ? try except raise 52 | #region built in funcs 53 | // aiter() anext() breakpoint() bytearray() bytes() callable() classmethod() compile() dir() frozenset() memoryview() property() repr() staticmethod() super() vars() 54 | // dict() set() 55 | // chr() ord() 56 | // range() enumerate() zip() 57 | // all() any() 58 | // map() 59 | // type() 60 | // reversed() sorted() 61 | // help() 62 | // open() 63 | // next() 64 | // eval() exec() 65 | // globals() locals() 66 | // bin() 67 | // id() 68 | // ascii() 69 | // iter() 70 | // slice() 71 | // object() 72 | // oct() hex() 73 | // complex() 74 | // delattr() getattr() hasattr() setattr() 75 | // format() 76 | // isinstance() issubclass() 77 | #endregion 78 | 79 | namespace GraphicIDE; 80 | 81 | public partial class Form1: Form { 82 | #region vars 83 | public static (int line, int col)? selectedLine = null; 84 | public static int? lastCol = null; 85 | public static List linesText = null!; 86 | public static readonly TextBox textBox = new(); 87 | public static readonly StringFormat stringFormat = new(); 88 | public static Font boldFont = null!; 89 | public const int WM_KEYDOWN = 0x100; 90 | public static int indentW, qWidth, qHeight, upSideDownW, txtHeight, fromW, colW; 91 | public static int screenWidth = 0, screenHeight = 0, prevHeight, prevWidth; 92 | public static List windows = new(); 93 | public static HashSet visibleMenues = new(); 94 | public static bool dragging = false, doubleClick = false; 95 | // todo convert to linked list 96 | public static List<(Button btn, Func<(int w, int h), Point> calcPos)> buttonsOnScreen = new(); 97 | public static Point screenPos; 98 | public static Form1 nonStatic = null!; 99 | public static ToolTip toolTip = new ToolTip(){ 100 | AutoPopDelay = 5000, 101 | InitialDelay = 1000, 102 | ReshowDelay = 500, 103 | ShowAlways = true, 104 | BackColor = Color.WhiteSmoke 105 | }; 106 | #endregion 107 | 108 | public Form1() { 109 | nonStatic = this; 110 | InitializeComponent(); 111 | this.MinimumSize = new(100, 100); 112 | // this.FormBorderStyle = FormBorderStyle.None; 113 | this.BackColor = Color.Black; 114 | this.DoubleBuffered = true; 115 | screenPos = GetScreenPos(); 116 | 117 | Prediction.Start(); 118 | 119 | textBox.AcceptsReturn = true; 120 | textBox.AcceptsTab = true; 121 | textBox.Dock = DockStyle.None; 122 | textBox.Size = new Size(0, 0); 123 | 124 | textBox.Multiline = true; 125 | textBox.ScrollBars = ScrollBars.Vertical; 126 | textBox.Text = "()"; 127 | textBox.SelectionStart = 1; 128 | textBox.SelectionLength = 0; 129 | textBox.Focus(); 130 | SetTabWidth(textBox, 4); 131 | 132 | FirstChangeFontSize(15); 133 | 134 | Controls.Add(textBox); 135 | textBox.TextChanged += new EventHandler(TextBox_TextChanged!); 136 | textBox.KeyDown += new KeyEventHandler(Form1_KeyDown!); 137 | 138 | stringFormat.SetTabStops(0, new float[] { 4 }); 139 | 140 | (prevHeight, prevWidth) = (screenHeight, screenWidth) = (GetHeight(), GetWidth()); 141 | 142 | var (windowHeight, windowWidth) = ( 143 | screenHeight, 144 | screenWidth / 2 145 | ); 146 | 147 | var mainFunc = NewFunc(".Main", isfirst: true); 148 | var mainWindow = MakeNewWindow(mainFunc, size: (windowWidth, windowHeight), pos: (0, 0)); 149 | var func2 = NewFunc("func()", isfirst: true); 150 | var window2 = MakeNewWindow(func2, size: (windowWidth, windowHeight), pos: (windowWidth, 0)); 151 | curWindow = mainWindow; 152 | curFunc = mainFunc; 153 | ChangeTab(curFunc.name, prevWindow: window2); 154 | 155 | var run = RunBtn(); 156 | // var debug = AddDebugBtn(); 157 | var tab = TabBtn(); 158 | var rename = RenameTabBtn(); 159 | var settings = SettingsBtn(); 160 | var unsaved = UnsavedButton(); 161 | var trash = TrashBtn(); 162 | var save = SaveBtn(); 163 | var open = OpenBtn(); 164 | unsaved.Hide(); 165 | 166 | AddConsole(); 167 | var execTime = MakeExecTimeDisplay(); 168 | toolTip.SetToolTip(execTime, "Executed time"); 169 | 170 | DrawTextScreen(); 171 | Invalidate(); 172 | 173 | this.WindowState = FormWindowState.Maximized; 174 | 175 | FocusTB(); 176 | } 177 | 178 | #region THE EVENTS 179 | public void Move_Event(object sender, EventArgs e) => screenPos = GetScreenPos(); 180 | public void Resize_Event(object sender, EventArgs e){ 181 | (int Width, int Height) WHTuple = (screenWidth, screenHeight) = (GetWidth(), GetHeight()); 182 | if(screenHeight == 0 || screenWidth == 0){ return; } 183 | var (changeH, changeW) = ( 184 | (float)prevHeight / screenHeight, 185 | (float)prevWidth / screenWidth 186 | ); 187 | 188 | foreach(var window in windows) { 189 | window.size.height /= changeH; 190 | window.size.width /= changeW; 191 | window.pos.x /= changeW; 192 | window.pos.y = window.pos.y / changeH; 193 | for (int i=0; i < window.tabButtons.Count; i++) { 194 | var btn = window.tabButtons[i]; 195 | btn.Location = new((int)window.pos.x + (TAB_WIDTH + 10) * i, (int)window.pos.y); 196 | var a = btn.Location; 197 | } 198 | } 199 | RefreshConsole(); 200 | foreach(var button in buttonsOnScreen) { 201 | button.btn.Location = button.calcPos(WHTuple); 202 | } 203 | 204 | if(visablePrompt is Prompt p){ 205 | p.tb.Location = new( 206 | (int)(screenWidth / 2 - p.tb.Width / 2), 207 | (int)(screenHeight / 2 - p.tb.Height / 2) 208 | ); 209 | } 210 | if(rightClickMenu is not null){ 211 | DisposeMenu(ref rightClickMenu); 212 | } 213 | 214 | (prevHeight, prevWidth) = (screenHeight, screenWidth); 215 | Invalidate(); 216 | } 217 | protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { 218 | var keyCode = (Keys) (msg.WParam.ToInt32() & Convert.ToInt32(Keys.KeyCode)); 219 | if(msg.Msg == WM_KEYDOWN && IsCtrlPressed()) { 220 | bool isAltlKeyPressed = IsAltlPressed(); 221 | bool isShift = IsShiftPressed(); 222 | bool refresh = true; 223 | 224 | ((Action)(keyCode switch { 225 | Keys.Delete => () => DeleteKey(isAltlKeyPressed, true), 226 | Keys.Back => () => BackSpaceKey(isAltlKeyPressed, true), 227 | Keys.Enter => () => EnterKey(true), 228 | Keys.End => () => EndKey(isShift, true), 229 | Keys.Home => () => HomeKey(isShift, true), 230 | Keys.Up => () => ChangeOffsetTo(curWindow.offset + txtHeight), 231 | Keys.Down => () => ChangeOffsetTo(curWindow.offset - txtHeight), 232 | Keys.Right => () => RightKey(isShift, isAltlKeyPressed, true), 233 | Keys.Left => () => LeftKey(isShift, isAltlKeyPressed, true), 234 | Keys.C => () => Copy(isAltlKeyPressed), 235 | Keys.V => () => Paste(), 236 | Keys.X => () => Cut(isAltlKeyPressed), 237 | Keys.D => () => Duplicate(isAltlKeyPressed), 238 | Keys.A => () => SelectAll(), 239 | Keys.N => () => PromptMakeNewTab(), 240 | Keys.R => () => PromptRenameTab(), 241 | Keys.Z => () => CtrlZ(), 242 | Keys.Y => () => CtrlY(), 243 | Keys.S => () => Save(isShift), 244 | Keys.O => () => Open(), 245 | Keys.Tab => () => CtrlTab(), 246 | Keys.Oemtilde => () => ToggleConsole(), 247 | Keys.Oemplus => () => ChangeFontSize(1), 248 | Keys.OemMinus => () => ChangeFontSize(-1), 249 | Keys.Space => () => PythonFuncs.Execute(), 250 | Keys.OemQuestion => () => Comment(), 251 | _ => () => refresh = false 252 | }))(); 253 | if(refresh){ 254 | DrawTextScreen(); 255 | Invalidate(); 256 | } 257 | return true; 258 | } 259 | return base.ProcessCmdKey(ref msg, keyData); 260 | } 261 | #endregion 262 | 263 | #region Mouse 264 | public static Menu? rightClickMenu; 265 | private static Menu? staticRightClickMenu; 266 | public static void RightClick(){ 267 | int size = 80, gap = 10; 268 | 269 | bool addToControls = true; 270 | if(staticRightClickMenu is null){ 271 | MakeFirstRCMenu(); 272 | addToControls = false; 273 | } 274 | 275 | (int x, int y) mouse = ( 276 | Cursor.Position.X - screenPos.X, 277 | Cursor.Position.Y - screenPos.Y 278 | ); 279 | (int X, int Y) location = (mouse.x, mouse.y); 280 | 281 | int sizeH = size * 2 + gap * 3; 282 | int sizeW = size * 3 + gap * 4; 283 | Rectangle bgPos = new(location.X, location.Y, sizeW, sizeH); 284 | 285 | foreach(var button in staticRightClickMenu!.Value.buttons) { 286 | button.btn.Location = button.getPos(location); 287 | if(addToControls){ 288 | nonStatic.Controls.Add(button.btn); 289 | } 290 | button.btn.BringToFront(); 291 | } 292 | 293 | rightClickMenu = new(bgPos, staticRightClickMenu!.Value.bgColor, staticRightClickMenu.Value.buttons); 294 | visibleMenues.Add((Menu)rightClickMenu); 295 | BlockMouse(staticRightClickMenu!.Value.buttons[0].btn, rightClickMenu); 296 | nonStatic.Invalidate(); 297 | } 298 | private static void MakeFirstRCMenu(){ 299 | int size = 80, gap = 10; 300 | 301 | Button bg = MakeButton(40, 40, new(1, 1), streatch: false); 302 | bg.FlatAppearance.MouseOverBackColor = Color.Transparent; 303 | bg.MouseDown += new MouseEventHandler((object? _, MouseEventArgs e) => { 304 | DisposeMenu(ref rightClickMenu); 305 | if(e.Button == MouseButtons.Right){ 306 | RightClick(); 307 | } 308 | }); 309 | 310 | Button copy = MakeButton(size, size, copyImg, streatch: false); 311 | Func<(int X, int Y), Point> copyGetPos = (pos) => new(pos.X + gap, pos.Y + gap); 312 | copy.Click += new EventHandler((_,_) => { 313 | DisposeMenu(ref rightClickMenu); 314 | Copy(IsAltlPressed()); 315 | }); 316 | toolTip.SetToolTip(copy, "copy"); 317 | 318 | Button paste = MakeButton(size, size, pasteImg, streatch: false); 319 | Func<(int X, int Y), Point> pasteGetPos = (pos) => new(pos.X + 2 * gap + 1 * size, pos.Y + gap); 320 | paste.Click += new EventHandler((_,_) => { 321 | DisposeMenu(ref rightClickMenu); 322 | Paste(); 323 | DrawTextScreen(); 324 | nonStatic.Invalidate(); 325 | }); 326 | toolTip.SetToolTip(paste, "paste"); 327 | 328 | Button search = MakeButton(size, size, searchImg, streatch: false); 329 | Func<(int X, int Y), Point> searchGetPos = (pos) => new(pos.X + gap, pos.Y + 2 * gap + size); 330 | search.Click += new EventHandler((_,_) => { 331 | DisposeMenu(ref rightClickMenu); 332 | string txt = ( 333 | selectedLine is null 334 | ? linesText[CursorPos.line] 335 | : GetSelectedText() 336 | ).Trim(); 337 | if(!txt.Equals("")) { 338 | Process.Start( 339 | new ProcessStartInfo( 340 | "cmd", 341 | $"/c start https://www.google.com/search?q=Python{ WebUtility.UrlEncode(" " + txt) }" 342 | ) { CreateNoWindow = true } 343 | ); 344 | } 345 | }); 346 | toolTip.SetToolTip(search, "Google selected"); 347 | 348 | Button terminal = MakeButton(size, size, consoleImg, streatch: false); 349 | Func<(int X, int Y), Point> terminalGetPos = (pos) => new(pos.X + 2 * gap + size, pos.Y + 2 * gap + size); 350 | terminal.Click += new EventHandler((_,_) => { 351 | DisposeMenu(ref rightClickMenu); 352 | Process.Start(new ProcessStartInfo("cmd.exe"){ UseShellExecute = true }); 353 | }); 354 | toolTip.SetToolTip(terminal, "open cmd"); 355 | 356 | Button run = MakeButton(size, size, play3dImg, streatch: false); 357 | Func<(int X, int Y), Point> runGetPos = (pos) => new(pos.X + 3 * gap + 2 * size, pos.Y + gap); 358 | run.Click += new EventHandler((_,_) => { 359 | DisposeMenu(ref rightClickMenu); 360 | PythonFuncs.Execute(); 361 | }); 362 | toolTip.SetToolTip(run, "run"); 363 | 364 | Button rename = MakeButton(size, size, renameImg, streatch: false); 365 | Func<(int X, int Y), Point> renameGetPos = (pos) => new(pos.X + 3 * gap + 2 * size, pos.Y + 2 * gap + size); 366 | rename.Click += new EventHandler((_,_) => { 367 | DisposeMenu(ref rightClickMenu); 368 | // Todo 369 | }); 370 | toolTip.SetToolTip(rename, "rename"); 371 | 372 | staticRightClickMenu = new(new(0,0,1,1), sandyBrush, new(){ 373 | (bg, (_)=>new(0,0)), 374 | (copy, copyGetPos), (paste, pasteGetPos), (search, searchGetPos), 375 | (terminal, terminalGetPos), (run, runGetPos), (rename, renameGetPos) 376 | }); 377 | } 378 | public static async void BlockMouse(Button btn, Menu? screen){ 379 | int w = btn.Size.Width / 2, h = btn.Size.Height / 2; 380 | while(screen is not null){ 381 | await Task.Delay(10); 382 | btn.Location = new(Cursor.Position.X - screenPos.X - w, Cursor.Position.Y - screenPos.Y- h); 383 | } 384 | } 385 | public static void DisposeMenu(ref Menu? menu){ 386 | if(menu is Menu m){ 387 | foreach(var item in m.buttons) { 388 | nonStatic.Controls.Remove(item.btn); 389 | } 390 | visibleMenues.Remove(m); 391 | } 392 | menu = null; 393 | nonStatic.Invalidate(); 394 | } 395 | protected override void OnMouseWheel(MouseEventArgs e) { 396 | if(curWindow.function.displayImage!.Height > 40) { 397 | ChangeOffsetTo(curWindow.offset + e.Delta / 10); 398 | } 399 | Invalidate(); 400 | base.OnMouseWheel(e); 401 | } 402 | protected override void OnMouseDown(MouseEventArgs e) { 403 | dragging = true; 404 | Drag(e); 405 | base.OnMouseDown(e); 406 | } 407 | protected override void OnMouseUp(MouseEventArgs e) { 408 | dragging = false; 409 | base.OnMouseUp(e); 410 | } 411 | protected override void OnMouseDoubleClick(MouseEventArgs e) { 412 | dragging = false; 413 | doubleClick = true; 414 | 415 | GoInDirCtrl(GetNextL, IsAltlPressed()); 416 | selectedLine = (CursorPos.line, CursorPos.col); 417 | GoInDirCtrl(GetNextR, IsAltlPressed()); 418 | 419 | DrawTextScreen(); 420 | Invalidate(); 421 | base.OnMouseDoubleClick(e); 422 | } 423 | public void ClickedSelected((int line, int col) pos, (int,int) sel) { 424 | var newSelectedLine = (CursorPos.line, -1); 425 | var newCurCol = linesText[CursorPos.line].Length - 1; 426 | if(newCurCol == pos.col && newSelectedLine == sel) { 427 | GoInDirCtrl(GetNextL, IsAltlPressed()); 428 | selectedLine = (CursorPos.line, CursorPos.col); 429 | GoInDirCtrl(GetNextR, IsAltlPressed()); 430 | } else { 431 | CursorPos.ChangeCol(newCurCol); 432 | selectedLine = newSelectedLine; 433 | } 434 | DrawTextScreen(); 435 | Invalidate(); 436 | } 437 | async void Drag(MouseEventArgs e) { 438 | if(rightClickMenu is not null){ 439 | DisposeMenu(ref rightClickMenu); 440 | } 441 | (int line, int col)? tempSelectedLine = null; 442 | if(e.Button == MouseButtons.Left) { 443 | (int x, int y) mousePos = ( 444 | Cursor.Position.X - screenPos.X, 445 | Cursor.Position.Y - screenPos.Y 446 | ); 447 | foreach(var window in windows) { 448 | bool inX = mousePos.x >= window.pos.x && mousePos.x <= window.pos.x + window.size.width; 449 | bool inY = mousePos.y >= window.pos.y && mousePos.y <= window.pos.y + window.size.height; 450 | if(inX && inY) { 451 | if(window.Equals(curWindow)) { 452 | var prev = (CursorPos.line, CursorPos.col); 453 | var prevSel = selectedLine; 454 | MouseBtnClick(refresh: false); 455 | if(prevSel is (int, int) ps && InBetween((CursorPos.line, CursorPos.col), prev, ps)) { 456 | ClickedSelected(prev, ps); 457 | return; 458 | } 459 | tempSelectedLine = (CursorPos.line, CursorPos.col); 460 | break; 461 | } 462 | bool dontDraw = curWindow.asPlainText; 463 | var prevWindow = curWindow; 464 | curWindow = window; 465 | ChangeTab(window.function.name, prevWindow, dontDraw: dontDraw); 466 | break; 467 | } 468 | } 469 | } else if(e.Button == MouseButtons.Middle) { 470 | PythonFuncs.Execute(); 471 | return; 472 | } else if(e.Button == MouseButtons.Right) { 473 | RightClick(); 474 | return; 475 | } 476 | 477 | for(int i = 0; i < 10; i++) { 478 | await Task.Delay(1); 479 | if(!dragging) { 480 | if(doubleClick) { doubleClick = false; } 481 | else { MouseBtnClick(); } 482 | return; 483 | } 484 | } 485 | if(!IsShiftPressed() || selectedLine is null) { 486 | selectedLine = tempSelectedLine!; 487 | } 488 | while(dragging) { 489 | MouseBtnClick(); 490 | await Task.Delay(1); 491 | } 492 | } 493 | public static void MouseBtnClick(bool refresh=true) { 494 | if(selectedLine is not null) { 495 | if(!IsShiftPressed() && !dragging) { 496 | selectedLine = null; 497 | } 498 | } 499 | CursorPos.ChangeLine(GetClickRow()); 500 | CursorPos.ChangeCol(BinarySearch( 501 | linesText[CursorPos.line].Length, 502 | Cursor.Position.X - curWindow.pos.x - screenPos.X, 503 | GetDistW 504 | )); 505 | textBox.Focus(); 506 | if(refresh) { 507 | DrawTextScreen(); 508 | nonStatic.Invalidate(); 509 | } 510 | } 511 | public static int GetClickRow() { 512 | double mouse = Cursor.Position.Y - (curWindow.pos.y + curWindow.offset) - screenPos.Y; 513 | if(!curWindow.function.name.Equals(".console")){ 514 | mouse -= TAB_HEIGHT; 515 | } 516 | int i = (int)Math.Floor(mouse / txtHeight); 517 | return Max(0, Min(linesText.Count - 1, i)); 518 | } 519 | public static int BinarySearch(int len, float item, Func Get) { 520 | if(len == 0) { return -1; } 521 | int first = 0, mid; 522 | int last = len - 1; 523 | do { 524 | mid = first + (last - first) / 2; 525 | var pos = Get(mid); 526 | if(item > pos) { first = mid + 1; } 527 | else { last = mid - 1; } 528 | if(pos == item) { return mid; } 529 | } while(first <= last); 530 | 531 | var cur = Abs(item - Get(mid)); 532 | if(mid > -1) { 533 | if(Abs(item - Get(mid - 1)) < cur) { 534 | return mid - 1; 535 | } 536 | } 537 | if(mid < len - 1) { 538 | if(Abs(item - Get(mid + 1)) < cur) { 539 | return mid + 1; 540 | } 541 | } 542 | return mid; 543 | } 544 | 545 | #endregion 546 | 547 | #region SetTabSize 548 | private const int EM_SETTABSTOPS = 0x00CB; 549 | [DllImport("User32.dll", CharSet = CharSet.Auto)] 550 | private static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam); 551 | public static void SetTabWidth(TextBox textbox, int tabWidth) { 552 | Graphics graphics = textbox.CreateGraphics(); 553 | var characterWidth = (int)graphics.MeasureString("M", textbox.Font).Width; 554 | SendMessage(textbox.Handle, EM_SETTABSTOPS, 1, new int[] { tabWidth * characterWidth }); 555 | } 556 | #endregion 557 | 558 | #region Miscelaneuos 559 | public static float GetDistW(int i) { 560 | return MeasureWidth(linesText[CursorPos.line][..(i + 1)], boldFont); 561 | } 562 | public static (int line, int col, char val)? GetNextR() { 563 | if(CursorPos.col != linesText[CursorPos.line].Length - 1) { 564 | return (CursorPos.line, CursorPos.col + 1, linesText[CursorPos.line][CursorPos.col + 1]); 565 | } 566 | if(CursorPos.line == linesText.Count - 1) { 567 | return null; 568 | } 569 | return (CursorPos.line + 1, -1, '\n'); 570 | } 571 | public static (int line, int col, char val)? GetNextL() { 572 | if(CursorPos.col != - 1) { 573 | return (CursorPos.line, CursorPos.col - 1, linesText[CursorPos.line][CursorPos.col]); 574 | } 575 | if(CursorPos.line == 0) { 576 | return null; 577 | } 578 | return (CursorPos.line - 1, linesText[CursorPos.line - 1].Length - 1, '\n'); 579 | } 580 | public static void GoInDirCtrl(Func<(int line, int col, char val)?> GetNext, bool isAlt) { 581 | var next = GetNext(); 582 | char? cur = next?.val; 583 | if(cur is null) { } 584 | else if(" \n\t".Contains(cur.Value)) { 585 | Move(() => " \n\t".Contains(next!.Value.val)); 586 | } else if(IsNumeric(cur!.Value)) { 587 | if(isAlt) { 588 | Move(() => IsAltNumeric(next!.Value.val)); 589 | } else { 590 | Move(() => IsNumeric(next!.Value.val)); 591 | } 592 | } else { 593 | Move(() => !" \n\t".Contains(next!.Value.val) && !IsNumeric(next!.Value.val)); 594 | while(next is not null && " \n\t".Contains(next.Value.val)) { 595 | CursorPos.ChangeBoth((next!.Value.line, next!.Value.col)); 596 | next = GetNext(); 597 | } 598 | } 599 | void Move(Func Condition) { 600 | do { 601 | CursorPos.ChangeBoth((next!.Value.line, next!.Value.col)); 602 | next = GetNext(); 603 | } while( 604 | next is not null && Condition() 605 | ); 606 | } 607 | } 608 | #endregion 609 | } 610 | 611 | public record struct BM_Middle(Bitmap Img, int Middle); 612 | public record struct Menu(Rectangle bgPos, SolidBrush bgColor, List<(Button btn, Func<(int X, int Y), Point> getPos)> buttons); 613 | static class CursorPos { 614 | public static int line{ get; private set; } = 0; 615 | public static int col{ get; private set; } = -1; 616 | private static void RealignWondow(){ 617 | int txtPos = CursorPos.line * Form1.txtHeight; 618 | int pos = txtPos + curWindow.offset; 619 | if(pos < 0){ 620 | curWindow.offset = - txtPos; 621 | } else if(pos >= (int)curWindow.size.height - TAB_HEIGHT - (int)(Form1.txtHeight/0.8)){ 622 | curWindow.offset = - (txtPos + Form1.txtHeight - (int)curWindow.size.height + TAB_HEIGHT); 623 | } 624 | // TODO for col too 625 | } 626 | public static void ChangeLine(int i){ 627 | CursorPos.line = i; 628 | RealignWondow(); 629 | predictionMenu = null; 630 | } 631 | public static void ChangeCol(int i){ 632 | CursorPos.col = i; 633 | RealignWondow(); 634 | predictionMenu = null; 635 | } 636 | public static void ChangeBoth((int line, int col) val){ 637 | (CursorPos.line, CursorPos.col) = val; 638 | RealignWondow(); 639 | predictionMenu = null; 640 | } 641 | public static (int line, int col) ToTuple(){ 642 | return (CursorPos.line, CursorPos.col); 643 | } 644 | } 645 | public class Window { 646 | public Function function; 647 | public (float width, float height) size; 648 | public (float x, float y) pos; 649 | public int offset = 0; 650 | public bool isPic = false; 651 | public int tabsEnd = 0; 652 | public readonly List