?? edit.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 : EDIT.c
Purpose : Implementation of edit widget
---------------------------END-OF-HEADER------------------------------
*/
#include <stdlib.h>
#include <string.h>
#define EDIT_C /* Required to generate intermodule data */
#include "EDIT.h"
#include "GUIDebug.h"
#include "GUI_Protected.h"
#include "EDIT_Private.h"
#if GUI_WINSUPPORT
/*********************************************************************
*
* Private config defaults
*
**********************************************************************
*/
/* Define default fonts */
#ifndef EDIT_FONT_DEFAULT
#define EDIT_FONT_DEFAULT &GUI_Font13_1
#endif
#ifndef EDIT_ALIGN_DEFAULT
#define EDIT_ALIGN_DEFAULT GUI_TA_LEFT | GUI_TA_VCENTER
#endif
/* Define colors */
#ifndef EDIT_BKCOLOR0_DEFAULT
#define EDIT_BKCOLOR0_DEFAULT 0xC0C0C0
#endif
#ifndef EDIT_BKCOLOR1_DEFAULT
#define EDIT_BKCOLOR1_DEFAULT GUI_WHITE
#endif
#ifndef EDIT_TEXTCOLOR0_DEFAULT
#define EDIT_TEXTCOLOR0_DEFAULT GUI_BLACK
#endif
#ifndef EDIT_TEXTCOLOR1_DEFAULT
#define EDIT_TEXTCOLOR1_DEFAULT GUI_BLACK
#endif
#ifndef EDIT_BORDER_DEFAULT
#define EDIT_BORDER_DEFAULT 1
#endif
#ifndef EDIT_XOFF
#define EDIT_XOFF 1
#endif
/*********************************************************************
*
* Static data
*
**********************************************************************
*/
EDIT_PROPS EDIT__DefaultProps = {
EDIT_ALIGN_DEFAULT,
EDIT_BORDER_DEFAULT,
EDIT_FONT_DEFAULT,
EDIT_TEXTCOLOR0_DEFAULT,
EDIT_TEXTCOLOR1_DEFAULT,
EDIT_BKCOLOR0_DEFAULT,
EDIT_BKCOLOR1_DEFAULT
};
/*********************************************************************
*
* Macros for internal use
*
**********************************************************************
*/
#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL
#define OBJECT_ID 0x4569 /* Magic nubmer, should be unique if possible */
#define INIT_ID(p) p->DebugId = OBJECT_ID
#define DEINIT_ID(p) p->DebugId = 0
#else
#define INIT_ID(p)
#define DEINIT_ID(p)
#endif
/*********************************************************************
*
*
**********************************************************************
*/
/*********************************************************************
*
* EDIT_h2p
*/
#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL
EDIT_Obj* EDIT_h2p(EDIT_Handle h) {
EDIT_Obj* p = (EDIT_Obj*)GUI_ALLOC_h2p(h);
if (p) {
//houhh 20061022...
if (p->DebugId != OBJECT_ID) {
GUI_DEBUG_ERROROUT("EDIT.C: Wrong handle type or Object not init'ed");
return 0;
}
}
return p;
}
#endif
///////////houhh 20061018...
static GUI_TIMER_HANDLE Timer1 = 0; //houhh 20061018...
static void _Paint(EDIT_Obj* pObj, EDIT_Handle hObj) ;
void ShowCurrsor(GUI_TIMER_MESSAGE* TimeMsg)
{
EDIT_Handle hObj = (EDIT_Handle) TimeMsg->Context;
EDIT_Obj* pObj = (EDIT_Obj*) GUI_ALLOC_h2p(hObj);
WM_Obj* pWin = WM_H2P(hObj);
GUI_DEBUG_LOG("EDIT: _Callback(WM_PAINT)\n");
WM_SelectWindow(hObj);
_Paint(pObj, hObj);
pObj->CurrsorShow++;
GUI_TIMER_Restart(Timer1);
}
///////
/*********************************************************************
*
* _Paint
*/
static void _Paint(EDIT_Obj* pObj, EDIT_Handle hObj) {
GUI_RECT rFillRect, rInside, r, rText, rInvert;
const char GUI_UNI_PTR * pText = NULL;
int IsEnabled, CursorWidth;
IsEnabled = WM__IsEnabled(hObj);
/* Set colors and font */
LCD_SetBkColor(pObj->Props.aBkColor[IsEnabled]);
LCD_SetColor(pObj->Props.aTextColor[0]);
GUI_SetFont(pObj->Props.pFont);
/* Calculate size */
WM__GetClientRectWin(&pObj->Widget.Win, &r);
WIDGET__GetInsideRect(&pObj->Widget, &rFillRect);
if (pObj->hpText) {
pText = (const char*) GUI_ALLOC_h2p(pObj->hpText);
}
rInside = rFillRect;
rInside.x0 += pObj->Props.Border + EDIT_XOFF;
rInside.x1 -= pObj->Props.Border + EDIT_XOFF;
GUI__CalcTextRect(pText, &rInside, &rText, pObj->Props.Align);
/* Calculate position and size of cursor */
if (pObj->Widget.State & WIDGET_STATE_FOCUS) {
const char GUI_UNI_PTR * p = pText;
CursorWidth = ((pObj->XSizeCursor > 0) ? (pObj->XSizeCursor) : (1));
if (pText) {
U16 Char;
int i;
// pObj->SelSize = 3; //houhh 20061023...
if ((pObj->EditMode != GUI_EDIT_MODE_INSERT) || (pObj->SelSize)) {
int NumChars, CursorOffset;
NumChars = GUI__GetNumChars(pText);
if (pObj->CursorPos < NumChars) {
if (pObj->SelSize) {
CursorWidth = 0;
for (i = pObj->CursorPos; i < (int)(pObj->CursorPos + pObj->SelSize); i++) {
CursorOffset = GUI_UC__NumChars2NumBytes(pText, i);
Char = GUI_UC_GetCharCode (pText + CursorOffset);
CursorWidth += GUI_GetCharDistX (Char);
}
if (!CursorWidth) {
CursorWidth = 1;
}
} else {
CursorOffset = GUI_UC__NumChars2NumBytes(pText, pObj->CursorPos);
Char = GUI_UC_GetCharCode(pText + CursorOffset);
CursorWidth = GUI_GetCharDistX(Char);
}
}
}
rInvert = rText;
for (i = 0; i != pObj->CursorPos; i++) {
Char = GUI_UC__GetCharCodeInc(&p);
rInvert.x0 += GUI_GetCharDistX(Char);
}
}
}
/* WM loop */
WM_ITERATE_START(NULL) {
/* Set clipping rectangle */
WM_SetUserClipRect(&rFillRect);
/* Display text */
WIDGET__FillStringInRect(pText, &rFillRect, &rInside, &rText);
/* Display cursor if needed */
if (pObj->Widget.State & WIDGET_STATE_FOCUS) {
///////////////houhh 20061020...
// static GUI_TIMER_HANDLE Timer1 = NULL; //houhh 20061018...
if(!Timer1){
Timer1 = GUI_TIMER_Create((GUI_TIMER_CALLBACK*)ShowCurrsor, 1000*2, 0, 0); //houhh 20061018...
GUI_TIMER_SetTime(Timer1, 1000*2);
GUI_TIMER_SetPeriod(Timer1, 500);
}
if(Timer1) GUI_TIMER_Context(Timer1, hObj);
if(pObj->CurrsorShow%2) //houhh 20061022...
GUI_InvertRect(rInvert.x0, rInvert.y0, rInvert.x0 + CursorWidth - 1, rInvert.y1);
/////////////
GUI_InvertRect(rInvert.x0, rInvert.y0, rInvert.x0 + CursorWidth - 1, rInvert.y1);
}
WM_SetUserClipRect(NULL);
/* Draw the 3D effect (if configured) */
WIDGET__EFFECT_DrawDown(&pObj->Widget);
} WM_ITERATE_END();
}
/*********************************************************************
*
* _Delete
*/
static void _Delete(EDIT_Obj* pObj) {
GUI_ALLOC_FreePtr(&pObj->hpText);
}
/*********************************************************************
*
* EDIT_SetCursorAtPixel
*/
void EDIT_SetCursorAtPixel(EDIT_Handle hObj, int xPos) {
if (hObj) {
EDIT_Obj* pObj;
WM_LOCK();
pObj = EDIT_H2P(hObj);
if (pObj->hpText) {
const GUI_FONT GUI_UNI_PTR *pOldFont;
int xSize, TextWidth, NumChars;
const char GUI_UNI_PTR * pText;
pText = (char*) GUI_ALLOC_h2p(pObj->hpText);
pOldFont = GUI_SetFont(pObj->Props.pFont);
xSize = WM_GetWindowSizeX(hObj);
TextWidth = GUI_GetStringDistX(pText);
switch (pObj->Props.Align & GUI_TA_HORIZONTAL) {
case GUI_TA_HCENTER:
xPos -= (xSize - TextWidth + 1) / 2;
break;
case GUI_TA_RIGHT:
xPos -= xSize - TextWidth - (pObj->Props.Border + EDIT_XOFF);
break;
default:
xPos -= (pObj->Props.Border + EDIT_XOFF) + pObj->Widget.pEffect->EffectSize;
}
NumChars = GUI__GetNumChars(pText);
if (xPos < 0) {
EDIT__SetCursorPos(pObj, 0);
} else if (xPos > TextWidth) {
EDIT__SetCursorPos(pObj, NumChars);
} else {
int i, x, xLenChar;
U16 Char;
for (i = 0, x = 0; (i < NumChars) && (x < xPos); i++) {
Char = GUI_UC__GetCharCodeInc(&pText);
xLenChar = GUI_GetCharDistX(Char);
if (xPos < (x + xLenChar))
break;
x += xLenChar;
}
EDIT__SetCursorPos(pObj, i);
}
GUI_SetFont(pOldFont);
EDIT_Invalidate(hObj);
}
WM_UNLOCK();
}
}
/*********************************************************************
*
* _IncrementBuffer
*
* Increments the buffer size by AddBytes.
*/
static int _IncrementBuffer(EDIT_Obj* pObj, unsigned AddBytes) {
WM_HMEM hNew;
int NewSize;
NewSize = pObj->BufferSize + AddBytes;
hNew = GUI_ALLOC_Realloc(pObj->hpText, NewSize);
if (hNew) {
if (!(pObj->hpText)) {
char* pText;
pText = (char*) GUI_ALLOC_h2p(hNew);
*pText = 0;
}
pObj->BufferSize = NewSize;
pObj->hpText = hNew;
return 1;
}
return 0;
}
/*********************************************************************
*
* _IsSpaceInBuffer
*
* Checks the available space in the buffer. If there is not enough
* space left this function attempts to get more.
*
* Returns:
* 1 = requested space is available
* 0 = failed to get enough space
*/
static int _IsSpaceInBuffer(EDIT_Obj* pObj, int BytesNeeded) {
int NumBytes = 0;
if (pObj->hpText) {
NumBytes = strlen((char*)GUI_ALLOC_h2p(pObj->hpText));
}
BytesNeeded = (BytesNeeded + NumBytes + 1) - pObj->BufferSize;
if (BytesNeeded > 0) {
if (!_IncrementBuffer(pObj, BytesNeeded + EDIT_REALLOC_SIZE)) {
return 0;
}
}
return 1;
}
/*********************************************************************
*
* _IsCharsAvailable
*
* Checks weither the maximum number of characters is reached or not.
*
* Returns:
* 1 = requested number of chars is available
* 0 = maximum number of chars have reached
*/
static int _IsCharsAvailable(EDIT_Obj* pObj, int CharsNeeded) {
if ((CharsNeeded > 0) && (pObj->MaxLen > 0)) {
int NumChars = 0;
if (pObj->hpText) {
NumChars = GUI__GetNumChars((char*)GUI_ALLOC_h2p(pObj->hpText));
}
if ((CharsNeeded + NumChars) > pObj->MaxLen) {
return 0;
}
}
return 1;
}
/*********************************************************************
*
* _DeleteChar
*
* Deletes a character at the current cursor position and moves
* all bytes after the cursor position.
*/
static void _DeleteChar(EDIT_Handle hObj, EDIT_Obj* pObj) {
if (pObj->hpText) {
unsigned CursorOffset;
char* pText;
pText = (char*) GUI_ALLOC_h2p(pObj->hpText);
CursorOffset = GUI_UC__NumChars2NumBytes(pText, pObj->CursorPos);
if (CursorOffset < strlen(pText)) {
int NumBytes;
pText += CursorOffset;
NumBytes = GUI_UC_GetCharSize(pText);
strcpy(pText, pText + NumBytes);
WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
}
}
}
/*********************************************************************
*
* _InsertChar
*
* Create space at the current cursor position and inserts a character.
*/
static int _InsertChar(EDIT_Handle hObj, EDIT_Obj* pObj, U16 Char) {
if (_IsCharsAvailable(pObj, 1)) {
int BytesNeeded;
BytesNeeded = GUI_UC__CalcSizeOfChar(Char);
if (_IsSpaceInBuffer(pObj, BytesNeeded)) {
int CursorOffset;
char* pText;
pText = (char*) GUI_ALLOC_h2p(pObj->hpText);
CursorOffset = GUI_UC__NumChars2NumBytes(pText, pObj->CursorPos);
pText += CursorOffset;
memmove(pText + BytesNeeded, pText, strlen(pText) + 1);
GUI_UC_Encode(pText, Char);
WM_NotifyParent(hObj, WM_NOTIFICATION_VALUE_CHANGED);
return 1;
}
}
return 0;
}
/*********************************************************************
*
* EDIT__GetCurrentChar
*/
U16 EDIT__GetCurrentChar(EDIT_Obj* pObj) {
U16 Char = 0;
if (pObj->hpText) {
const char* pText;
pText = (const char*) GUI_ALLOC_h2p(pObj->hpText);
pText += GUI_UC__NumChars2NumBytes(pText, pObj->CursorPos);
Char = GUI_UC_GetCharCode(pText);
}
return Char;
}
/*********************************************************************
*
* EDIT__SetCursorPos
*
* Sets a new cursor position.
*/
void EDIT__SetCursorPos(EDIT_Obj* pObj, int CursorPos) {
if (pObj->hpText) {
char* pText;
int NumChars, Offset;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -