public void BeginCreateDocument(TankInstance tank, IProgressScope progress, Action <CreateDocumentResult> callback)
        {
            Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
            {
                progress.ReportStatusMessage(this.L("stat_inspector", "status_analysing"));
                progress.ReportIsIndetermine();

                this.LogInfo("creating document from template file '{0}'", this.Filename);
                var document = this.LoadTemplate();
                progress.ReportProgress(0);

                var decendants = LogicalTreeHelperEx.GetDecendants <TextElement>(document).ToArray();
                var statVms    = new Dictionary <IStat, StatVM>();

                var completedDecendant = 0;

                foreach (var decendant in decendants)
                {
                    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                    {
                        var key = StatBehaviors.GetKey(decendant);
                        if (key != null)
                        {
                            var stat = StatsProviderManager.Instance.GetStat(key);
                            if (stat == null)
                            {
                                this.LogWarning("unknown stat: key='{0}'", key);
                                return;
                            }

                            var statVm = statVms.GetOrCreate(stat, () => new StatVM(stat, tank));

                            decendant.DataContext = statVm;

                            if (decendant is IAddChild)
                            {
                                this.ApplyTemplate(decendant);
                            }

                            ++completedDecendant;
                            progress.ReportProgress((double)completedDecendant / decendants.Length);
                        }
                    }), DispatcherPriority.Background);
                }

                Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                {
                    progress.ReportIsIndetermine();
                    callback(new CreateDocumentResult(document, statVms.Values));
                    progress.ReportProgress(1.0);
                }), DispatcherPriority.Background);
            }), DispatcherPriority.Background);
        }
Пример #2
0
        public override ValidationResult Validate(object value, CultureInfo cultureInfo, BindingExpressionBase owner)
        {
            string name       = (string)value;
            var    expression = owner as BindingExpression;

            if (expression.ResolvedSource is PObject pObj)
            {
                var renderer = pObj.GetRenderer();

                if (renderer != null)
                {
                    var scope = LogicalTreeHelperEx.FindLogicalParents <INameScope>(renderer.Element).FirstOrDefault();

                    if (pObj.Equals(scope.GetOwner(name)))
                    {
                        return(base.Validate(true, cultureInfo, owner));
                    }

                    if (string.IsNullOrEmpty(name))
                    {
                        scope.Unregister(pObj);

                        return(base.Validate(true, cultureInfo, owner));
                    }

                    if (Core.StringRule.IsValidName(name ?? "", true))
                    {
                        if (scope.HasName(name))
                        {
                            MessageBox.Show($"'{name}'는 이미 정의된 이름입니다.", "DeXign", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                            expression.UpdateTarget();
                        }
                        else
                        {
                            scope.Register(pObj, name);

                            return(base.Validate(true, cultureInfo, owner));
                        }
                    }
                }
                else
                {
                    MessageBox.Show($"네임 스코프를 찾을 수 없습니다.", "DeXign");
                }
            }

            return(base.Validate(false, cultureInfo, owner));
        }
Пример #3
0
 private void TabChanged(object sender, SelectionChangedEventArgs e)
 {
     if (e.Source is TabControl)
     {
         // are we being added or removed?
         var gameParent = LogicalTreeHelperEx.FindParent <TabItem>(this);
         if (e.AddedItems.Contains(gameParent))
         {
             // added
             IsActive = true;
         }
         else if (e.RemovedItems.Contains(gameParent))
         {
             // removed
             IsActive = false;
         }
     }
 }
Пример #4
0
        protected override void Initialize()
        {
            // init is only called once per game
            _numberOfInitializeCalls++;

            new WpfGraphicsDeviceService(this);

            base.Initialize();
            // not really pretty, but gets the job done
            var parent = LogicalTreeHelperEx.FindParent <Window>(this) as ILogToUi;

            _logger = parent ?? throw new NotSupportedException("This scene only works on windows that support ILogToUi right now");

            _text = new TextComponent(this, "dummy", new Vector2(0, 0));
            Components.Add(_text);
            _id = ++Counter;
            _logger.Log($"Tabbed game {_id} initialize");
            Activated   += OnActivated;
            Deactivated += OnDeactivated;
        }
Пример #5
0
        private void OnWindowActivated(object sender, EventArgs e)
        {
            var tabControl = LogicalTreeHelperEx.FindParent <TabControl>(this);
            // if there is any parent that is a tabitem, we must be inside a TabControl
            //
            var windowIsInTab = tabControl != null;

            if (windowIsInTab)
            {
                // inside a tab, check whether the tab is active
                var tabItem = LogicalTreeHelperEx.FindParent <TabItem>(this);
                // only set to true for the currently active tab
                IsActive = tabControl.SelectedItem == tabItem;
            }
            else
            {
                // regular control on the window
                IsActive = true;
            }
        }
        private void HandleMouse(object sender, MouseEventArgs e)
        {
            if (e.Handled)
            {
                return;
            }

            if (e.LeftButton == MouseButtonState.Pressed)
            {
            }

            var pos = e.GetPosition(_focusElement);

            if (!CaptureMouseWithin)
            {
                // clamp as fast moving mouse will somtimes still report values outside the control without explicit capture (e.g. negative values)
                pos = new Point(Clamp(pos.X, 0, _focusElement.ActualWidth), Clamp(pos.Y, 0, _focusElement.ActualHeight));
            }
            if (_focusElement.IsMouseDirectlyOver && System.Windows.Input.Keyboard.FocusedElement != _focusElement)
            {
                //if (WindowHelper.IsControlOnActiveWindow(_focusElement))
                {
                    // however, only focus if we are the active window, otherwise the window will become active and pop into foreground just by hovering the mouse over the game panel

                    //finally check if user wants us to focus already on mouse over
                    //if (_focusElement.FocusOnMouseOver)
                    if (e.LeftButton == MouseButtonState.Pressed)
                    {
                        var           res    = LogicalTreeHelperEx.FindParent <Grid>(_focusElement);
                        HitTestResult result = VisualTreeHelper.HitTest(res, pos);
                        if (result?.VisualHit == _focusElement)
                        {
                            _focusElement.Focus();
                        }
                    }
                    //else
                    //{
                    //    // otherwise focus only when the user clicks into the game
                    //    // on windows this behaviour doesn't require an explicit left click
                    //    // instead, left, middle, right and even xbuttons work (the only thing that doesn't trigger focus is scrolling)
                    //    // so mimic that exactly
                    //    if (e.LeftButton == MouseButtonState.Pressed ||
                    //        e.RightButton == MouseButtonState.Pressed ||
                    //        e.MiddleButton == MouseButtonState.Pressed ||
                    //        e.XButton1 == MouseButtonState.Pressed ||
                    //        e.XButton2 == MouseButtonState.Pressed)
                    //    {
                    //        _focusElement.Focus();
                    //    }
                    //}
                }
            }

            if ((!_focusElement.IsMouseDirectlyOver || _focusElement.IsMouseCaptured) && CaptureMouseWithin)
            {
                var  v   = (Visual)_focusElement;
                bool hit = false;
                //VisualTreeHelper.HitTest(v, filterTarget => HitTestFilterBehavior.Continue, target =>
                //{
                //    if (target.VisualHit == _focusElement)
                //    {
                //        // our actual element was hit
                //        hit = true;
                //    }
                //    return HitTestResultBehavior.Continue;
                //}, new PointHitTestParameters(pos));

                var           res    = LogicalTreeHelperEx.FindParent <Grid>(_focusElement);
                HitTestResult result = VisualTreeHelper.HitTest(res, pos);
                if (result?.VisualHit == _focusElement)
                {
                    hit = true;
                }



                // IsMouseDirectlyOver always returns true if the mouse is captured, so we need to do our own hit testing if the Mouse is captured to find out whether it is actually over the control or not
                if (hit)
                {
                    //{
                    //    // outside the hitbox
                    //
                    //    // when the mouse is leaving the control we need to register button releases
                    //    // when the user clicks in the control, holds the button and moves it outside the control and releases there it normally does not registered
                    //    // the control would thus think that the button is still pressed
                    //    // using capture allows us to receive this event, propagate it and then free the mouse
                    //
                    //    _mouseState = new MouseState(_mouseState.X, _mouseState.Y, _mouseState.ScrollWheelValue,
                    //        (ButtonState) e.LeftButton, (ButtonState) e.MiddleButton, (ButtonState) e.RightButton, (ButtonState) e.XButton1,
                    //        (ButtonState) e.XButton2);
                    //    // only release if LeftMouse is up
                    //    if (e.LeftButton == MouseButtonState.Released)
                    //    {
                    //        _focusElement.ReleaseMouseCapture();
                    //    }
                    //    e.Handled = true;
                    //    return;
                    //}
                    // inside the control and captured -> still requires full update, so run code below and don't return right away
                }
                else
                {
                    if (_focusElement.IsMouseCaptured)
                    {
                        _mouseState = new MouseState(_mouseState.X, _mouseState.Y, _mouseState.ScrollWheelValue,
                                                     (ButtonState)e.LeftButton, (ButtonState)e.MiddleButton, (ButtonState)e.RightButton, (ButtonState)e.XButton1,
                                                     (ButtonState)e.XButton2);
                        // only release if LeftMouse is up
                        if (e.LeftButton == MouseButtonState.Released)
                        {
                            _focusElement.ReleaseMouseCapture();
                        }
                        e.Handled = true;
                    }

                    // mouse is outside the control and not captured, so don't update the mouse state
                    return;
                }
            }

            if (CaptureMouseWithin)
            {
                // capture the mouse, this allows receiving of mouse event while the mouse is leaving the control: https://msdn.microsoft.com/en-us/library/ms591452(v=vs.110).aspx
                if (!_focusElement.IsMouseCaptured)
                {
                    // however, only focus if we are the active window, otherwise the window will become active and pop into foreground just by hovering the mouse over the game panel
                    //if (WindowHelper.IsControlOnActiveWindow(_focusElement))
                    //if ()
                    {
                        // however, only focus if we are the active window, otherwise the window will become active while remaining in the background
                        //
                        if (e.LeftButton == MouseButtonState.Pressed)
                        {
                            _focusElement.CaptureMouse();
                        }
                    }
                    //else
                    //{
                    //    // don't update mouse events if we are just hovering over different window
                    //    return;
                    //}
                }
            }
            else
            {
                if (_focusElement.IsFocused && !WindowHelper.IsControlOnActiveWindow(_focusElement))
                {
                    // don't update mouse events if we are just hovering over different window
                    return;
                }
            }
            e.Handled = true;
            var m = _mouseState;
            var w = e as MouseWheelEventArgs;

            _mouseState = new MouseState((int)pos.X, (int)pos.Y, m.ScrollWheelValue + (w?.Delta ?? 0), (ButtonState)e.LeftButton, (ButtonState)e.MiddleButton, (ButtonState)e.RightButton, (ButtonState)e.XButton1, (ButtonState)e.XButton2);
        }
Пример #7
0
        private void OnLoaded(object sender, RoutedEventArgs eventArgs)
        {
            if (IsInDesignMode || _loaded)
            {
                return;
            }

            _loaded = true;

            // get the current window and register Activate/Deactivate
            var window = LogicalTreeHelperEx.FindParent <Window>(this);

            if (window == null)
            {
                throw new NotSupportedException("The game control does not have a parent window, this is currently not supported");
            }

            window.Activated   += OnWindowActivated;
            window.Deactivated += OnWindowDeactivated;
            window.Closed      += OnWindowClosed;
            var tabControl = LogicalTreeHelperEx.FindParent <TabControl>(this);
            // if there is any parent that is a tabitem, we must be inside a TabControl
            //
            var windowIsInTab = tabControl != null;

            if (windowIsInTab)
            {
                // also hook up to tab events
                tabControl.SelectionChanged += TabChanged;
            }
            // check whether current window is indeed the active one (usually it will be)
            // but there are some edge cases (programmatically show a tab with this game control after a timer) -> window doesn't have to be active
            var active = Application.Current.Windows.OfType <Window>().SingleOrDefault(x => x.IsActive);

            if (active == window && IsVisible)
            {
                IsActive = true;
            }

            if (!_graphicsDeviceInitialized)
            {
                //InitializeGraphicsDevice();
                _graphicsDeviceInitialized = true;
            }
            _spriteBatch = new SpriteBatch(_graphicsDevice);
            InitializeImageSource();

            // workaround for exceptions in Onloaded being swallowed by default on x64
            // https://stackoverflow.com/questions/4807122/wpf-showdialog-swallowing-exceptions-during-window-load
            try
            {
                // initialize runs in userland
                // user can f**k up anything an have an exception thrown
                // if it throws, we don't want rendering to start
                Initialize();
                StartRendering();
            }
            catch (Exception ex)
            {
                if (Environment.Is64BitOperatingSystem || Environment.Is64BitProcess)
                {
                    // catch and rethrow because WPF just swallows it silently on x64..
                    BackgroundWorker deCancerifyWpf = new BackgroundWorker();
                    deCancerifyWpf.DoWork             += (e, arg) => { arg.Result = arg.Argument; };
                    deCancerifyWpf.RunWorkerCompleted += (e, arg) =>
                    {
                        // who needs a proper stacktrace anyway
                        // at least we get to see the exception..
                        throw new Exception("Initialize failed, see inner exception for details.", (Exception)arg.Result);
                    };
                    deCancerifyWpf.RunWorkerAsync(ex);
                }
            }
        }