pebble/src/fw/kernel/ui/modals/modal_manager.h
Josh Soref d4d8ed5147 spelling: priority
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2025-01-29 00:03:27 -05:00

176 lines
8.1 KiB
C

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "modal_manager_private.h"
#include "applib/graphics/graphics.h"
#include "applib/ui/click_internal.h"
#include "applib/ui/window.h"
#include "applib/ui/window_stack_animation.h"
#include "applib/ui/window_stack_private.h"
#include "kernel/events.h"
struct ModalContext;
typedef struct ModalContext ModalContext;
typedef bool (*ModalContextFilterCallback)(ModalContext *context, void *data);
//! This defines the priorities for the various modals. The order in which they are
//! defined is specified by the interruption policy and determine who is able to interrupt
//! whom. If a modal has a higher priority than another modal, it is able to interrupt
//! that modal. Before adding anything to here, consider how it would affect the interrupt
//! policy.
//! Interruption Policy:
//! https://docs.google.com/presentation/d/1xIjOR9kh4jcBYonzRstdtFQW0ZNMoFZZwYOUMN2JHNI
typedef enum ModalPriority {
//! Invalid priority for a modal.
ModalPriorityInvalid = -1,
//! Min priority, all modals are below or equal to this priority.
ModalPriorityMin = 0,
//! Discreet mode for watchface overlay information such as Timeline Peek.
//! This priority should be used for modals that meant to display above the watchface without
//! completely obstructing the watchface. For this reason, Discreet modal windows do not have
//! compositor transitions because partial obstruction requires notifying the app of the
//! unobstructed regions which only the modal window is able to derive.
ModalPriorityDiscreet = ModalPriorityMin,
//! Priority for generic one-off windows such as the battery charging window.
//! This priority should be used for any modals that don't necessarily care how
//! they are shown, just that they are shown.
ModalPriorityGeneric,
//! Priority used for displaying the phone ui after a phone call has been answered.
//! Note: Notifications should always be able to subvert this.
ModalPriorityPhone,
//! Priority used for displaying notifications.
ModalPriorityNotification,
//! Priority used for displaying alerts. Alerts are important, but shouldn't
//! impact the user of the watch.
ModalPriorityAlert,
//! Priority used for displaying the voice screen for recording. Ensure this one is
//! always kept second to last.
ModalPriorityVoice,
//! Priority for displaying time-sensitive/critical windows which provide information
//! on things that may affect the user's watch experience. However, these should never
//! prevent an alarm from displaying.
ModalPriorityCritical,
//! Priority used for displaying wake up events such as alarms.
ModalPriorityAlarm,
//! Max priority, all modals are below this priority
ModalPriorityMax,
NumModalPriorities = ModalPriorityMax,
} ModalPriority;
typedef enum ModalProperty {
ModalProperty_None = 0,
//! Whether there exists a modal in a modal stack on screen.
ModalProperty_Exists = (1 << 0),
//! Whether there exists a modal in a modal stack on screen that uses compositor transitions.
ModalProperty_CompositorTransitions = (1 << 1),
//! Whether there exists a modal that requested to render.
ModalProperty_RenderRequested = (1 << 2),
//! Whether all modal stacks are transparent. Having no modal is treated as transparent.
ModalProperty_Transparent = (1 << 3),
//! Whether all modal stacks pass input through. Having no modal is treated as unfocused.
ModalProperty_Unfocused = (1 << 4),
//! The default properties equivalent to there being no modal windows.
ModalPropertyDefault = (ModalProperty_Transparent | ModalProperty_Unfocused),
} ModalProperty;
//! Initializes the modal window state. This should be called before any
//! Modal applications attempt to push windows.
void modal_manager_init(void);
//! Sets whether modal windows are enabled.
//! @param enabled Boolean indicating whether enabled or disabled
//! Note that this is usable before modal_manager_init is called and modal_manager_init will not
//! reset this state.
void modal_manager_set_min_priority(ModalPriority priority);
//! Gets whether modal windows are enabled.
// @returns boolean indicating if modals are enabled
bool modal_manager_get_enabled(void);
//! Returns the ClickManager for the modal windows.
//! @returns pointer to a \ref ClickManager
ClickManager *modal_manager_get_click_manager(void);
//! Returns the first \ref WindowStack to pass the given filter callback.
//! Iterates down from the highest priority to the lowest priority.
//! @param filter_cb The \ref ModalContextFilterCallback
//! @param context Context to pass to the callback
//! @returns pointer to a \ref WindowStack
WindowStack *modal_manager_find_window_stack(ModalContextFilterCallback filter_cb, void *ctx);
//! Returns the stack with the given window priority.
//! If the passed priority is invalid, raises an assertion.
//! @param priority The \ref ModalPriority of the desired \ref WindowStack
//! @returns pointer to a \ref WindowStack
WindowStack *modal_manager_get_window_stack(ModalPriority priority);
//! Returns the \ref Window of the current visible stack if there is one,
//! otherwise NULL.
//! @returns Pointer to a \ref Window
Window *modal_manager_get_top_window(void);
//! Handles a button press event for the Modal Window. Raises an
//! assertion if the event is not a click event.
//! @param event The \ref PebbleEvent to handle.
void modal_manager_handle_button_event(PebbleEvent *event);
//! Pops all windows from all modal stacks.
void modal_manager_pop_all(void);
//! Pops all windows from modal stacks with priorities less than the given priority
//! @param the max priority stack to pop all windows from
void modal_manager_pop_all_below_priority(ModalPriority priority);
//! Called from the kernel event loop between events to handle any changes that have been made
//! to the modal window stacks.
void modal_manager_event_loop_upkeep(void);
//! Enumerates through the modal stacks and returns the flattened properties of all stacks
//! combined. For example, if all modals are transparent, the Transparent property will be
//! returned. Flattened meaning the entire stack is considered in aggregate. For example, if any
//! one modal is opaque, the Transparent property won't be returned.
ModalProperty modal_manager_get_properties(void);
//! Renders the highest priority top opaque window and all windows with higher priority.
//! @param ctx The \ref GContext in which to render.
//! @return Modal properties such as whether the modals are transparent or unfocusable
void modal_manager_render(GContext *ctx);
//! Determines whether the given modal window is visible. Use window_manager_is_window_visible if
//! both app windows and modal windows need to be considered.
//! @param window The modal window to determine whether it is visible.
//! @return true if the modal window is visible, false otherwise
bool modal_manager_is_window_visible(Window *window);
//! Determines whether the given modal window is focused. Use window_manager_is_window_focused if
//! both app windows and modal windows need to be considered.
//! @param window The modal window to determine whether it is focused.
//! @return true if the modal window is focused, false otherwise
bool modal_manager_is_window_focused(Window *window);
//! Wrapper to call \ref window_stack_push() with the appropriate stack for
//! the given \ref ModalPriority
//! @param window The window to push onto the stack
//! @param priority The priority of the window stack to push to
//! @param animated `True` for animated, otherwise `False`
void modal_window_push(Window *window, ModalPriority priority, bool animated);
//! Reset the modal manager state. Useful for unit testing.
void modal_manager_reset(void);