/// <summary>
        /// Implements the reducer function
        /// </summary>
        /// <param name="state">Current state</param>
        /// <param name="action">Action</param>
        /// <returns></returns>
        private static AppState ReduceWindowState(AppState state, IReducerAction action)
        {
            if (!(action is WindowActionBase windowAction))
            {
                return(state);
            }
            switch (windowAction)
            {
            case MaximizeWindowAction _:
                if (state.WindowState != WindowState.Maximized)
                {
                    s_Worker?.Invoke(WindowState.Maximized);
                    return(state.Assign(s => s.WindowState = WindowState.Maximized));
                }
                return(state);

            case MinimizeWindowAction _:
                if (state.WindowState != WindowState.Minimized)
                {
                    s_Worker?.Invoke(WindowState.Minimized);
                    return(state.Assign(s => s.WindowState = WindowState.Minimized));
                }
                return(state);

            case RestoreWindowAction _:
                if (state.WindowState != WindowState.Normal)
                {
                    s_Worker?.Invoke(WindowState.Normal);
                    return(state.Assign(s => s.WindowState = WindowState.Normal));
                }
                return(state);

            case AppGotFocusAction _:
                return(state.Assign(s => s.HasFocus = true));

            case AppLostFocusAction _:
                return(state.Assign(s => s.HasFocus = false));

            case CloseWindowAction _:
                s_Worker?.Invoke(WindowState.ToClose);
                return(state.Assign(s => s.WindowState = WindowState.ToClose));

            default:
                return(state);
            }
        }
Exemple #2
0
        /// <summary>
        /// Dispatches the specified actions, and sets
        /// the new state of the store accordingly.
        /// </summary>
        /// <param name="action">Action to dispatch</param>
        /// <returns>
        /// The new state of the store.
        /// </returns>
        /// <remarks>
        /// The action forst goes through the chain of middleware objects,
        /// starting from the first one. Middleware objects can vote to abandone
        /// the dispatch process. Though they can, they should not change the
        /// app state.
        ///
        /// If a middleware votes for abandon the dispatch process, the subsequent
        /// middleware objects are skipped; the reducer would not be dispatched.
        /// After going through the middlewares, all reducers are invoked, starting
        /// with the first.
        ///
        /// Whenever the new state is different from the previous one, the StateChanged
        /// event is raised.
        /// </remarks>
        public TState Dispatch(IReducerAction action)
        {
            var oldState = _lastState;

            // --- Go through middlewares
            var goOn = true;

            foreach (var middleware in _middlewares)
            {
                if (!(goOn = middleware(this, action)))
                {
                    break;
                }
            }

            // --- Call the reducer, provided the middleware does
            // --- not abandon
            if (goOn)
            {
                lock (_syncRoot)
                {
                    foreach (var reducer in _reducers)
                    {
                        _lastState = reducer(_lastState, action);
                    }
                }
            }

            // --- Check for change
            var stateHasChanged = typeof(TState) is IEqualityComparer <TState>
                                  ? !(oldState as IEqualityComparer <TState>).Equals(_lastState as IEqualityComparer <TState>)
                                      : (object)oldState != (object)_lastState;

            if (stateHasChanged)
            {
                StateChanged?.Invoke(oldState, _lastState);
            }
            return(_lastState);
        }
 /// <summary>
 /// Dispatches the specified action.
 /// </summary>
 /// <param name="action">Action to dispatch</param>
 public void Dispatch(IReducerAction action)
 {
     StateStore.Dispatch(action);
 }
Exemple #4
0
        /// <summary>
        /// Implements the reducer function
        /// </summary>
        /// <param name="state">Current state</param>
        /// <param name="action">Action</param>
        /// <returns></returns>
        private static AppState ReduceAppMenuState(AppState state, IReducerAction action)
        {
            if (!(action is MenuActionBase menuAction))
            {
                return(state);
            }
            switch (menuAction)
            {
            case SetAppMenuAction setAppMenuAction:
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a => a.AppMenu = setAppMenuAction.AppMenu)));

            case MenuAltPressedAction _:
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                {
                    a.HighlightAccessKeys = s.MenuState.SelectedIndex < 0;
                    a.OpenPanes = new List <MenuPaneInfo>();
                    a.KeyboardAction = true;
                })));

            case MenuAltReleasedAction _:
                var itemIndex = state.MenuState.SelectedIndex < 0 ? 0 : -1;
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                {
                    a.SelectedIndex = itemIndex;
                    a.HighlightAccessKeys = itemIndex >= 0;
                    a.KeyboardAction = true;
                })));

            case MenuPaneClosedAction _:
            {
                var(parentPanes, lastPane) = GetOpenMenuPanes(state.MenuState);
                if (lastPane != null)
                {
                    return(state.Assign(
                               s => s.MenuState = s.MenuState.Assign(
                                   a =>
                        {
                            a.OpenPanes = parentPanes;
                            a.KeyboardAction = true;
                        })));
                }
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.SelectedIndex = -1;
                        a.HighlightAccessKeys = false;
                        a.KeyboardAction = true;
                    })));
            }

            case MenuButtonSetAction menuButtonSetAction:
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                {
                    a.SelectedIndex = menuButtonSetAction.ItemIndex;
                    a.OpenPanes = menuButtonSetAction.Pane != null
                                    ? new List <MenuPaneInfo> {
                        menuButtonSetAction.Pane
                    }
                                    : new List <MenuPaneInfo>();
                    a.KeyboardAction = menuButtonSetAction.KeyboardAction;
                })));

            case MenuItemDownAction _:
            {
                var(parentPanes, lastPane) = GetOpenMenuPanes(state.MenuState);
                if (lastPane == null)
                {
                    return(state);
                }
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.OpenPanes = parentPanes.Concat(
                            new List <MenuPaneInfo> {
                            lastPane.Assign(lp => lp.SelectedIndex = GetNextMenuItemIndex(lp, 1))
                        }).ToList();
                    })));
            }

            case MenuItemUpAction _:
            {
                var(parentPanes, lastPane) = GetOpenMenuPanes(state.MenuState);
                if (lastPane == null)
                {
                    return(state);
                }
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.OpenPanes = parentPanes.Concat(
                            new List <MenuPaneInfo> {
                            lastPane.Assign(lp => lp.SelectedIndex = GetNextMenuItemIndex(lp, -1))
                        }).ToList();
                    })));
            }

            case MenuPaneOpenAction menuPaneOpenAction:
            {
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.OpenPanes = a.OpenPanes.Concat(
                            new List <MenuPaneInfo> {
                            menuPaneOpenAction.Pane
                        }).ToList();
                        a.KeyboardAction = menuPaneOpenAction.KeyboardAction;
                    })));
            }

            case MenuCloseAllPanesAction _:
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                {
                    a.SelectedIndex = -1;
                    a.HighlightAccessKeys = false;
                    a.OpenPanes = new List <MenuPaneInfo>();
                    a.KeyboardAction = false;
                })));

            case MenuItemSelectAction menuItemSelectAction:
            {
                var(parentPanes, lastPane) = GetOpenMenuPanes(state.MenuState);
                if (lastPane == null)
                {
                    return(state);
                }
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.OpenPanes = parentPanes.Concat(
                            new List <MenuPaneInfo>
                        {
                            lastPane.Assign(lp => lp.SelectedIndex = menuItemSelectAction.Index)
                        }).ToList();
                        a.KeyboardAction = true;
                    })));
            }

            case MenuButtonClickAction menuButtonClickAction:
            {
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.SelectedIndex = menuButtonClickAction.Index;
                        a.OpenPanes = new List <MenuPaneInfo>
                        {
                            menuButtonClickAction.Pane
                        };
                        a.KeyboardAction = false;
                    })));
            }

            case MenuKeepPaneAction menuKeepPaneAction:
            {
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.OpenPanes = a.OpenPanes.Take(menuKeepPaneAction.PaneIndex + 1).ToList();
                        a.KeyboardAction = false;
                    })));
            }

            case MenuItemPointAction menuItemPointAction:
            {
                var panes     = state.MenuState.OpenPanes.ToList();
                var paneIndex = menuItemPointAction.PaneIndex;
                if (paneIndex < 0 || paneIndex >= panes.Count)
                {
                    return(state);
                }
                var pane          = panes[menuItemPointAction.PaneIndex];
                var selectedIndex = menuItemPointAction.ItemIndex >= 0
                            ? pane.Items.Flatten().ToArray()[menuItemPointAction.ItemIndex].Enabled
                                ? menuItemPointAction.ItemIndex
                                : -1
                            : -1;
                panes[menuItemPointAction.PaneIndex] = new MenuPaneInfo
                {
                    Items         = pane.Items,
                    ParentIndex   = pane.ParentIndex,
                    LeftPos       = pane.LeftPos,
                    TopPos        = pane.TopPos,
                    SelectedIndex = selectedIndex
                };
                return(state.Assign(
                           s => s.MenuState = s.MenuState.Assign(
                               a =>
                    {
                        a.OpenPanes = panes;
                        a.KeyboardAction = false;
                    })));
            }

            default:
                return(state);
            }
Exemple #5
0
 /// <summary>
 /// Dispatches the specified actions, and sets
 /// the new state of the store accordingly.
 /// </summary>
 /// <param name="action">Action to dispatch</param>
 /// <returns>
 /// The new state of the store.
 /// </returns>
 public static AppState Dispatch(IReducerAction action)
 => s_Store.Dispatch(action);