mirror of
https://github.com/google/pebble.git
synced 2025-04-30 15:21:41 -04:00
632 lines
30 KiB
C
632 lines
30 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 "inverter_layer.h"
|
|
#include "menu_cell_layer.h"
|
|
#include "scroll_layer.h"
|
|
|
|
#include "applib/app_timer.h"
|
|
#include "applib/fonts/fonts.h"
|
|
#include "applib/graphics/text.h"
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
|
|
//! @file menu_layer.h
|
|
//! @addtogroup UI
|
|
//! @{
|
|
//! @addtogroup Layer Layers
|
|
//! @{
|
|
//! @addtogroup MenuLayer
|
|
//! \brief Layer that displays a standard list menu. Data is provided using
|
|
//! callbacks.
|
|
//!
|
|
//! 
|
|
//! <h3>Key Points</h3>
|
|
//! * The familiar list-style menu widget, as used throughout the Pebble user
|
|
//! interface.
|
|
//! * Built on top of \ref ScrollLayer, inheriting all its goodness like
|
|
//! animated scrolling, automatic "more content" shadow indicators, etc.
|
|
//! * All data needed to render the menu is requested on-demand via callbacks,
|
|
//! to avoid the need to keep a lot of data in memory.
|
|
//! * Support for "sections". A section is a group of items, visually separated
|
|
//! by a header with the name at the top of the section.
|
|
//! * Variable heights: each menu item cell and each section header can have
|
|
//! its own height. The heights are provided by callbacks.
|
|
//! * Deviation from the Layer system for cell drawing: Each menu item does
|
|
//! _not_ have its own Layer (to minimize memory usage). Instead, a
|
|
//! drawing callback is set onto the \ref MenuLayer that is responsible
|
|
//! for drawing each menu item. The \ref MenuLayer will call this callback for each
|
|
//! menu item that is visible and needs to be rendered.
|
|
//! * Cell and header drawing can be customized by implementing a custom drawing
|
|
//! callback.
|
|
//! * A few "canned" menu cell drawing functions are provided for convenience,
|
|
//! which support the default menu cell layout with a title, optional subtitle
|
|
//! and icon.
|
|
//!
|
|
//! For short, static list menus, consider using \ref SimpleMenuLayer.
|
|
//! @{
|
|
|
|
//! @internal
|
|
//! Constant to indicate that a menu item index is not found
|
|
#define MENU_INDEX_NOT_FOUND ((const uint16_t) ~0)
|
|
|
|
//////////////////////
|
|
// Menu Layer
|
|
|
|
struct MenuLayer;
|
|
|
|
//! Data structure to represent an menu item's position in a menu, by specifying
|
|
//! the section index and the row index within that section.
|
|
typedef struct MenuIndex {
|
|
//! The index of the section
|
|
uint16_t section;
|
|
//! The index of the row within the section with index `.section`
|
|
uint16_t row;
|
|
} MenuIndex;
|
|
|
|
//! Macro to create a MenuIndex
|
|
#define MenuIndex(section, row) ((MenuIndex){ (section), (row) })
|
|
|
|
//! Comparator function to determine the order of two MenuIndex values.
|
|
//! @param a Pointer to the menu index of the first item
|
|
//! @param b Pointer to the menu index of the second item
|
|
//! @return 0 if A and B are equal, 1 if A has a higher section & row
|
|
//! combination than B or else -1
|
|
int16_t menu_index_compare(const MenuIndex *a, const MenuIndex *b);
|
|
|
|
//! @internal
|
|
//! Data structure with geometric information of a cell at specific menu index.
|
|
//! This is used internally for caching.
|
|
typedef struct MenuCellSpan {
|
|
int16_t y;
|
|
int16_t h;
|
|
int16_t sep;
|
|
MenuIndex index;
|
|
} MenuCellSpan;
|
|
|
|
//! Function signature for the callback to get the number of sections in a menu.
|
|
//! @param menu_layer The \ref MenuLayer for which the data is requested
|
|
//! @param callback_context The callback context
|
|
//! @return The number of sections in the menu
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef uint16_t (*MenuLayerGetNumberOfSectionsCallback)(struct MenuLayer *menu_layer,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to get the number of rows in a
|
|
//! given section in a menu.
|
|
//! @param menu_layer The \ref MenuLayer for which the data is requested
|
|
//! @param section_index The index of the section of the menu for which the
|
|
//! number of items it contains is requested
|
|
//! @param callback_context The callback context
|
|
//! @return The number of rows in the given section in the menu
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef uint16_t (*MenuLayerGetNumberOfRowsInSectionsCallback)(struct MenuLayer *menu_layer,
|
|
uint16_t section_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to get the height of the menu cell
|
|
//! at a given index.
|
|
//! @param menu_layer The \ref MenuLayer for which the data is requested
|
|
//! @param cell_index The MenuIndex for which the cell height is requested
|
|
//! @param callback_context The callback context
|
|
//! @return The height of the cell at the given MenuIndex
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef int16_t (*MenuLayerGetCellHeightCallback)(struct MenuLayer *menu_layer,
|
|
MenuIndex *cell_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to get the height of the section header
|
|
//! at a given section index.
|
|
//! @param menu_layer The \ref MenuLayer for which the data is requested
|
|
//! @param section_index The index of the section for which the header height is
|
|
//! requested
|
|
//! @param callback_context The callback context
|
|
//! @return The height of the section header at the given section index
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef int16_t (*MenuLayerGetHeaderHeightCallback)(struct MenuLayer *menu_layer,
|
|
uint16_t section_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to get the height of the separator
|
|
//! at a given index.
|
|
//! @param menu_layer The \ref MenuLayer for which the data is requested
|
|
//! @param cell_index The MenuIndex for which the cell height is requested
|
|
//! @param callback_context The callback context
|
|
//! @return The height of the separator at the given MenuIndex
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef int16_t (*MenuLayerGetSeparatorHeightCallback)(struct MenuLayer *menu_layer,
|
|
MenuIndex *cell_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to render the menu cell at a given
|
|
//! MenuIndex.
|
|
//! @param ctx The destination graphics context to draw into
|
|
//! @param cell_layer The cell's layer, containing the geometry of the cell
|
|
//! @param cell_index The MenuIndex of the cell that needs to be drawn
|
|
//! @param callback_context The callback context
|
|
//! @note The `cell_layer` argument is provided to make it easy to re-use an
|
|
//! `.update_proc` implementation in this callback. Only the bounds and frame
|
|
//! of the `cell_layer` are actually valid and other properties should be
|
|
//! ignored.
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef void (*MenuLayerDrawRowCallback)(GContext* ctx,
|
|
const Layer *cell_layer,
|
|
MenuIndex *cell_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to render the section header at a given
|
|
//! section index.
|
|
//! @param ctx The destination graphics context to draw into
|
|
//! @param cell_layer The header cell's layer, containing the geometry of the
|
|
//! header cell
|
|
//! @param section_index The section index of the section header that needs to
|
|
//! be drawn
|
|
//! @param callback_context The callback context
|
|
//! @note The `cell_layer` argument is provided to make it easy to re-use an
|
|
//! `.update_proc` implementation in this callback. Only the bounds and frame
|
|
//! of the `cell_layer` are actually valid and other properties should be
|
|
//! ignored.
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef void (*MenuLayerDrawHeaderCallback)(GContext* ctx,
|
|
const Layer *cell_layer,
|
|
uint16_t section_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to render the separator at a given
|
|
//! MenuIndex.
|
|
//! @param ctx The destination graphics context to draw into
|
|
//! @param cell_layer The cell's layer, containing the geometry of the cell
|
|
//! @param cell_index The MenuIndex of the separator that needs to be drawn
|
|
//! @param callback_context The callback context
|
|
//! @note The `cell_layer` argument is provided to make it easy to re-use an
|
|
//! `.update_proc` implementation in this callback. Only the bounds and frame
|
|
//! of the `cell_layer` are actually valid and other properties should be
|
|
//! ignored.
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef void (*MenuLayerDrawSeparatorCallback)(GContext* ctx,
|
|
const Layer *cell_layer,
|
|
MenuIndex *cell_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to handle the event that a user hits
|
|
//! the SELECT button.
|
|
//! @param menu_layer The \ref MenuLayer for which the selection event occured
|
|
//! @param cell_index The MenuIndex of the cell that is selected
|
|
//! @param callback_context The callback context
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef void (*MenuLayerSelectCallback)(struct MenuLayer *menu_layer,
|
|
MenuIndex *cell_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback to handle a change in the current
|
|
//! selected item in the menu.
|
|
//! @param menu_layer The \ref MenuLayer for which the selection event occured
|
|
//! @param new_index The MenuIndex of the new item that is selected now
|
|
//! @param old_index The MenuIndex of the old item that was selected before
|
|
//! @param callback_context The callback context
|
|
//! @see \ref menu_layer_set_callbacks()
|
|
//! @see \ref MenuLayerCallbacks
|
|
typedef void (*MenuLayerSelectionChangedCallback)(struct MenuLayer *menu_layer,
|
|
MenuIndex new_index,
|
|
MenuIndex old_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback which allows or changes selection behavior of the menu.
|
|
//! In order to change the cell that should be selected, modify the passed in new_index.
|
|
//! Preventing the selection from changing, new_index can be assigned the value of old_index.
|
|
//! @param menu_layer The \ref MenuLayer for which the selection event that occured
|
|
//! @param new_index Pointer to the index that the MenuLayer is going to change selection to.
|
|
//! @param old_index The index that is being unselected.
|
|
//! @param callback_context The callback context
|
|
//! @note \ref menu_layer_set_selected_index will not trigger this callback when
|
|
//! the selection changes, but \ref menu_layer_set_selected_next will.
|
|
typedef void (*MenuLayerSelectionWillChangeCallback)(struct MenuLayer *menu_layer,
|
|
MenuIndex *new_index,
|
|
MenuIndex old_index,
|
|
void *callback_context);
|
|
|
|
//! Function signature for the callback which draws the menu's background.
|
|
//! The background is underneath the cells of the menu, and is visible in the
|
|
//! padding below the bottom cell, or if a cell's background color is set to \ref GColorClear.
|
|
//! @param ctx The destination graphics context to draw into.
|
|
//! @param bg_layer The background's layer, containing the geometry of the background.
|
|
//! @param highlight Whether this should be rendered as highlighted or not. Highlight style
|
|
//! should match the highlight style of cells, since this color can be used for animating selection.
|
|
typedef void (*MenuLayerDrawBackgroundCallback)(GContext* ctx,
|
|
const Layer *bg_layer,
|
|
bool highlight,
|
|
void *callback_context);
|
|
|
|
//! Data structure containing all the callbacks of a \ref MenuLayer.
|
|
typedef struct MenuLayerCallbacks {
|
|
//! Callback that gets called to get the number of sections in the menu.
|
|
//! This can get called at various moments throughout the life of a menu.
|
|
//! @note When `NULL`, the number of sections defaults to 1.
|
|
MenuLayerGetNumberOfSectionsCallback get_num_sections;
|
|
|
|
//! Callback that gets called to get the number of rows in a section. This
|
|
//! can get called at various moments throughout the life of a menu.
|
|
//! @note Must be set to a valid callback; `NULL` causes undefined behavior.
|
|
MenuLayerGetNumberOfRowsInSectionsCallback get_num_rows;
|
|
|
|
//! Callback that gets called to get the height of a cell.
|
|
//! This can get called at various moments throughout the life of a menu.
|
|
//! @note When `NULL`, the default height of \ref MENU_CELL_BASIC_CELL_HEIGHT pixels is used.
|
|
//! Developers may wish to use \ref MENU_CELL_ROUND_FOCUSED_SHORT_CELL_HEIGHT
|
|
//! and \ref MENU_CELL_ROUND_UNFOCUSED_SHORT_CELL_HEIGHT on a round display
|
|
//! to respect the system aesthetic.
|
|
MenuLayerGetCellHeightCallback get_cell_height;
|
|
|
|
//! Callback that gets called to get the height of a section header.
|
|
//! This can get called at various moments throughout the life of a menu.
|
|
//! @note When `NULL`, the default height of 0 pixels is used. This disables
|
|
//! section headers.
|
|
MenuLayerGetHeaderHeightCallback get_header_height;
|
|
|
|
//! Callback that gets called to render a menu item.
|
|
//! This gets called for each menu item, every time it needs to be
|
|
//! re-rendered.
|
|
//! @note Must be set to a valid callback; `NULL` causes undefined behavior.
|
|
MenuLayerDrawRowCallback draw_row;
|
|
|
|
//! Callback that gets called to render a section header.
|
|
//! This gets called for each section header, every time it needs to be
|
|
//! re-rendered.
|
|
//! @note Must be set to a valid callback, unless `.get_header_height` is
|
|
//! `NULL`. Causes undefined behavior otherwise.
|
|
MenuLayerDrawHeaderCallback draw_header;
|
|
|
|
//! Callback that gets called when the user triggers a click with the SELECT
|
|
//! button.
|
|
//! @note When `NULL`, click events for the SELECT button are ignored.
|
|
MenuLayerSelectCallback select_click;
|
|
|
|
//! Callback that gets called when the user triggers a long click with the
|
|
//! SELECT button.
|
|
//! @note When `NULL`, long click events for the SELECT button are ignored.
|
|
MenuLayerSelectCallback select_long_click;
|
|
|
|
//! Callback that gets called whenever the selection changes.
|
|
//! @note When `NULL`, selection change events are ignored.
|
|
MenuLayerSelectionChangedCallback selection_changed;
|
|
|
|
//! Callback that gets called to get the height of a separator
|
|
//! This can get called at various moments throughout the life of a menu.
|
|
//! @note When `NULL`, the default height of 0 is used.
|
|
MenuLayerGetSeparatorHeightCallback get_separator_height;
|
|
|
|
//! Callback that gets called to render a separator.
|
|
//! This gets called for each separator, every time it needs to be
|
|
//! re-rendered.
|
|
//! @note Must be set to a valid callback, unless `.get_separator_height` is
|
|
//! `NULL`. Causes undefined behavior otherwise.
|
|
MenuLayerDrawSeparatorCallback draw_separator;
|
|
|
|
//! Callback that gets called before the selected cell changes.
|
|
//! This gets called before the selected item in the MenuLayer is changed,
|
|
//! and will allow for the selected cell to be overridden.
|
|
//! This allows for skipping cells in the menu, locking selection onto a given item,
|
|
MenuLayerSelectionWillChangeCallback selection_will_change;
|
|
|
|
//! Callback that gets called before any cells are drawn.
|
|
//! This supports two states, either highlighted or not highlighted.
|
|
//! If highlighted is specified, it is expected to be colored in the same
|
|
//! style as the menu's cells are.
|
|
//! If this callback is not specified, it will default to the colors set with
|
|
//! \ref menu_layer_set_normal_colors and \ref menu_layer_set_highlight_colors.
|
|
MenuLayerDrawBackgroundCallback draw_background;
|
|
} MenuLayerCallbacks;
|
|
|
|
enum {
|
|
MenuLayerColorBackground = 0,
|
|
MenuLayerColorForeground,
|
|
MenuLayerColor_Count,
|
|
};
|
|
#ifndef __clang__
|
|
_Static_assert(MenuLayerColor_Count == 2, "Bad enum MenuLayerColor");
|
|
#endif
|
|
|
|
//! Data structure of a MenuLayer.
|
|
//! @note a `MenuLayer *` can safely be casted to a `Layer *` and
|
|
//! `ScrollLayer *` and can thus be used with all other functions that take a
|
|
//! `Layer *` or `ScrollLayer *`, respectively, as an argument.
|
|
//! <br/>For example, the following is legal:
|
|
//! \code{.c}
|
|
//! MenuLayer menu_layer;
|
|
//! ...
|
|
//! layer_set_hidden((Layer *)&menu_layer, true);
|
|
//! \endcode
|
|
//! @note However there are a few caveats:
|
|
//! * Do not try to change to bounds or frame of a \ref MenuLayer, after
|
|
//! initializing it.
|
|
typedef struct MenuLayer {
|
|
ScrollLayer scroll_layer;
|
|
InverterLayer inverter;
|
|
//! @internal
|
|
struct {
|
|
//! @internal
|
|
//! Cell index + geometry cache of a cell that was in frame during the last redraw
|
|
MenuCellSpan cursor;
|
|
} cache;
|
|
//! @internal
|
|
//! Selected cell index + geometry cache of the selected cell
|
|
MenuCellSpan selection;
|
|
MenuLayerCallbacks callbacks;
|
|
void *callback_context;
|
|
|
|
//! Default colors to be used for \ref MenuLayer.
|
|
//! Use MenuLayerColorNormal and MenuLayerColorHightlight for indexing.
|
|
GColor normal_colors[MenuLayerColor_Count];
|
|
GColor highlight_colors[MenuLayerColor_Count];
|
|
|
|
//! Animation used for selection. Note this is only used in 3.x+ apps, legacy2 apps don't
|
|
//! use this.
|
|
struct {
|
|
Animation *animation;
|
|
GRect target; //! The target frame of the animation
|
|
//! cell_layer's bounds.origin will be modified by this to allow for
|
|
//! content scrolling without scrolling the actual cells
|
|
int16_t cell_content_origin_offset_y;
|
|
//! used to express "bouncing" of the highlight
|
|
int16_t selection_extend_top;
|
|
//! same as selection_extend_top but for the bottom
|
|
int16_t selection_extend_bottom;
|
|
//! some animations (e.g. center focused) will use this field to postpone the update of
|
|
//! menulayer.selection (especially for the .index)
|
|
MenuCellSpan new_selection;
|
|
} animation;
|
|
|
|
//! @internal
|
|
//! If true, there will be padding after the bottom item in the menu
|
|
//! Defaults to 'true'
|
|
bool pad_bottom:1;
|
|
|
|
//! If true, the MenuLayer will generally scroll the content so that the selected row is
|
|
//! on the center of the screen.
|
|
bool center_focused:1;
|
|
|
|
//! If true, the MenuLayer will not perform the selection cell clipping animation. This is
|
|
//! independent of the scrolling animation.
|
|
bool selection_animation_disabled:1;
|
|
|
|
//! Add some padding to keep track of the \ref MenuLayer size budget.
|
|
//! As long as the size stays within this budget, 2.x apps can safely use the 3.x MenuLayer type.
|
|
//! When padding is removed, the assertion below should also be removed.
|
|
uint8_t padding[44];
|
|
} MenuLayer;
|
|
|
|
//! Padding used below the last item in pixels
|
|
#define MENU_LAYER_BOTTOM_PADDING 20
|
|
|
|
//! Initializes a \ref MenuLayer with given frame
|
|
//! All previous contents are erased and the following default values are set:
|
|
//! * Clips: `true`
|
|
//! * Hidden: `false`
|
|
//! * Content size: `frame.size`
|
|
//! * Content offset: \ref GPointZero
|
|
//! * Callbacks: None (`NULL` for each one)
|
|
//! * Callback context: `NULL`
|
|
//! * After the relevant callbacks are called to populate the menu, the item at MenuIndex(0, 0)
|
|
//! will be selected initially.
|
|
//! The layer is marked dirty automatically.
|
|
//! @param menu_layer The \ref MenuLayer to initialize
|
|
//! @param frame The frame with which to initialze the \ref MenuLayer
|
|
void menu_layer_init(MenuLayer *menu_layer, const GRect *frame);
|
|
|
|
//! Creates a new \ref MenuLayer on the heap and initalizes it with the default values.
|
|
//!
|
|
//! * Clips: `true`
|
|
//! * Hidden: `false`
|
|
//! * Content size: `frame.size`
|
|
//! * Content offset: \ref GPointZero
|
|
//! * Callbacks: None (`NULL` for each one)
|
|
//! * Callback context: `NULL`
|
|
//! * After the relevant callbacks are called to populate the menu, the item at MenuIndex(0, 0)
|
|
//! will be selected initially.
|
|
//! @return A pointer to the \ref MenuLayer. `NULL` if the \ref MenuLayer could not
|
|
//! be created
|
|
MenuLayer* menu_layer_create(GRect frame);
|
|
|
|
void menu_layer_deinit(MenuLayer* menu_layer);
|
|
|
|
//! Destroys a \ref MenuLayer previously created by menu_layer_create.
|
|
void menu_layer_destroy(MenuLayer* menu_layer);
|
|
|
|
//! Gets the "root" Layer of the \ref MenuLayer, which is the parent for the sub-
|
|
//! layers used for its implementation.
|
|
//! @param menu_layer Pointer to the MenuLayer for which to get the "root" Layer
|
|
//! @return The "root" Layer of the \ref MenuLayer.
|
|
//! @internal
|
|
//! @note The result is always equal to `(Layer *) menu_layer`.
|
|
Layer* menu_layer_get_layer(const MenuLayer *menu_layer);
|
|
|
|
//! Gets the ScrollLayer of the \ref MenuLayer, which is the layer responsible for
|
|
//! the scrolling of the \ref MenuLayer.
|
|
//! @param menu_layer Pointer to the \ref MenuLayer for which to get the ScrollLayer
|
|
//! @return The ScrollLayer of the \ref MenuLayer.
|
|
//! @internal
|
|
//! @note The result is always equal to `(ScrollLayer *) menu_layer`.
|
|
ScrollLayer* menu_layer_get_scroll_layer(const MenuLayer *menu_layer);
|
|
|
|
//! @internal
|
|
//! This function replaces \ref menu_layer_set_callbacks_by_value in order to change the callbacks
|
|
//! parameter to be passed by a pointer instead of being passed by value. Callers consume much less
|
|
//! code space when passing a pointer compared to passing structs by value.
|
|
//! @see menu_layer_set_callbacks_by_value
|
|
void menu_layer_set_callbacks(MenuLayer *menu_layer,
|
|
void *callback_context,
|
|
const MenuLayerCallbacks *callbacks);
|
|
|
|
//! Sets the callbacks for the MenuLayer.
|
|
//! @param menu_layer Pointer to the \ref MenuLayer for which to set the callbacks
|
|
//! and callback context.
|
|
//! @param callback_context The new callback context. This is passed into each
|
|
//! of the callbacks and can be set to point to application provided data.
|
|
//! @param callbacks The new callbacks for the \ref MenuLayer. The storage for this
|
|
//! data structure must be long lived. Therefore, it cannot be stack-allocated.
|
|
//! @see MenuLayerCallbacks
|
|
void menu_layer_set_callbacks_by_value(MenuLayer *menu_layer, void *callback_context,
|
|
MenuLayerCallbacks callbacks);
|
|
|
|
//! Convenience function to set the \ref ClickConfigProvider callback on the
|
|
//! given window to the \ref MenuLayer internal click config provider. This internal
|
|
//! click configuration provider, will set up the default UP & DOWN
|
|
//! scrolling / menu item selection behavior.
|
|
//! This function calls \ref scroll_layer_set_click_config_onto_window to
|
|
//! accomplish this.
|
|
//!
|
|
//! Click and long click events for the SELECT button can be handled by
|
|
//! installing the appropriate callbacks using \ref menu_layer_set_callbacks().
|
|
//! This is a deviation from the usual click configuration provider pattern.
|
|
//! @param menu_layer The \ref MenuLayer that needs to receive click events.
|
|
//! @param window The window for which to set the click configuration.
|
|
//! @see \ref Clicks
|
|
//! @see \ref window_set_click_config_provider_with_context()
|
|
//! @see \ref scroll_layer_set_click_config_onto_window()
|
|
void menu_layer_set_click_config_onto_window(MenuLayer *menu_layer,
|
|
struct Window *window);
|
|
|
|
//! This enables or disables padding at the bottom of the \ref MenuLayer.
|
|
//! Padding at the bottom of the layer keeps the bottom item from being at the very bottom of the
|
|
//! screen.
|
|
//! Padding is turned on by default for all MenuLayers.
|
|
//! The color of the padded area will be the background color set using
|
|
//! \ref menu_layer_set_normal_colors(). To color the padding a different color, use
|
|
//! \ref MenuLayerDrawBackgroundCallback.
|
|
//! @param menu_layer The menu layer for which to enable or disable the padding.
|
|
//! @param enable True = enable padding, False = disable padding.
|
|
void menu_layer_pad_bottom_enable(MenuLayer *menu_layer, bool enable);
|
|
|
|
//! Values to specify how a (selected) row should be aligned relative to the
|
|
//! visible area of the \ref MenuLayer.
|
|
typedef enum {
|
|
//! Don't align or update the scroll offset of the \ref MenuLayer.
|
|
MenuRowAlignNone,
|
|
|
|
//! Scroll the contents of the \ref MenuLayer in such way that the selected row
|
|
//! is centered relative to the visible area.
|
|
MenuRowAlignCenter,
|
|
|
|
//! Scroll the contents of the \ref MenuLayer in such way that the selected row
|
|
//! is at the top of the visible area.
|
|
MenuRowAlignTop,
|
|
|
|
//! Scroll the contents of the \ref MenuLayer in such way that the selected row
|
|
//! is at the bottom of the visible area.
|
|
MenuRowAlignBottom,
|
|
} MenuRowAlign;
|
|
|
|
//! Selects the next or previous item, relative to the current selection.
|
|
//! @param menu_layer The \ref MenuLayer for which to select the next item
|
|
//! @param up Supply `false` to select the next item in the list (downwards),
|
|
//! or `true` to select the previous item in the list (upwards).
|
|
//! @param scroll_align The alignment of the new selection
|
|
//! @param animated Supply `true` to animate changing the selection, or `false`
|
|
//! to change the selection instantly.
|
|
//! @note If there is no next/previous item, this function is a no-op.
|
|
void menu_layer_set_selected_next(MenuLayer *menu_layer,
|
|
bool up,
|
|
MenuRowAlign scroll_align,
|
|
bool animated);
|
|
|
|
//! Selects the item with given \ref MenuIndex.
|
|
//! @param menu_layer The \ref MenuLayer for which to change the selection
|
|
//! @param index The index of the item to select
|
|
//! @param scroll_align The alignment of the new selection
|
|
//! @param animated Supply `true` to animate changing the selection, or `false`
|
|
//! to change the selection instantly.
|
|
//! @note If the section and/or row index exceeds the available number of sections
|
|
//! or resp. rows, the exceeding index/indices will be capped, effectively
|
|
//! selecting the last section and/or row, resp.
|
|
void menu_layer_set_selected_index(MenuLayer *menu_layer,
|
|
MenuIndex index, MenuRowAlign scroll_align,
|
|
bool animated);
|
|
|
|
//! Gets the MenuIndex of the currently selected menu item.
|
|
//! @param menu_layer The \ref MenuLayer for which to get the current selected index.
|
|
//! @see menu_cell_layer_is_highlighted
|
|
//! @note This function should not be used to determine whether a cell should be
|
|
//! highlighted or not. See \ref menu_cell_layer_is_highlighted for more
|
|
//! information.
|
|
MenuIndex menu_layer_get_selected_index(const MenuLayer *menu_layer);
|
|
|
|
//! Returns whether or not the specified cell index is currently selected.
|
|
//! @param menu_layer The \ref MenuLayer to use when determining if the index is selected.
|
|
//! @param index The \ref MenuIndex of the cell to check for selection.
|
|
//! @note This function should not be used to determine whether a cell is highlighted or not.
|
|
//! See \ref menu_cell_layer_is_highlighted for more information.
|
|
bool menu_layer_is_index_selected(const MenuLayer *menu_layer, MenuIndex *index);
|
|
|
|
//! Reloads the data of the menu. This causes the menu to re-request the menu
|
|
//! item data, by calling the relevant callbacks.
|
|
//! The current selection and scroll position will not be changed. See the
|
|
//! note with \ref menu_layer_set_selected_index() for the behavior if the
|
|
//! old selection is no longer valid.
|
|
//! @param menu_layer The \ref MenuLayer for which to reload the data.
|
|
void menu_layer_reload_data(MenuLayer *menu_layer);
|
|
|
|
//! Set the default colors to be used for cells when it is in a normal state (not highlighted).
|
|
//! The GContext's text and fill colors will be set appropriately prior to calling the `.draw_row`
|
|
//! callback.
|
|
//! If this function is not explicitly called on a \ref MenuLayer, it will default to white
|
|
//! background with black foreground.
|
|
//! @param menu_layer The \ref MenuLayer for which to set the colors.
|
|
//! @param background The color to be used for the background of the cell.
|
|
//! @param foreground The color to be used for the foreground and text of the cell.
|
|
//! @see \ref menu_layer_set_highlight_colors
|
|
void menu_layer_set_normal_colors(MenuLayer *menu_layer, GColor background, GColor foreground);
|
|
|
|
//! Set the default colors to be used for cells when it is in a highlighted state.
|
|
//! The GContext's text and fill colors will be set appropriately prior to calling the `.draw_row`
|
|
//! callback.
|
|
//! If this function is not explicitly called on a \ref MenuLayer, it will default to black
|
|
//! background with white foreground.
|
|
//! @param menu_layer The \ref MenuLayer for which to set the colors.
|
|
//! @param background The color to be used for the background of the cell.
|
|
//! @param foreground The color to be used for the foreground and text of the cell.
|
|
//! @see \ref menu_layer_set_normal_colors
|
|
void menu_layer_set_highlight_colors(MenuLayer *menu_layer, GColor background, GColor foreground);
|
|
|
|
|
|
//! True, if the \ref MenuLayer generally scrolls such that the selected row is in the center.
|
|
//! @see \ref menu_layer_set_center_focused
|
|
bool menu_layer_get_center_focused(MenuLayer *menu_layer);
|
|
|
|
//! Controls if the \ref MenuLayer generally scrolls such that the selected row is in the center.
|
|
//! For platforms with a round display (PBL_ROUND) the default is true,
|
|
//! otherwise false is the default
|
|
//! @param menu_layer The menu layer for which to enable or disable the behavior.
|
|
//! @param center_focused true = enable the mode, false = disable it.
|
|
//! @see \ref menu_layer_get_center_focused
|
|
void menu_layer_set_center_focused(MenuLayer *menu_layer, bool center_focused);
|
|
|
|
|
|
//! @} // end addtogroup MenuLayer
|
|
//! @} // end addtogroup Layer
|
|
//! @} // end addtogroup UI
|
|
|