Пример #1
0
        /// <summary>
        /// Invoked by "Level => Open level file" or the relevant toolbar button.
        /// Allows the user to load a text file containing Sokoban levels.
        /// </summary>
        private void openLevelFile(object sender, EventArgs e)
        {
            if (!mayDestroyEverything(Program.Tr.Mainform_MessageTitle_OpenLevelFile))
            {
                return;
            }

            OpenFileDialog openDlg = new OpenFileDialog();

            openDlg.DefaultExt       = "txt";
            openDlg.Filter           = Program.Tr.Save_FileType_TextFiles + "|*.txt|" + Program.Tr.Save_FileType_AllFiles + "|*.*";
            openDlg.InitialDirectory = Program.Settings.LastOpenSaveDirectory;
            if (openDlg.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            try
            {
                lstLevels.LoadLevelPack(openDlg.FileName);
            }
            catch (LevelListBox.InvalidLevelException)
            {
                DlgMessage.ShowError(Program.Tr.Mainform_InvalidFile, Program.Tr.Mainform_InvalidFile_Title);
                return;
            }

            Program.Settings.LastOpenSaveDirectory = Path.GetDirectoryName(openDlg.FileName);
            Program.Settings.SaveThreaded();
            ctMainArea.Modified = false;
            showLevelList(true);
            lstLevels.PlayFirstUnsolved();
        }
Пример #2
0
        private bool LoadCommitsPreserveChanges(List <CommitModel> newCommits, bool warnIfNoMatch)
        {
            var  oldCommits = Commits;
            bool warned     = false;

            foreach (var oldCommit in oldCommits.Where(or => or.Modified))
            {
                var newCommit = newCommits.SingleOrDefault(r => r.Hash == oldCommit.Hash);
                if (newCommit != null)
                {
                    newCommit.RestoreFrom(oldCommit);
                }
                else if (warnIfNoMatch && !warned)
                {
                    var btn = DlgMessage.ShowWarning($"You have made changes to commit {oldCommit.Hash} but the repository you are opening does not have this commit.\nIf you choose to proceed, your changes to this commit will be discarded.\n\nDo you wish to proceed, discarding your change?",
                                                     "&Yes", "Yes to &all", "Cancel");
                    if (btn == 2)
                    {
                        return(false);
                    }
                    if (btn == 1)
                    {
                        warned = true;
                    }
                }
            }
            Commits = newCommits;
            return(true);
        }
Пример #3
0
        public override bool AskForValue(string parameterName, ref object value)
        {
            var result = DlgMessage.Show(Prompt, parameterName, DlgType.Question, ReadableNames.Concat("Cancel").ToArray());

            value = result == ReadableNames.Length ? null : Enum.ToObject(EnumType, result);
            return(value != null);
        }
Пример #4
0
        /// <summary>
        /// Saves the level file to the currently selected file name. If none, or
        /// if forceDialog is true, a Save dialog is shown first. Returns true if
        /// saved successfully.
        /// </summary>
        public bool SaveWithDialog(bool forceDialog)
        {
            // Check if have a file name
            if (forceDialog || Program.Settings.LevelFilename == null)
            {
                SaveFileDialog dlg = new SaveFileDialog();
                dlg.DefaultExt       = "txt";
                dlg.Filter           = Program.Tr.Save_FileType_TextFiles + "|*.txt|" + Program.Tr.Save_FileType_AllFiles + "|*.*";
                dlg.InitialDirectory = Program.Settings.LastOpenSaveDirectory;
                DialogResult result = dlg.ShowDialog();

                // If the user cancelled the dialog, bail out
                if (result != DialogResult.OK)
                {
                    return(false);
                }

                // Update the current filename
                Program.Settings.LastOpenSaveDirectory = Path.GetDirectoryName(dlg.FileName);
                Program.Settings.LevelFilename         = dlg.FileName;
            }

            // Just save.
            try
            {
                SaveLevelPack(Program.Settings.LevelFilename);
                return(true);
            }
            catch (Exception e)
            {
                // If anything fails here, don't crash. Just tell the caller that save hasn't actually happened.
                DlgMessage.Show(Program.Tr.LevelList_Message_CannotSaveSettings + "\n" + e.Message, Program.Tr.LevelList_Message_CannotSaveSettings_Title, DlgType.Error);
                return(false);
            }
        }
Пример #5
0
        /// <summary>
        /// Attempts to start a server. If the server is already running, stops it first.
        /// Does not throw any exceptions if the server cannot be started, but  shows a
        /// warning to the user that the server could not be started. The outcome can be
        /// determined via <see cref="ServerRunning"/>.
        /// </summary>
        public void StartServer(HttpServerOptions hsOptions, FileSystemOptions fsOptions = null)
        {
            if (ServerRunning)
            {
                StopServer();
            }

            try
            {
                Resolver = new UrlResolver();
                Server   = new HttpServer(hsOptions)
                {
                    Handler = Resolver.Handle
                };
                Server.StartListening();
                _navLinksPages.Clear();
                RegisterHandlers(fsOptions);
            }
            catch
            {
                try { Server.StopListening(true); }
                catch { }
                Server = null;
                DlgMessage.ShowWarning("The server could not be started. Try a different port (current port is {0}).".Fmt(hsOptions.Endpoints.JoinString()));
            }
        }
Пример #6
0
        /// <summary>Override; see base.</summary>
        protected override void EditCurrentLanguage()
        {
            if (_getCurrentLanguage() == _defaultLanguage)
            {
                DlgMessage.Show("The currently selected language is the native language of this application and cannot be edited.", "Edit current language", DlgType.Info);
                return;
            }
            if (_translationWindow == null)
            {
#if !DEBUG
                try
#endif
                {
                    _translationWindow = new TranslationWindow(typeof(TTranslation), _settings, _icon, _programTitle, _moduleName, _getCurrentLanguage());
                }
#if !DEBUG
                catch (Exception ex)
                {
                    DlgMessage.Show("Translation could not be loaded: " + ex.Message, "Edit current language", DlgType.Info);
                    return;
                }
#endif
                _translationWindow.TranslationChanged += tr => { FireTranslationChanged((TTranslation)tr); };
                _translationWindow.Closed             += delegate { _translationWindow = null; };
            }
            _translationWindow.Show();
        }
Пример #7
0
 private void revert(object sender, EventArgs e)
 {
     if (_currentFilePath != null && DlgMessage.Show("Revert all changes made since last save?", "Revert", DlgType.Question, "&Revert", "&Cancel") == 0)
     {
         openCore(_currentFilePath);
     }
 }
Пример #8
0
        private static IList <TypeInfo <T> > findTypes <T>(string name) where T : IHasTypeNameDescription
        {
            var infos = new List <TypeInfo <T> >();

            foreach (var type in Assembly.GetEntryAssembly().GetTypes().Where(t => typeof(T).IsAssignableFrom(t) && !t.IsAbstract))
            {
                var constructor = type.GetConstructor(new Type[0]);
                if (constructor == null)
                {
                    // (the error message will only be seen by maker developers, so it's ok that it's shown before any UI appears)
                    DlgMessage.ShowWarning("Ignored {1} type \"{0}\" because it does not have a public parameterless constructor.".Fmt(type, name));
                }
                else
                {
                    infos.Add(new TypeInfo <T>
                    {
                        Type        = type,
                        Constructor = () => (T)constructor.Invoke(new object[0]),
                        Name        = type.Name,
                        Description = type.FullName,
                    });
                }
            }
            infos.Sort(CustomComparer <TypeInfo <T> > .By(ti => ti.Name));
            return(infos.AsReadOnly());
        }
Пример #9
0
        private void tryItOnline(object sender, EventArgs e)
        {
            if (null == _lastRendering)
            {
                DlgMessage.ShowError("Nothing to run!");
            }
            else
            {
                const string languageId = "hexagony", fieldSeparator = "\xff";

                var stateString = languageId + fieldSeparator + fieldSeparator
                                  + Regex.Replace(_file.Grid.ToString(), "\r\n", "\n")
                                  + fieldSeparator + fieldSeparator;

                byte[] bytes = new byte[stateString.Length];
                for (int i = 0; i < stateString.Length; ++i)
                {
                    bytes[i] = (byte)stateString[i];
                }

                bytes = Ionic.Zlib.ZlibStream.CompressBuffer(bytes);
                byte[] truncatedHeader = new byte[bytes.Length - 2];
                Array.Copy(bytes, 2, truncatedHeader, 0, truncatedHeader.Length);

                System.Diagnostics.Process.Start("https://tio.run/##" + Regex.Replace(
                                                     System.Convert.ToBase64String(truncatedHeader).Replace('+', '@'),
                                                     "=+", ""));
            }
        }
Пример #10
0
        public override bool AskForValue(string parameterName, ref object value)
        {
            var result = DlgMessage.Show(Prompt, parameterName, DlgType.Question, ReadableFalseName, ReadableTrueName, "Cancel");

            value = result == 0 ? false : result == 1 ? true : (object)null;
            return(result < 2);
        }
Пример #11
0
        /// <summary>Deletes the settings file.</summary>
        public virtual void Delete(string filename = null, SettingsOnFailure onFailure = SettingsOnFailure.Throw)
        {
            // Save and delete must not be interrupted or superseded by a SaveThreaded
            lock (_lock)
            {
                if (_saveThread != null) // this can only ever occur in the Sleep/lock wait phase of the quick save thread
                {
                    _saveThread.Abort();
                    _saveThread = null;
                }
                var attr = SettingsUtil.GetAttribute(GetType());
                if (filename == null)
                {
                    filename = attr.GetFileName();
                }

                if (onFailure == SettingsOnFailure.Throw)
                {
                    File.Delete(filename);
                }
                else if (onFailure == SettingsOnFailure.DoNothing)
                {
                    try { File.Delete(filename); }
                    catch { }
                }
                else
                {
                    while (true)
                    {
                        try
                        {
                            File.Delete(filename);
                            break;
                        }
                        catch (Exception e)
                        {
                            var choices = new List <string>()
                            {
                                "Try &again", "&Don't delete settings"
                            };
                            if (onFailure == SettingsOnFailure.ShowRetryWithCancel)
                            {
                                choices.Add("&Cancel");
                            }
                            int choice = DlgMessage.ShowWarning("Program settings could not be deleted.\n({0})\n\nWould you like to try again?".Fmt(e.Message), choices.ToArray());
                            if (choice == 1)
                            {
                                return;
                            }
                            if (choice == 2)
                            {
                                throw new SettingsCancelException();
                            }
                        }
                    }
                    ;
                }
            }
        }
Пример #12
0
        /// <summary>
        /// Attempts to open the level at the specified index either for playing or editing.
        /// </summary>
        /// <param name="index">The index of the level to be opened, or null to deselect the current level.</param>
        /// <param name="state">Must be <see cref="LevelListBoxState.Playing"/> or <see cref="LevelListBoxState.Editing"/>. Ignored if index is null.</param>
        private void setActiveLevel(int?index, LevelListBoxState state)
        {
            if (LevelActivating != null)
            {
                // Confirm with the owner that the level can be changed
                ConfirmEventArgs args = new ConfirmEventArgs {
                    ConfirmOK = true
                };
                LevelActivating(this, args);
                if (!args.ConfirmOK)
                {
                    return;
                }
            }

            if (index == null)
            {
                _activeLevelIndex = null;
            }
            else if (index.Value < 0 || index.Value >= Items.Count || !(Items[index.Value] is SokobanLevel))
            {
                Ut.InternalError();
            }
            else
            {
                SokobanLevelStatus status;
                if (state == LevelListBoxState.Playing && (status = ((SokobanLevel)Items[index.Value]).Validity) != SokobanLevelStatus.Valid)
                {
                    string problem = status == SokobanLevelStatus.NotEnclosed
                        ? Program.Tr.Mainform_Validity_NotEnclosed
                        : Program.Tr.Mainform_Validity_WrongNumber;
                    if (DlgMessage.Show(Program.Tr.Mainform_Validity_CannotOpen + "\n\n" + problem + "\n\n" + Program.Tr.Mainform_Validity_CannotOpen_Fix,
                                        Program.Tr.Mainform_MessageTitle_OpenLevel, DlgType.Error, Program.Tr.Mainform_Validity_CannotOpen_btnEdit, Program.Tr.Dialogs_btnCancel) == 0)
                    {
                        _state            = LevelListBoxState.Editing;
                        _activeLevelIndex = index.Value;
                    }
                    else
                    {
                        return;
                    }
                }
                else
                {
                    _state            = state;
                    _activeLevelIndex = index.Value;
                }
            }

            RefreshItems();

            // Inform the owner that the level has changed
            LevelActivated(this, new EventArgs());

            // Make the active level selected
            SelectActiveLevel();
        }
Пример #13
0
 private void deletePath(object sender, EventArgs e)
 {
     if (DlgMessage.Show("Are you sure you wish to delete this path?", "Confirmation", DlgType.Question, "&Delete path", "&Cancel") == 0)
     {
         _file.Paths.Remove((HCPath)lstPaths.SelectedItem);
         updateList();
         rerender();
     }
 }
Пример #14
0
        public static void KtaneFriendshipUpDownButtons()
        {
            if (Program.Settings.SelectedVertices.Count != 12)
            {
                DlgMessage.ShowInfo("Need 12 vertices for this tool.");
                return;
            }

            var outerDn = Program.Settings.SelectedVertices.Skip(0).Take(3).Select(pt => Program.Settings.Faces.SelectMany(fc => fc.Vertices).Where(v => v.Location == pt).ToArray()).ToArray();
            var innerDn = Program.Settings.SelectedVertices.Skip(3).Take(3).Select(pt => Program.Settings.Faces.SelectMany(fc => fc.Vertices).Where(v => v.Location == pt).ToArray()).ToArray();
            var outerUp = Program.Settings.SelectedVertices.Skip(6).Take(3).Select(pt => Program.Settings.Faces.SelectMany(fc => fc.Vertices).Where(v => v.Location == pt).ToArray()).ToArray();
            var innerUp = Program.Settings.SelectedVertices.Skip(9).Take(3).Select(pt => Program.Settings.Faces.SelectMany(fc => fc.Vertices).Where(v => v.Location == pt).ToArray()).ToArray();

            var undo = new List <Tuple <VertexInfo, Pt, Pt, Pt?, Pt?> >();

            const double f      = .8 * .1;
            const double innerY = .13;
            const double outerY = .150511;

            for (int k = 0; k < 3; k++)
            {
                // Down
                var innerDnX = (.12 * f * cs(360 * k / 3 + 90) - .052) * 10;
                var innerDnZ = (.12 * f * sn(360 * k / 3 + 90) + .06) * 10;

                var outerDnX = (.16 * f * cs(360 * k / 3 + 90) - .052) * 10;
                var outerDnZ = (.16 * f * sn(360 * k / 3 + 90) + .06) * 10;

                // Up
                var innerUpX = (-.12 * f * cs(360 * k / 3 + 90) - .07) * 10;
                var innerUpZ = (-.12 * f * sn(360 * k / 3 + 90) + .0648) * 10;

                var outerUpX = (-.16 * f * cs(360 * k / 3 + 90) - .07) * 10;
                var outerUpZ = (-.16 * f * sn(360 * k / 3 + 90) + .0648) * 10;

                foreach (var v in outerDn[k])
                {
                    undo.Add(Tuple.Create(v, v.Location, new Pt(outerDnX, outerY, outerDnZ), v.Normal, new Pt(0, 1, 0).Nullable()));
                }
                foreach (var v in innerDn[k])
                {
                    undo.Add(Tuple.Create(v, v.Location, new Pt(innerDnX, innerY, innerDnZ), v.Normal, v.Normal));
                }
                foreach (var v in outerUp[k])
                {
                    undo.Add(Tuple.Create(v, v.Location, new Pt(outerUpX, outerY, outerUpZ), v.Normal, new Pt(0, 1, 0).Nullable()));
                }
                foreach (var v in innerUp[k])
                {
                    undo.Add(Tuple.Create(v, v.Location, new Pt(innerUpX, innerY, innerUpZ), v.Normal, v.Normal));
                }
            }

            Program.Settings.Execute(new MoveVertices(undo.ToArray()));
        }
Пример #15
0
        static void enterMoveMode()
        {
            if (_selectedBox == null)
            {
                DlgMessage.Show("No item is selected.", "Error", DlgType.Error);
                return;
            }

            _mode = EditMode.Moving;
            Invalidate(_selectedBox);
        }
 private void ok(object sender, RoutedEventArgs e)
 {
     if (_promptSure != null && _checkItems.Count(item => item.IsChecked) > 0)
     {
         if (DlgMessage.ShowWarning(_promptSure, _promptSureYes, App.Translation.Prompt.Cancel) != 0)
         {
             return;
         }
     }
     DialogResult = true;
 }
Пример #17
0
        private bool compile(ExecutionState state)
        {
            removeRunToCursorBreakpoint();
            _currentPosition = null;

            if (_env != null)
            {
                _env.State = state;
                return(true);
            }

            if (_saveWhenRun)
            {
                save();
            }

            try
            {
                _env = _currentLanguage.Compile(txtSource.Text, _input ?? "");
                _env.OriginalSource     = txtSource.Text;
                _env.State              = state;
                _env.DebuggerBreak     += p => { this.BeginInvoke(new Action(() => debuggerBreak(p))); };
                _env.ExecutionFinished += (c, e) => { this.BeginInvoke(new Action(() => executionFinished(c, e))); };
                foreach (int bp in lstBreakpoints.Items)
                {
                    _env.AddBreakpoint(bp);
                }
                _env.BreakpointsChanged += () => { this.BeginInvoke(new Action(() => breakpointsChanged())); };
                tabWatch.Controls.Clear();
                tabWatch.Controls.Add(_env.InitializeWatchWindow());
                if (EsotericIDEProgram.Settings.WatchFont != null)
                {
                    _env.SetWatchWindowFont(EsotericIDEProgram.Settings.WatchFont);
                }
                return(true);
            }
            catch (CompileException e)
            {
                if (e.Index != null)
                {
                    txtSource.Focus();
                    txtSource.SelectionStart  = e.Index.Value;
                    txtSource.SelectionLength = e.Length ?? 0;
                    txtSource.ScrollToCaret();
                }
                DlgMessage.Show("Compilation failed:" + Environment.NewLine + e.Message, "Esoteric IDE", DlgType.Error, "&OK");
                return(false);
            }
            catch (Exception e)
            {
                DlgMessage.Show("Compilation failed:" + Environment.NewLine + e.Message + " (" + e.GetType().FullName + ")", "Esoteric IDE", DlgType.Error, "&OK");
                return(false);
            }
        }
Пример #18
0
 private void copyHexagonySource(object sender, EventArgs e)
 {
     if (null == _lastRendering)
     {
         DlgMessage.ShowError("Nothing to copy!");
     }
     else
     {
         System.Windows.Forms.Clipboard.SetText(_file.Grid.ToString());
     }
 }
Пример #19
0
        /// <summary>
        /// Invoked by "Help => Help". Displays the helpfile.
        /// </summary>
        private void help(object sender, EventArgs e)
        {
            string helpfile = PathUtil.AppPathCombine("ExpSok.chm");

            if (File.Exists(helpfile))
            {
                Help.ShowHelp(this, helpfile, HelpNavigator.TopicId, "20");
            }
            else
            {
                DlgMessage.ShowWarning(Program.Tr.Mainform_Error_HelpFileNotFound.Fmt(helpfile), null);
            }
        }
Пример #20
0
 private void miOpenInBrowser_Click(object sender, EventArgs e)
 {
     if (Program.Interface.ServerRunning)
     {
         ProcessStartInfo si = new ProcessStartInfo("http://localhost:{0}".Fmt(Program.Interface.ServerPort));
         si.UseShellExecute = true;
         Process.Start(si);
     }
     else
     {
         DlgMessage.ShowInfo(Program.Tr.Warning_CannotOpenInBrowser);
     }
 }
Пример #21
0
 private void openCore(string filePath)
 {
     if (!File.Exists(filePath))
     {
         DlgMessage.Show("The specified file does not exist.", "Error", DlgType.Error);
         return;
     }
     _currentFilePath = filePath;
     _file            = ClassifyJson.Deserialize <HCFile>(JsonValue.Parse(File.ReadAllText(_currentFilePath)));
     _anyChanges      = false;
     // _lastFileTime = File.GetLastWriteTimeUtc(_currentFilePath);
     updateList();
     rerender();
 }
Пример #22
0
        private void insertByteArray(IIde ide)
        {
            string @default, selected = ide.GetSelectedText();

            try { @default = ScliptingUtil.DecodeByteArray(selected).ToHex(); }
            catch { @default = ""; }
            var line = InputBox.GetLine("Type a byte array to insert (in hexdump format; two hexadecimal digits per byte):", @default, "Esoteric IDE", "&OK", "&Cancel");

            if (line != null)
            {
                try { ide.InsertText(ScliptingUtil.EncodeByteArray(line.FromHex())); }
                catch { DlgMessage.Show("The text you entered is not valid hexadecimal. Please ensure that you enter an even number of characters 0-9/a-f.", "Esoteric IDE", DlgType.Error, "&OK"); }
            }
        }
Пример #23
0
        public void ReloadRepo()
        {
            Repository repo;

            try
            {
                repo = new Repository(RepoPath);
            }
            catch
            {
                DlgMessage.ShowWarning("It looks like there is no valid Git repository at this path anymore. Please use “Browse” to load from another path.");
                return;
            }
            LoadCommitsPreserveChanges(repo.Commits.Select(commit => new CommitModel(commit)).ToList(), true);
        }
Пример #24
0
 private void mouseDown(object sender, MouseEventArgs e)
 {
     if (_lastRendering != null)
     {
         _lastMouseDown = _file.FromScreen(e.X, e.Y);
         if (e.Button == MouseButtons.Right)
         {
             mnuContext.Show(ctImage, e.Location);
         }
         else
         {
             DlgMessage.Show("The position you clicked is: " + _lastMouseDown.ToString(), "Axial coordinates", DlgType.Info);
         }
     }
 }
Пример #25
0
 /// <summary>
 /// Creates a new compressor of a specified name. Use to obtain an actual compressor
 /// instance given an algorithm name.
 /// </summary>
 public static Compressor GetCompressor(string name)
 {
     if (Compressors.ContainsKey(name))
     {
         Compressor compr = (Compressor)Compressors[name].GetConstructor(new Type[] { }).Invoke(new object[] { });
         compr.Name = name;
         return(compr);
     }
     else
     {
         DlgMessage.ShowError("Compressor named {0} is not defined".Fmt(name));
         Environment.Exit(1);
         return(null);
     }
 }
Пример #26
0
 private EventHandler checkDebugging(IIde ide, Action <HexagonyEnv> action)
 {
     return((_, __) =>
     {
         var env = ide.GetEnvironment() as HexagonyEnv;
         if (env == null || env.State != ExecutionState.Debugging)
         {
             DlgMessage.Show("Program must be running but stopped in the debugger.", "Error", DlgType.Error);
         }
         else
         {
             action(env);
         }
     });
 }
Пример #27
0
        /// <summary>
        /// Activates the previous level for playing. Wraps around and starts from the
        /// last level if necessary. If no previous level is found, an appropriate
        /// message is displayed to the user. The function will trigger the
        /// LevelActivating event before activating the level.
        /// </summary>
        /// <param name="mustBeUnsolved">Specifies whether to activate the immediately
        /// previous level (false) or the previous unsolved level (true).</param>
        public void PlayPrev(bool mustBeUnsolved)
        {
            int?i = findPrevNext(mustBeUnsolved, false);

            if (i == null)
            {
                DlgMessage.Show(
                    mustBeUnsolved ? Program.Tr.LevelList_Message_NoMoreUnsolved : Program.Tr.LevelList_Message_NoOtherLevel,
                    mustBeUnsolved ? Program.Tr.LevelList_Message_PrevUnsolved_Title : Program.Tr.LevelList_Message_Prev_Title,
                    DlgType.Info, Program.Tr.Dialogs_btnOK);
            }
            else
            {
                playingIndex = i.Value;
            }
        }
Пример #28
0
 private void openCore(string filePath)
 {
     if (!File.Exists(filePath))
     {
         DlgMessage.Show("The specified file does not exist.", "Error", DlgType.Error);
         return;
     }
     _currentFilePath             = filePath;
     txtSource.Text               = File.ReadAllText(_currentFilePath).UnifyLineEndings();
     txtOutput.Text               = "";
     _timerPreviousSource         = txtSource.Text;
     _timerPreviousCursorPosition = -1;
     sourceTextboxFixHack();
     _anyChanges   = false;
     _lastFileTime = File.GetLastWriteTimeUtc(_currentFilePath);
 }
Пример #29
0
        public static void KtaneFriendshipSubmitButton()
        {
            if (!Program.Settings.IsFaceSelected || Program.Settings.SelectedFaces.Count != 1)
            {
                DlgMessage.ShowInfo("Need exactly one selected face for this tool.");
                return;
            }
            var face = Program.Settings.SelectedFaces[0];

            const double centerX     = -0.64;
            const double centerZ     = 0.3;
            const double innerRadius = .16; // .2 × .8
            const double outerRadius = .18;
            const double innerY      = .13;
            const double outerY      = .150511;
            const int    steps       = 72;

            var newFaces = new List <Face>();

            foreach (var inf in Enumerable.Range(0, steps).Select(k => 360.0 * k / steps).Select(angle => new
            {
                Inner = new Pt(innerRadius * cs(angle) + centerX, innerY, innerRadius * sn(angle) + centerZ),
                Outer = new Pt(outerRadius * cs(angle) + centerX, outerY, outerRadius * sn(angle) + centerZ)
            }).ConsecutivePairs(true))
            {
                var i1 = inf.Item1;
                var i2 = inf.Item2;

                // Bevel
                newFaces.Add(new Face(Ut.NewArray(
                                          new VertexInfo(i2.Inner, null, new Pt(centerX, innerY, centerZ) - i2.Inner),
                                          new VertexInfo(i2.Outer, null, new Pt(0, 1, 0)),
                                          new VertexInfo(i1.Outer, null, new Pt(0, 1, 0)),
                                          new VertexInfo(i1.Inner, null, new Pt(centerX, innerY, centerZ) - i1.Inner))));

                // Rim
                var closest1 = face.Vertices.MinElement(v => v.Location.Distance(i1.Outer));
                var closest2 = face.Vertices.MinElement(v => v.Location.Distance(i2.Outer));
                newFaces.Add(new Face(
                                 (closest1 == closest2 ? new[] { i1.Outer, i2.Outer, closest1.Location } : new[] { i1.Outer, i2.Outer, closest2.Location, closest1.Location })
                                 .Select(v => new VertexInfo(v, null, new Pt(0, 1, 0)))
                                 .ToArray()));
            }

            Program.Settings.Execute(new AddRemoveFaces(new[] { face }, newFaces.ToArray()));
        }
Пример #30
0
 private void checkFileChanged()
 {
     // Make sure this is not called while it is already running, which would
     // happen because dismissing the DlgMessage triggers activated()
     if (!_checkFileChangedBusy)
     {
         _checkFileChangedBusy = true;
         if (_currentFilePath != null &&
             File.Exists(_currentFilePath) &&
             File.GetLastWriteTimeUtc(_currentFilePath) > _lastFileTime &&
             DlgMessage.Show("The file has changed on disk. Reload?", "File has changed", DlgType.Question, "&Reload", "&Cancel") == 0)
         {
             openCore(_currentFilePath);
         }
         _checkFileChangedBusy = false;
     }
 }