330 lines
12 KiB
C
330 lines
12 KiB
C
|
#ifndef _GUISLICE_EX_XLISTBOX_H_
|
||
|
#define _GUISLICE_EX_XLISTBOX_H_
|
||
|
|
||
|
#include "GUIslice.h"
|
||
|
|
||
|
|
||
|
// =======================================================================
|
||
|
// GUIslice library extension: Listbox control
|
||
|
// - Calvin Hass
|
||
|
// - https://www.impulseadventure.com/elec/guislice-gui.html
|
||
|
// - https://github.com/ImpulseAdventure/GUIslice
|
||
|
// =======================================================================
|
||
|
//
|
||
|
// The MIT License
|
||
|
//
|
||
|
// Copyright 2016-2020 Calvin Hass
|
||
|
//
|
||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
|
// of this software and associated documentation files (the "Software"), to deal
|
||
|
// in the Software without restriction, including without limitation the rights
|
||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
|
// copies of the Software, and to permit persons to whom the Software is
|
||
|
// furnished to do so, subject to the following conditions:
|
||
|
//
|
||
|
// The above copyright notice and this permission notice shall be included in
|
||
|
// all copies or substantial portions of the Software.
|
||
|
//
|
||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
|
// THE SOFTWARE.
|
||
|
//
|
||
|
// =======================================================================
|
||
|
/// \file XListbox.h
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#endif // __cplusplus
|
||
|
|
||
|
|
||
|
// ============================================================================
|
||
|
// Extended Element: Listbox
|
||
|
// - NOTE: The XListbox element is in beta development.
|
||
|
// Therefore, its API is subject to change.
|
||
|
// ============================================================================
|
||
|
|
||
|
// Define unique identifier for extended element type
|
||
|
// - Select any number above GSLC_TYPE_BASE_EXTEND
|
||
|
#define GSLC_TYPEX_LISTBOX GSLC_TYPE_BASE_EXTEND + 10
|
||
|
|
||
|
// Define constants specific to the control
|
||
|
#define XLISTBOX_SEL_NONE -1 // Indicator for "no selection"
|
||
|
#define XLISTBOX_SIZE_AUTO -1 // Indicator for "auto-size"
|
||
|
#define XLISTBOX_BUF_OH_R 2 // Listbox buffer overhead per row
|
||
|
|
||
|
/// Callback function for Listbox feedback
|
||
|
typedef bool (*GSLC_CB_XLISTBOX_SEL)(void* pvGui,void* pvElem,int16_t nSel);
|
||
|
|
||
|
// Extended element data structures
|
||
|
// - These data structures are maintained in the gslc_tsElem
|
||
|
// structure via the pXData pointer
|
||
|
|
||
|
/// Extended data for Listbox element
|
||
|
typedef struct {
|
||
|
|
||
|
// Config
|
||
|
uint8_t* pBufItems; ///< Buffer containing items
|
||
|
uint16_t nBufItemsMax; ///< Max size of buffer containing items
|
||
|
uint16_t nBufItemsPos; ///< Current buffer position
|
||
|
int16_t nItemCnt; ///< Number of items in the list
|
||
|
|
||
|
// Style config
|
||
|
int8_t nCols; ///< Number of columns
|
||
|
int8_t nRows; ///< Number of columns (or XLSITBOX_SIZE_AUTO to calculate)
|
||
|
bool bNeedRecalc; ///< Determine if sizing may need recalc
|
||
|
int8_t nMarginW; ///< Margin inside main listbox area (X offset)
|
||
|
int8_t nMarginH; ///< Margin inside main listbox area (Y offset)
|
||
|
int16_t nItemW; ///< Width of listbox item
|
||
|
int16_t nItemH; ///< Height of listbox item
|
||
|
int8_t nItemGap; ///< Gap between listbox items
|
||
|
gslc_tsColor colGap; ///< Gap color
|
||
|
bool bItemAutoSizeW; ///< Enable auto-sizing of items (in width)
|
||
|
bool bItemAutoSizeH; ///< Enable auto-sizing of items (in height)
|
||
|
|
||
|
// State
|
||
|
int16_t nItemCurSel; ///< Currently selected item (XLISTBOX_SEL_NONE for none)
|
||
|
int16_t nItemCurSelLast; ///< Old selected item to redraw (XLISTBOX_SEL_NONE for none)
|
||
|
int16_t nItemSavedSel; ///< Persistent selected item (ie. saved selection)
|
||
|
int16_t nItemTop; ///< Item to show at top of list after scrolling (0 is default)
|
||
|
|
||
|
// Callbacks
|
||
|
GSLC_CB_XLISTBOX_SEL pfuncXSel; ///< Callback func ptr for selection update
|
||
|
|
||
|
} gslc_tsXListbox;
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Create a Listbox Element
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] nElemId: Element ID to assign (0..16383 or GSLC_ID_AUTO to autogen)
|
||
|
/// \param[in] nPage: Page ID to attach element to
|
||
|
/// \param[in] pXData: Ptr to extended element data structure
|
||
|
/// \param[in] rElem: Rectangle coordinates defining checkbox size
|
||
|
/// \param[in] nFontId: Font ID for item display
|
||
|
/// \param[in] pBufItems: Pointer to buffer that will contain list of items
|
||
|
/// \param[in] nBufItemsMax: Max size of buffer for list of items (pBufItems)
|
||
|
/// \param[in] nSelDefault: Default item to select
|
||
|
///
|
||
|
/// \return Pointer to Element reference or NULL if failure
|
||
|
///
|
||
|
gslc_tsElemRef* gslc_ElemXListboxCreate(gslc_tsGui* pGui, int16_t nElemId, int16_t nPage,
|
||
|
gslc_tsXListbox* pXData, gslc_tsRect rElem, int16_t nFontId, uint8_t* pBufItems,
|
||
|
uint16_t nBufItemsMax, int16_t nSelDefault);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Configure the number of rows & columns to display in the listbox
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nRows: Number of rows (>= 1, or XLISTBOX_SIZE_AUTO to base on content)
|
||
|
/// \param[in] nCols: Number of columns (>= 1)
|
||
|
///
|
||
|
/// \return none
|
||
|
///
|
||
|
void gslc_ElemXListboxSetSize(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, int8_t nRows, int8_t nCols);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Configure the margin inside the listbox
|
||
|
/// - Defines the region bewteen the element rect and the inner listbox items
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nMarginW: Set the margin (horizontal) inside the listbox (0 for none)
|
||
|
/// \param[in] nMarginH: Set the margin (horizontal) inside the listbox (0 for none)
|
||
|
///
|
||
|
/// \return none
|
||
|
///
|
||
|
void gslc_ElemXListboxSetMargin(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, int8_t nMarginW, int8_t nMarginH);
|
||
|
|
||
|
///
|
||
|
/// Configure the size of the listbox items
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nItemW: Set the width of a listbox item (or -1 to auto-size)
|
||
|
/// \param[in] nItemH: Set the height of a listbox item
|
||
|
///
|
||
|
/// \return none
|
||
|
///
|
||
|
void gslc_ElemXListboxItemsSetSize(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, int16_t nItemW, int16_t nItemH);
|
||
|
|
||
|
///
|
||
|
/// Configure the gap between listbox items
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nGap: Set the gap between listbox items (0 for none)
|
||
|
/// \param[in] colGap: Set the color of the gap between listbox items
|
||
|
///
|
||
|
/// \return none
|
||
|
///
|
||
|
void gslc_ElemXListboxItemsSetGap(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, int8_t nGap, gslc_tsColor colGap);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Empty the listbox of all items
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
///
|
||
|
/// \return none
|
||
|
///
|
||
|
void gslc_ElemXListboxReset(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Add an item to the listbox
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] pStrItem: String to use when creating the listbox item
|
||
|
///
|
||
|
/// \return true if OK, false if fail (eg. insufficient buffer storage)
|
||
|
///
|
||
|
bool gslc_ElemXListboxAddItem(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, const char* pStrItem);
|
||
|
|
||
|
///
|
||
|
/// Insert an item in the listbox at a specific position
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nInsertPos: Insertion position
|
||
|
/// \param[in] pStrItem: String to use when creating the listbox item
|
||
|
///
|
||
|
/// \return true if OK, false if fail (eg. insufficient buffer storage)
|
||
|
///
|
||
|
bool gslc_ElemXListboxInsertItemAt(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, uint16_t nInsertPos,
|
||
|
const char* pStrItem);
|
||
|
|
||
|
///
|
||
|
/// Insert an item in the listbox at a specific position
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nDeletePos: Position to delete
|
||
|
///
|
||
|
/// \return true if OK, false if fail
|
||
|
///
|
||
|
bool gslc_ElemXListboxDeleteItemAt(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, uint16_t nDeletePos);
|
||
|
|
||
|
///
|
||
|
/// Get the indexed listbox item
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
/// \param[in] nItemCurSel: Item index to fetch
|
||
|
/// \param[out] pStrItem: Ptr to the string buffer to receive the item
|
||
|
/// \param[in] nStrItemLen: Maximum buffer length of pStrItem
|
||
|
///
|
||
|
/// \return true if success, false if fail (eg. can't locate item)
|
||
|
///
|
||
|
bool gslc_ElemXListboxGetItem(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, int16_t nItemCurSel,
|
||
|
char* pStrItem, uint8_t nStrItemLen);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Get the number of items in the listbox
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Ptr to Element Reference to update
|
||
|
///
|
||
|
/// \return Number of items
|
||
|
///
|
||
|
int16_t gslc_ElemXListboxGetItemCnt(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef);
|
||
|
|
||
|
///
|
||
|
/// Draw a Listbox element on the screen
|
||
|
/// - Called from gslc_ElemDraw()
|
||
|
///
|
||
|
/// \param[in] pvGui: Void ptr to GUI (typecast to gslc_tsGui*)
|
||
|
/// \param[in] pvElemRef: Void ptr to Element (typecast to gslc_tsElemRef*)
|
||
|
/// \param[in] eRedraw: Redraw mode
|
||
|
///
|
||
|
/// \return true if success, false otherwise
|
||
|
///
|
||
|
bool gslc_ElemXListboxDraw(void* pvGui,void* pvElemRef,gslc_teRedrawType eRedraw);
|
||
|
|
||
|
///
|
||
|
/// Handle touch events to Listbox element
|
||
|
/// - Called from gslc_ElemSendEventTouch()
|
||
|
///
|
||
|
/// \param[in] pvGui: Void ptr to GUI (typecast to gslc_tsGui*)
|
||
|
/// \param[in] pvElemRef: Void ptr to Element ref (typecast to gslc_tsElemRef*)
|
||
|
/// \param[in] eTouch: Touch event type
|
||
|
/// \param[in] nRelX: Touch X coord relative to element
|
||
|
/// \param[in] nRelY: Touch Y coord relative to element
|
||
|
///
|
||
|
/// \return true if success, false otherwise
|
||
|
///
|
||
|
bool gslc_ElemXListboxTouch(void* pvGui,void* pvElemRef,gslc_teTouch eTouch,int16_t nRelX,int16_t nRelY);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Get a Listbox element's current selection
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Pointer to Element reference
|
||
|
///
|
||
|
/// \return Current Listbox selection (or -1 if none)
|
||
|
///
|
||
|
int16_t gslc_ElemXListboxGetSel(gslc_tsGui* pGui,gslc_tsElemRef* pElemRef);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Set a Listbox element's current selection
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Pointer to Element reference
|
||
|
/// \param[in] nItemCurSel: Listbox item to select (or -1 for none)
|
||
|
///
|
||
|
/// \return true if success, false if fail
|
||
|
///
|
||
|
bool gslc_ElemXListboxSetSel(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, int16_t nItemCurSel);
|
||
|
|
||
|
///
|
||
|
/// Set the Listbox scroll position
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Pointer to Element reference
|
||
|
/// \param[in] nScrollPos: Scroll the listbox so that the nScrollPos item is at the top (0 default)
|
||
|
///
|
||
|
/// \return true if success, false if fail
|
||
|
///
|
||
|
bool gslc_ElemXListboxSetScrollPos(gslc_tsGui* pGui, gslc_tsElemRef* pElemRef, uint16_t nScrollPos);
|
||
|
|
||
|
|
||
|
///
|
||
|
/// Assign the selection callback function for a Listbox
|
||
|
///
|
||
|
/// \param[in] pGui: Pointer to GUI
|
||
|
/// \param[in] pElemRef: Pointer to Element reference
|
||
|
/// \param[in] funcCb: Function pointer to selection routine (or NULL for none)
|
||
|
///
|
||
|
/// \return none
|
||
|
///
|
||
|
void gslc_ElemXListboxSetSelFunc(gslc_tsGui* pGui,gslc_tsElemRef* pElemRef,GSLC_CB_XLISTBOX_SEL funcCb);
|
||
|
|
||
|
// ============================================================================
|
||
|
|
||
|
// ------------------------------------------------------------------------
|
||
|
// Read-only element macros
|
||
|
// ------------------------------------------------------------------------
|
||
|
|
||
|
// Macro initializers for Read-Only Elements in Flash/PROGMEM
|
||
|
//
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif // __cplusplus
|
||
|
#endif // _GUISLICE_EX_XLISTBOX_H_
|
||
|
|