📄 listbox.c
字号:
/*
*********************************************************************************************************
* uC/GUI
* Universal graphic software for embedded applications
*
* (c) Copyright 2002, Micrium Inc., Weston, FL
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
*
* 礐/GUI is protected by international copyright laws. Knowledge of the
* source code may not be used to write a similar product. This file may
* only be used in accordance with a license and should not be redistributed
* in any way. We appreciate your understanding and fairness.
*
----------------------------------------------------------------------
File : LISTBOX.c
Purpose : Implementation of listbox widget
---------------------------END-OF-HEADER------------------------------
*/
#include <stdlib.h>
#include <string.h>
#include "GUI_ARRAY.h"
#include "LISTBOX_Private.h"
#include "SCROLLBAR.h"
#include "GUIDebug.h"
#include "GUI_Protected.h"
#include "WM_Intern.h"
#if GUI_WINSUPPORT
/*********************************************************************
*
* Private config defaults
*
**********************************************************************
*/
/* Support for 3D effects */
#ifndef LISTBOX_USE_3D
#define LISTBOX_USE_3D 1
#endif
/* Define default fonts */
#ifndef LISTBOX_FONT_DEFAULT
#define LISTBOX_FONT_DEFAULT &GUI_Font13_1
#endif
/* Define colors */
#ifndef LISTBOX_BKCOLOR0_DEFAULT
#define LISTBOX_BKCOLOR0_DEFAULT GUI_WHITE /* Not selected */
#endif
#ifndef LISTBOX_BKCOLOR1_DEFAULT
#define LISTBOX_BKCOLOR1_DEFAULT GUI_GRAY /* Selected, no focus */
#endif
#ifndef LISTBOX_BKCOLOR2_DEFAULT
#define LISTBOX_BKCOLOR2_DEFAULT GUI_BLUE /* Selected, focus */
#endif
#ifndef LISTBOX_BKCOLOR3_DEFAULT
#define LISTBOX_BKCOLOR3_DEFAULT 0xC0C0C0 /* Disabled */
#endif
#ifndef LISTBOX_TEXTCOLOR0_DEFAULT
#define LISTBOX_TEXTCOLOR0_DEFAULT GUI_BLACK /* Not selected */
#endif
#ifndef LISTBOX_TEXTCOLOR1_DEFAULT
#define LISTBOX_TEXTCOLOR1_DEFAULT GUI_WHITE /* Selected, no focus */
#endif
#ifndef LISTBOX_TEXTCOLOR2_DEFAULT
#define LISTBOX_TEXTCOLOR2_DEFAULT GUI_WHITE /* Selected, focus */
#endif
#ifndef LISTBOX_TEXTCOLOR3_DEFAULT
#define LISTBOX_TEXTCOLOR3_DEFAULT GUI_GRAY /* Disabled */
#endif
#ifndef LISTBOX_SCROLLSTEP_H_DEFAULT
#define LISTBOX_SCROLLSTEP_H_DEFAULT 10
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
LISTBOX_PROPS LISTBOX_DefaultProps = {
LISTBOX_FONT_DEFAULT,
LISTBOX_SCROLLSTEP_H_DEFAULT,
LISTBOX_BKCOLOR0_DEFAULT,
LISTBOX_BKCOLOR1_DEFAULT,
LISTBOX_BKCOLOR2_DEFAULT,
LISTBOX_BKCOLOR3_DEFAULT,
LISTBOX_TEXTCOLOR0_DEFAULT,
LISTBOX_TEXTCOLOR1_DEFAULT,
LISTBOX_TEXTCOLOR2_DEFAULT,
LISTBOX_TEXTCOLOR3_DEFAULT,
};
/*********************************************************************
*
* Static routines
*
**********************************************************************
*/
/*********************************************************************
*
* _CallOwnerDraw
*/
static int _CallOwnerDraw(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, int Cmd, int ItemIndex) {
WIDGET_ITEM_DRAW_INFO ItemInfo;
int r;
ItemInfo.Cmd = Cmd;
ItemInfo.hWin = hObj;
ItemInfo.ItemIndex = ItemIndex;
if (pObj->pfDrawItem) {
r = pObj->pfDrawItem(&ItemInfo);
} else {
r = LISTBOX_OwnerDraw(&ItemInfo);
}
return r;
}
/*********************************************************************
*
* LISTBOX__GetNumItems
*
* Returns:
* Number of items
*/
unsigned LISTBOX__GetNumItems(const LISTBOX_Obj* pObj) {
return GUI_ARRAY_GetNumItems(&pObj->ItemArray);
}
/*********************************************************************
*
* LISTBOX__GetpString
*
* Returns:
* Pointer to the specified item
*/
const char* LISTBOX__GetpString(const LISTBOX_Obj* pObj, int Index) {
const char* s = NULL;
LISTBOX_ITEM* pItem = (LISTBOX_ITEM*)GUI_ARRAY_GetpItem(&pObj->ItemArray, Index);
if (pItem) {
s = pItem->acText;
}
return s;
}
/*********************************************************************
*
* _GetYSize
*/
static int _GetYSize(LISTBOX_Handle hObj) {
GUI_RECT Rect;
WM_GetInsideRectExScrollbar(hObj, &Rect);
return (Rect.y1 - Rect.y0 + 1);
}
/*********************************************************************
*
* _GetItemSizeX
*/
static int _GetItemSizeX(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, unsigned Index) {
LISTBOX_ITEM* pItem;
int xSize = 0;
pItem = (LISTBOX_ITEM*)GUI_ARRAY_GetpItem(&pObj->ItemArray, Index);
if (pItem) {
xSize = pItem->xSize;
}
if (xSize == 0) {
const GUI_FONT GUI_UNI_PTR* pOldFont;
pOldFont = GUI_SetFont(pObj->Props.pFont);
xSize = _CallOwnerDraw(hObj, pObj, WIDGET_ITEM_GET_XSIZE, Index);
GUI_SetFont(pOldFont);
}
if (pItem) {
pItem->xSize = xSize;
}
return xSize;
}
/*********************************************************************
*
* _GetItemSizeY
*/
static int _GetItemSizeY(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, unsigned Index) {
LISTBOX_ITEM* pItem;
int ySize = 0;
pItem = (LISTBOX_ITEM*)GUI_ARRAY_GetpItem(&pObj->ItemArray, Index);
if (pItem) {
ySize = pItem->ySize;
}
if (ySize == 0) {
const GUI_FONT GUI_UNI_PTR* pOldFont;
pOldFont = GUI_SetFont(pObj->Props.pFont);
ySize = _CallOwnerDraw(hObj, pObj, WIDGET_ITEM_GET_YSIZE, Index);
GUI_SetFont(pOldFont);
}
if (pItem) {
pItem->ySize = ySize;
}
return ySize;
}
/*********************************************************************
*
* _GetContentsSizeX
*/
static int _GetContentsSizeX(LISTBOX_Handle hObj) {
LISTBOX_Obj* pObj;
int i, NumItems, SizeX;
int Result = 0;
pObj = LISTBOX_H2P(hObj);
NumItems = LISTBOX__GetNumItems(pObj);
for (i = 0; i < NumItems; i++) {
SizeX = _GetItemSizeX(hObj, pObj, i);
if (Result < SizeX) {
Result = SizeX;
}
}
return Result;
}
/*********************************************************************
*
* _GetItemPosY
*/
static int _GetItemPosY(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj, unsigned Index) {
if (Index < LISTBOX__GetNumItems(pObj)) {
if ((int)Index >= pObj->ScrollStateV.v) {
unsigned i;
int PosY = 0;
for (i = pObj->ScrollStateV.v; i < Index; i++) {
PosY += _GetItemSizeY(hObj, pObj, i);
}
return PosY;
}
}
return -1;
}
/*********************************************************************
*
* _IsPartiallyVis
*/
static int _IsPartiallyVis(LISTBOX_Handle hObj, const LISTBOX_Obj* pObj) {
int Index;
Index = pObj->Sel;
if (Index < (int)LISTBOX__GetNumItems(pObj)) {
if (Index >= pObj->ScrollStateV.v) {
int y;
y = _GetItemPosY (hObj, pObj, Index);
y += _GetItemSizeY(hObj, pObj, Index);
if (y > _GetYSize(hObj)) {
return 1;
}
}
}
return 0;
}
/*********************************************************************
*
* _GetNumVisItems
*
* Returns:
* Number of fully or partially visible items
*/
static unsigned _GetNumVisItems(const LISTBOX_Obj* pObj, LISTBOX_Handle hObj) {
int NumItems, r = 1;
NumItems = LISTBOX__GetNumItems(pObj);
if (NumItems > 1) {
int i, ySize, DistY = 0;
ySize = _GetYSize(hObj);
for (i = NumItems - 1; i >= 0; i--) {
DistY += _GetItemSizeY(hObj, pObj, i);
if (DistY > ySize) {
break;
}
}
r = NumItems - i - 1;
if (r < 1) {
return 1;
}
}
return r;
}
/*********************************************************************
*
* _NotifyOwner
*
* Purpose:
* Notify owner of the window.
* If no owner is registered, the parent is considered owner.
*/
static void _NotifyOwner(WM_HWIN hObj, int Notification) {
WM_MESSAGE Msg = {0};
WM_HWIN hOwner;
LISTBOX_Obj* pObj = LISTBOX_H2P(hObj);
hOwner = pObj->hOwner ? pObj->hOwner : WM_GetParent(hObj);
Msg.MsgId = WM_NOTIFY_PARENT;
Msg.Data.v = Notification;
Msg.hWinSrc= hObj;
WM_SendMessage(hOwner, &Msg);
}
/*********************************************************************
*
* LISTBOX_OwnerDraw
*/
int LISTBOX_OwnerDraw(const WIDGET_ITEM_DRAW_INFO* pDrawItemInfo) {
switch (pDrawItemInfo->Cmd) {
case WIDGET_ITEM_GET_XSIZE: {
LISTBOX_Obj* pObj;
const GUI_FONT GUI_UNI_PTR* pOldFont;
const char* s;
int DistX;
pObj = LISTBOX_H2P(pDrawItemInfo->hWin);
pOldFont = GUI_SetFont(pObj->Props.pFont);
s = LISTBOX__GetpString(pObj, pDrawItemInfo->ItemIndex);
DistX = GUI_GetStringDistX(s);
GUI_SetFont(pOldFont);
return DistX;
}
case WIDGET_ITEM_GET_YSIZE: {
LISTBOX_Obj* pObj;
pObj = LISTBOX_H2P(pDrawItemInfo->hWin);
return GUI_GetYDistOfFont(pObj->Props.pFont) + pObj->ItemSpacing;
}
case WIDGET_ITEM_DRAW: {
LISTBOX_Obj* pObj;
LISTBOX_ITEM* pItem;
WM_HMEM hItem;
GUI_RECT r;
int FontDistY;
int ItemIndex = pDrawItemInfo->ItemIndex;
const char* s;
int ColorIndex;
char IsDisabled;
char IsSelected;
pObj = LISTBOX_H2P(pDrawItemInfo->hWin);
hItem = GUI_ARRAY_GethItem(&pObj->ItemArray, ItemIndex);
pItem = (LISTBOX_ITEM *)GUI_ALLOC_h2p(hItem);
WM_GetInsideRect(&r);
FontDistY = GUI_GetFontDistY();
/* Calculate color index */
IsDisabled = (pItem->Status & LISTBOX_ITEM_DISABLED) ? 1 : 0;
IsSelected = (pItem->Status & LISTBOX_ITEM_SELECTED) ? 1 : 0;
if (pObj->Flags & LISTBOX_SF_MULTISEL) {
if (IsDisabled) {
ColorIndex = 3;
} else {
ColorIndex = (IsSelected) ? 2 : 0;
}
} else {
if (IsDisabled) {
ColorIndex = 3;
} else {
if (ItemIndex == pObj->Sel) {
ColorIndex = (pObj->Widget.State & WIDGET_STATE_FOCUS) ? 2 : 1;
} else {
ColorIndex = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -