547 lines
15 KiB
C
547 lines
15 KiB
C
/*
|
|
*********************************************************************************************************
|
|
* uC/GUI
|
|
* Universal graphic software for embedded applications
|
|
*
|
|
* (c) Copyright 2002, Micrium Inc., Weston, FL
|
|
* (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH
|
|
*
|
|
* µC/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 : FRAMEWIN_SetResizeable.c
|
|
Purpose :
|
|
---------------------------END-OF-HEADER------------------------------
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include "FRAMEWIN_Private.h"
|
|
|
|
#if GUI_WINSUPPORT
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Defines
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
#ifndef FRAMEWIN_REACT_BORDER
|
|
#define FRAMEWIN_REACT_BORDER 3
|
|
#endif
|
|
#ifndef FRAMEWIN_MINSIZE_X
|
|
#define FRAMEWIN_MINSIZE_X 20
|
|
#endif
|
|
#ifndef FRAMEWIN_MINSIZE_Y
|
|
#define FRAMEWIN_MINSIZE_Y 20
|
|
#endif
|
|
|
|
#define FRAMEWIN_RESIZE_X (1<<0)
|
|
#define FRAMEWIN_RESIZE_Y (1<<1)
|
|
#define FRAMEWIN_REPOS_X (1<<2)
|
|
#define FRAMEWIN_REPOS_Y (1<<3)
|
|
#define FRAMEWIN_MOUSEOVER (1<<4)
|
|
#define FRAMEWIN_RESIZE (FRAMEWIN_RESIZE_X | FRAMEWIN_RESIZE_Y | FRAMEWIN_REPOS_X | FRAMEWIN_REPOS_Y)
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static data
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
static GUI_HOOK _HOOK_Resizeable;
|
|
static int _CaptureX;
|
|
static int _CaptureY;
|
|
static int _CaptureFlags;
|
|
|
|
#if GUI_SUPPORT_CURSOR
|
|
static const GUI_CURSOR GUI_UNI_PTR * _pOldCursor;
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static data, cursors
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
#if GUI_SUPPORT_CURSOR
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Cursor colors
|
|
*/
|
|
static GUI_CONST_STORAGE GUI_COLOR _ColorsCursor[] = {
|
|
0x0000FF,0x000000,0xFFFFFF
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_LOGPALETTE _PalCursor = {
|
|
3, /* number of entries */
|
|
1, /* Has transparency */
|
|
&_ColorsCursor[0]
|
|
};
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Cursor data, CursorH
|
|
*/
|
|
static GUI_CONST_STORAGE unsigned char _acResizeCursorH[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x40, 0x00, 0x40, 0x00,
|
|
0x01, 0x40, 0x00, 0x50, 0x00,
|
|
0x06, 0x40, 0x00, 0x64, 0x00,
|
|
0x1A, 0x55, 0x55, 0x69, 0x00,
|
|
0x6A, 0xAA, 0xAA, 0xAA, 0x40,
|
|
0x1A, 0x55, 0x55, 0x69, 0x00,
|
|
0x06, 0x40, 0x00, 0x64, 0x00,
|
|
0x01, 0x40, 0x00, 0x50, 0x00,
|
|
0x00, 0x40, 0x00, 0x40, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_BITMAP _bmResizeCursorH = {
|
|
17, /* XSize */
|
|
17, /* YSize */
|
|
5, /* BytesPerLine */
|
|
2, /* BitsPerPixel */
|
|
_acResizeCursorH, /* Pointer to picture data (indices) */
|
|
&_PalCursor /* Pointer to palette */
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_CURSOR _ResizeCursorH = {
|
|
&_bmResizeCursorH, 8, 8
|
|
};
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Cursor data, CursorV
|
|
*/
|
|
static GUI_CONST_STORAGE unsigned char _acResizeCursorV[] = {
|
|
0x00, 0x00, 0x40, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x06, 0xA4, 0x00, 0x00,
|
|
0x00, 0x1A, 0xA9, 0x00, 0x00,
|
|
0x00, 0x55, 0x95, 0x40, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x55, 0x95, 0x40, 0x00,
|
|
0x00, 0x1A, 0xA9, 0x00, 0x00,
|
|
0x00, 0x06, 0xA4, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x00, 0x40, 0x00, 0x00
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_BITMAP _bmResizeCursorV = {
|
|
17, /* XSize */
|
|
17, /* YSize */
|
|
5, /* BytesPerLine */
|
|
2, /* BitsPerPixel */
|
|
_acResizeCursorV, /* Pointer to picture data (indices) */
|
|
&_PalCursor /* Pointer to palette */
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_CURSOR _ResizeCursorV = {
|
|
&_bmResizeCursorV, 8, 8
|
|
};
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Cursor data, CursorDD
|
|
*/
|
|
static GUI_CONST_STORAGE unsigned char _acResizeCursorDD[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x05, 0x55, 0x00, 0x00, 0x00,
|
|
0x06, 0xA4, 0x00, 0x00, 0x00,
|
|
0x06, 0x90, 0x00, 0x00, 0x00,
|
|
0x06, 0x64, 0x00, 0x00, 0x00,
|
|
0x05, 0x19, 0x00, 0x00, 0x00,
|
|
0x04, 0x06, 0x40, 0x00, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x00, 0x00, 0x64, 0x04, 0x00,
|
|
0x00, 0x00, 0x19, 0x14, 0x00,
|
|
0x00, 0x00, 0x06, 0x64, 0x00,
|
|
0x00, 0x00, 0x01, 0xA4, 0x00,
|
|
0x00, 0x00, 0x06, 0xA4, 0x00,
|
|
0x00, 0x00, 0x15, 0x54, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_BITMAP _bmResizeCursorDD = {
|
|
17, /* XSize */
|
|
17, /* YSize */
|
|
5, /* BytesPerLine */
|
|
2, /* BitsPerPixel */
|
|
_acResizeCursorDD, /* Pointer to picture data (indices) */
|
|
&_PalCursor /* Pointer to palette */
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_CURSOR _ResizeCursorDD = {
|
|
&_bmResizeCursorDD, 8, 8
|
|
};
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Cursor data, CursorDU
|
|
*/
|
|
static GUI_CONST_STORAGE unsigned char _acResizeCursorDU[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x15, 0x54, 0x00,
|
|
0x00, 0x00, 0x06, 0xA4, 0x00,
|
|
0x00, 0x00, 0x01, 0xA4, 0x00,
|
|
0x00, 0x00, 0x06, 0x64, 0x00,
|
|
0x00, 0x00, 0x19, 0x14, 0x00,
|
|
0x00, 0x00, 0x64, 0x04, 0x00,
|
|
0x00, 0x01, 0x90, 0x00, 0x00,
|
|
0x04, 0x06, 0x40, 0x00, 0x00,
|
|
0x05, 0x19, 0x00, 0x00, 0x00,
|
|
0x06, 0x64, 0x00, 0x00, 0x00,
|
|
0x06, 0x90, 0x00, 0x00, 0x00,
|
|
0x06, 0xA4, 0x00, 0x00, 0x00,
|
|
0x05, 0x55, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_BITMAP _bmResizeCursorDU = {
|
|
17, /* XSize */
|
|
17, /* YSize */
|
|
5, /* BytesPerLine */
|
|
2, /* BitsPerPixel */
|
|
_acResizeCursorDU, /* Pointer to picture data (indices) */
|
|
&_PalCursor /* Pointer to palette */
|
|
};
|
|
|
|
static GUI_CONST_STORAGE GUI_CURSOR _ResizeCursorDU = {
|
|
&_bmResizeCursorDU, 8, 8
|
|
};
|
|
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Static code, helpers
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* _SetResizeCursor
|
|
*/
|
|
#if GUI_SUPPORT_CURSOR
|
|
static void _SetResizeCursor(int Mode) {
|
|
const GUI_CURSOR GUI_UNI_PTR * pNewCursor = NULL;
|
|
if (Mode) {
|
|
int Direction;
|
|
Direction = Mode & (FRAMEWIN_RESIZE_X | FRAMEWIN_RESIZE_Y);
|
|
if (Direction == FRAMEWIN_RESIZE_X) {
|
|
pNewCursor = &_ResizeCursorH;
|
|
} else if (Direction == FRAMEWIN_RESIZE_Y) {
|
|
pNewCursor = &_ResizeCursorV;
|
|
} else {
|
|
Direction = Mode & (FRAMEWIN_REPOS_X | FRAMEWIN_REPOS_Y);
|
|
if ((Direction == (FRAMEWIN_REPOS_X | FRAMEWIN_REPOS_Y)) || !Direction) {
|
|
pNewCursor = &_ResizeCursorDD;
|
|
} else {
|
|
pNewCursor = &_ResizeCursorDU;
|
|
}
|
|
}
|
|
}
|
|
if (pNewCursor) {
|
|
const GUI_CURSOR GUI_UNI_PTR * pOldCursor;
|
|
pOldCursor = GUI_CURSOR_Select(pNewCursor);
|
|
if (_pOldCursor == NULL) {
|
|
_pOldCursor = pOldCursor;
|
|
}
|
|
} else if (_pOldCursor) {
|
|
GUI_CURSOR_Select(_pOldCursor);
|
|
_pOldCursor = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _SetCapture
|
|
*/
|
|
static void _SetCapture(FRAMEWIN_Handle hWin, int x, int y, int Mode) {
|
|
if ((_CaptureFlags & FRAMEWIN_REPOS_X) == 0) {
|
|
_CaptureX = x;
|
|
}
|
|
if ((_CaptureFlags & FRAMEWIN_REPOS_Y) == 0) {
|
|
_CaptureY = y;
|
|
}
|
|
if (Mode) {
|
|
if (WM_HasCaptured(hWin) == 0) {
|
|
WM_SetCapture(hWin, 0);
|
|
}
|
|
#if GUI_SUPPORT_CURSOR
|
|
_SetResizeCursor(Mode);
|
|
#endif
|
|
if (Mode & FRAMEWIN_MOUSEOVER) {
|
|
Mode = 0;
|
|
}
|
|
_CaptureFlags = (Mode | FRAMEWIN_MOUSEOVER);
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _ChangeWindowPosSize
|
|
*/
|
|
static void _ChangeWindowPosSize(FRAMEWIN_Handle hWin, int* px, int* py) {
|
|
int dx = 0, dy = 0;
|
|
GUI_RECT Rect;
|
|
WM_GetClientRectEx(hWin, &Rect);
|
|
/* Calculate new size of window */
|
|
if (_CaptureFlags & FRAMEWIN_RESIZE_X) {
|
|
dx = (_CaptureFlags & FRAMEWIN_REPOS_X) ? (_CaptureX - *px) : (*px - _CaptureX);
|
|
}
|
|
if (_CaptureFlags & FRAMEWIN_RESIZE_Y) {
|
|
dy = (_CaptureFlags & FRAMEWIN_REPOS_Y) ? (_CaptureY - *py) : (*py - _CaptureY);
|
|
}
|
|
/* Check the minimal size of window */
|
|
if ((Rect.x1 + dx + 1) < FRAMEWIN_MINSIZE_X) {
|
|
dx = FRAMEWIN_MINSIZE_X - Rect.x1 - 1;
|
|
*px = _CaptureX + dx;
|
|
}
|
|
if ((Rect.y1 + dy + 1) < FRAMEWIN_MINSIZE_Y) {
|
|
dy = FRAMEWIN_MINSIZE_Y - Rect.y1 - 1;
|
|
*py = _CaptureY + dy;
|
|
}
|
|
/* Set new window position */
|
|
if (_CaptureFlags & FRAMEWIN_REPOS_X) {
|
|
WM_MoveWindow(hWin, -dx, 0);
|
|
}
|
|
if (_CaptureFlags & FRAMEWIN_REPOS_Y) {
|
|
WM_MoveWindow(hWin, 0, -dy);
|
|
}
|
|
/* Set new window size */
|
|
WM_ResizeWindow(hWin, dx, dy);
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _CheckBorderX
|
|
*/
|
|
static int _CheckBorderX(int x, int x1, int Border) {
|
|
int Mode = 0;
|
|
if (x > (x1 - Border)) {
|
|
Mode = FRAMEWIN_RESIZE_X;
|
|
} else if (x < (Border)) {
|
|
Mode = FRAMEWIN_RESIZE_X | FRAMEWIN_REPOS_X;
|
|
}
|
|
return Mode;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _CheckBorderY
|
|
*/
|
|
static int _CheckBorderY(int y, int y1, int Border) {
|
|
int Mode = 0;
|
|
if (y > (y1 - Border)) {
|
|
Mode = FRAMEWIN_RESIZE_Y;
|
|
} else if (y < (Border)) {
|
|
Mode = FRAMEWIN_RESIZE_Y | FRAMEWIN_REPOS_Y;
|
|
}
|
|
return Mode;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _CheckReactBorder
|
|
*/
|
|
static int _CheckReactBorder(FRAMEWIN_Handle hWin, int x, int y) {
|
|
int Mode = 0;
|
|
GUI_RECT r;
|
|
WM_GetClientRectEx(hWin, &r);
|
|
if ((x >= 0) && (y >= 0) && (x <= r.x1) && (y <= r.y1)) {
|
|
Mode |= _CheckBorderX(x, r.x1, FRAMEWIN_REACT_BORDER);
|
|
if (Mode) {
|
|
Mode |= _CheckBorderY(y, r.y1, 4 * FRAMEWIN_REACT_BORDER);
|
|
} else {
|
|
Mode |= _CheckBorderY(y, r.y1, FRAMEWIN_REACT_BORDER);
|
|
if (Mode) {
|
|
Mode |= _CheckBorderX(x, r.x1, 4 * FRAMEWIN_REACT_BORDER);
|
|
}
|
|
}
|
|
}
|
|
return Mode;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _OnTouch
|
|
*/
|
|
static int _OnTouch(FRAMEWIN_Handle hWin, WM_MESSAGE* pMsg) {
|
|
const GUI_PID_STATE* pState = (const GUI_PID_STATE*)pMsg->Data.p;
|
|
if (pState) { /* Something happened in our area (pressed or released) */
|
|
int x, y, Mode;
|
|
x = pState->x;
|
|
y = pState->y;
|
|
Mode = _CheckReactBorder(hWin, x, y);
|
|
if (pState->Pressed == 1) {
|
|
if (_CaptureFlags & FRAMEWIN_RESIZE) {
|
|
_ChangeWindowPosSize(hWin, &x, &y);
|
|
_SetCapture(hWin, x, y, 0);
|
|
return 1;
|
|
} else if (Mode) {
|
|
WM_SetFocus(hWin);
|
|
WM_BringToTop(hWin);
|
|
_SetCapture(hWin, x, y, Mode);
|
|
return 1;
|
|
}
|
|
#if (GUI_SUPPORT_MOUSE & GUI_SUPPORT_CURSOR)
|
|
else if (_CaptureFlags) {
|
|
WM_ReleaseCapture();
|
|
return 1;
|
|
}
|
|
#endif
|
|
} else if (WM_HasCaptured(hWin)) {
|
|
_CaptureFlags &= ~(FRAMEWIN_RESIZE);
|
|
#if (GUI_SUPPORT_MOUSE & GUI_SUPPORT_CURSOR)
|
|
if (!Mode)
|
|
#endif
|
|
{
|
|
WM_ReleaseCapture();
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************
|
|
*
|
|
* _ForwardMouseOverMsg
|
|
*/
|
|
#if (GUI_SUPPORT_MOUSE & GUI_SUPPORT_CURSOR)
|
|
static int _ForwardMouseOverMsg(FRAMEWIN_Handle hWin, WM_MESSAGE* pMsg) {
|
|
GUI_PID_STATE* pState = (GUI_PID_STATE *)pMsg->Data.p;
|
|
WM_HWIN hBelow;
|
|
pState->x += WM_GetWindowOrgX(hWin);
|
|
pState->y += WM_GetWindowOrgY(hWin);
|
|
hBelow = WM_Screen2hWin(pState->x, pState->y);
|
|
if (hBelow && (hBelow != hWin)) {
|
|
pState->x -= WM_GetWindowOrgX(hBelow);
|
|
pState->y -= WM_GetWindowOrgY(hBelow);
|
|
WM__SendMessage(hBelow, pMsg);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* _OnMouseOver
|
|
*/
|
|
#if (GUI_SUPPORT_MOUSE & GUI_SUPPORT_CURSOR)
|
|
static int _OnMouseOver(FRAMEWIN_Handle hWin, WM_MESSAGE* pMsg) {
|
|
const GUI_PID_STATE* pState = (const GUI_PID_STATE *)pMsg->Data.p;
|
|
if (pState) {
|
|
int x, y, Mode;
|
|
x = pState->x;
|
|
y = pState->y;
|
|
Mode = _CheckReactBorder(hWin, x, y);
|
|
if (Mode) {
|
|
if (_ForwardMouseOverMsg(hWin, pMsg) == 0) {
|
|
_SetCapture(hWin, x, y, Mode | FRAMEWIN_MOUSEOVER);
|
|
}
|
|
return 1;
|
|
} else if (WM_HasCaptured(hWin)) {
|
|
if ((_CaptureFlags & FRAMEWIN_RESIZE) == 0) {
|
|
WM_ReleaseCapture();
|
|
_ForwardMouseOverMsg(hWin, pMsg);
|
|
}
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/*********************************************************************
|
|
*
|
|
* static code, hook function
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* _HOOKFUNC_Resizeable
|
|
*/
|
|
static int _HOOKFUNC_Resizeable(WM_MESSAGE* pMsg) {
|
|
WM_HWIN hWin = pMsg->hWin;
|
|
if (WM_HasCaptured(hWin) && (_CaptureFlags == 0)) {
|
|
return 0;
|
|
}
|
|
if (FRAMEWIN_IsMinimized(hWin) || FRAMEWIN_IsMaximized(hWin)) {
|
|
return 0;
|
|
}
|
|
switch(pMsg->MsgId) {
|
|
case WM_TOUCH:
|
|
return _OnTouch(hWin, pMsg);
|
|
#if (GUI_SUPPORT_MOUSE & GUI_SUPPORT_CURSOR)
|
|
case WM_MOUSEOVER:
|
|
return _OnMouseOver(hWin, pMsg);
|
|
#endif
|
|
case WM_CAPTURE_RELEASED:
|
|
#if GUI_SUPPORT_CURSOR
|
|
_SetResizeCursor(0);
|
|
#endif
|
|
_CaptureFlags = 0;
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*********************************************************************
|
|
*
|
|
* Public code
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
/*********************************************************************
|
|
*
|
|
* FRAMEWIN_SetResizeable
|
|
*/
|
|
void FRAMEWIN_SetResizeable(FRAMEWIN_Handle hObj, int State) {
|
|
if (hObj) {
|
|
FRAMEWIN_Obj* pObj;
|
|
WM_LOCK();
|
|
pObj = FRAMEWIN_H2P(hObj);
|
|
if (pObj) {
|
|
if (State) {
|
|
GUI_HOOK_Add(&pObj->pFirstHook, &_HOOK_Resizeable, &_HOOKFUNC_Resizeable);
|
|
} else {
|
|
GUI_HOOK_Remove(&pObj->pFirstHook, &_HOOK_Resizeable);
|
|
}
|
|
}
|
|
WM_UNLOCK();
|
|
}
|
|
}
|
|
|
|
#else
|
|
void FRAMEWIN_SetResizeable_c(void) {} /* avoid empty object files */
|
|
#endif /* GUI_WINSUPPORT */
|
|
|
|
/*************************** End of file ****************************/
|