📄 scrolled.c
字号:
/*
** $Id: scrolled.c,v 1.14 2004/10/18 00:49:28 snig Exp $
**
** scrolled.c: basic scrolled window support
**
** Copyright (C) 2004 Feynman Software.
**
** Current maintainer: Zhong Shuyi (zhongsy@minigui.org).
**
** Create date: 2004/03/01
*/
/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "common.h"
#include "minigui.h"
#include "gdi.h"
#include "window.h"
#include "control.h"
#include "cliprect.h"
#include "internals.h"
#include "ctrlclass.h"
#ifdef _CTRL_SCROLLVIEW
#include "scrolled.h"
#define SV_H_OUTRANGE() \
(pscrdata->nContWidth > pscrdata->visibleWidth)
#define SV_V_OUTRANGE() \
(pscrdata->nContHeight > pscrdata->visibleHeight)
#define svHScroll(scrollval, newpos) \
svScroll(hWnd, pscrdata, scrollval, newpos, TRUE);
#define svVScroll(scrollval, newpos) \
svScroll (hWnd, pscrdata, scrollval, newpos, FALSE);
/* ---------------------------------------------------------------------------- */
/* adjust the horz scrollbar according to the content offset value */
int scrolled_set_hscrollinfo (HWND hWnd, PSCRDATA pscrdata)
{
SCROLLINFO si;
if (pscrdata->sbPolicy == SB_POLICY_NEVER) {
ShowScrollBar (hWnd, SB_HORZ, FALSE);
return 0;
}
else if (pscrdata->sbPolicy == SB_POLICY_AUTOMATIC) {
if (!SV_H_OUTRANGE()) {
ShowScrollBar (hWnd, SB_HORZ, FALSE);
return 0;
}
}
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = pscrdata->nContWidth - 1;
si.nPage = pscrdata->visibleWidth;
si.nPos = pscrdata->nContX;
SetScrollInfo (hWnd, SB_HORZ, &si, TRUE);
ShowScrollBar (hWnd, SB_HORZ, TRUE);
return 0;
}
/* adjust the vert scrollbar according to the content offset value */
int scrolled_set_vscrollinfo (HWND hWnd, PSCRDATA pscrdata)
{
SCROLLINFO si;
if (pscrdata->sbPolicy == SB_POLICY_NEVER) {
ShowScrollBar (hWnd, SB_VERT, FALSE);
return 0;
}
else if (pscrdata->sbPolicy == SB_POLICY_AUTOMATIC) {
if (!SV_V_OUTRANGE()) {
ShowScrollBar (hWnd, SB_VERT, FALSE);
return 0;
}
}
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = pscrdata->nContHeight - 1;
si.nPage = pscrdata->visibleHeight;
si.nPos = pscrdata->nContY;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
ShowScrollBar (hWnd, SB_VERT, TRUE);
return 0;
}
/* set content position */
BOOL scrolled_set_cont_pos (HWND hWnd, PSCRDATA pscrdata, int cont_x, int cont_y)
{
BOOL bChange = FALSE;
if (cont_x >= 0 && cont_x <= pscrdata->nContWidth - pscrdata->visibleWidth) {
pscrdata->nContX = cont_x;
//move content
scrolled_set_content (hWnd, pscrdata, FALSE);
SetScrollPos (hWnd, SB_HORZ, cont_x);
bChange = TRUE;
}
if (cont_y >= 0 && cont_y <= pscrdata->nContHeight - pscrdata->visibleHeight) {
pscrdata->nContY = cont_y;
//move content
scrolled_set_content (hWnd, pscrdata, FALSE);
SetScrollPos (hWnd, SB_VERT, cont_y);
bChange = TRUE;
}
return bChange;
}
/* make a point in the content area visible */
BOOL scrolled_make_pos_visible (HWND hWnd, PSCRDATA pscrdata, int pos_x, int pos_y)
{
int cont_x = -1, cont_y = -1;
if (pos_x >= 0) {
if (pos_x >= pscrdata->nContWidth)
pos_x = pscrdata->nContWidth - 1;
if (pos_x < pscrdata->nContX)
cont_x = pos_x;
else if (pos_x > pscrdata->nContX + pscrdata->visibleWidth - 1)
cont_x = pos_x - pscrdata->visibleWidth + 1;
}
if (pos_y >= 0) {
if (pos_y >= pscrdata->nContHeight)
pos_y = pscrdata->nContHeight - 1;
if (pos_y < pscrdata->nContY)
cont_y = pos_y;
else if (pos_y > pscrdata->nContY + pscrdata->visibleHeight - 1)
cont_y = pos_y - pscrdata->visibleHeight + 1;
}
return scrolled_set_cont_pos (hWnd, pscrdata, cont_x, cont_y);
}
/* scrollbar action */
static void svScroll (HWND hWnd, PSCRDATA pscrdata, int scrollval, int newpos, BOOL bHScroll)
{
int scrollBoundMax;
int scrollBoundMin;
int scroll = 0;
BOOL bScroll = FALSE;
int nOffset;
if (bHScroll) {
scrollBoundMax = pscrdata->nContWidth - pscrdata->visibleWidth;
nOffset = pscrdata->nContX;
}
else {
scrollBoundMax = pscrdata->nContHeight - pscrdata->visibleHeight;
nOffset = pscrdata->nContY;
}
scrollBoundMin = 0;
if (newpos >= 0) { // SB_THUMBTRACK
scrollval = newpos - nOffset;
}
scroll = (scrollval>0?scrollval:-scrollval);
if (scrollval > 0 && nOffset < scrollBoundMax) {
if ((nOffset + scroll) > scrollBoundMax)
nOffset = scrollBoundMax;
else
nOffset += scroll;
bScroll = TRUE;
}
else if ( scrollval < 0 && nOffset > scrollBoundMin) {
if ((nOffset - scroll) < scrollBoundMin)
nOffset = scrollBoundMin;
else
nOffset -= scroll;
bScroll = TRUE;
}
if (bScroll) {
scrolled_set_cont_pos (hWnd, pscrdata, (bHScroll?nOffset:-1), (bHScroll?-1:nOffset));
}
}
/* set the position and size of the viewport window */
void scrolled_set_visible (HWND hWnd, PSCRDATA pscrdata)
{
/* maybe we need to reset content width and height */
if (pscrdata->nContWidth < pscrdata->visibleWidth) {
pscrdata->nContWidth = pscrdata->visibleWidth;
//should refresh the whole window
scrolled_set_content (hWnd, pscrdata, TRUE);
}
if (pscrdata->nContHeight < pscrdata->visibleHeight) {
pscrdata->nContHeight = pscrdata->visibleHeight;
//should refresh the whole window
scrolled_set_content (hWnd, pscrdata, TRUE);
}
}
int scrolled_visible_to_content (PSCRDATA pscrdata, int *x, int *y)
{
if (x)
*x = *x + pscrdata->nContX;
if (y)
*y = *y + pscrdata->nContY;
return 0;
}
int scrolled_content_to_visible (PSCRDATA pscrdata, int *x, int *y)
{
if (x)
*x = *x - pscrdata->nContX;
if (y)
*y = *y - pscrdata->nContY;
if (!x || !y)
return -1;
if (*x < 0 || *x > pscrdata->visibleWidth ||
*y < 0 || *y > pscrdata->visibleHeight)
return -1;
return 0;
}
/* recalc visible area and container area, then set scrollbar */
void scrolled_recalc_areas (HWND hWnd, PSCRDATA pscrdata, int new_w, int new_h)
{
int old_vw, old_vh;
if (!pscrdata)
return;
old_vw = pscrdata->visibleWidth;
old_vh = pscrdata->visibleHeight;
/* reset viewport as client - margin */
pscrdata->visibleWidth = new_w;
pscrdata->visibleHeight = new_h;
scrolled_set_visible (hWnd, pscrdata);
if (pscrdata->nContWidth == old_vw) {
pscrdata->nContWidth = pscrdata->visibleWidth;
//should refresh the whole window
scrolled_set_content (hWnd, pscrdata, TRUE);
}
if (pscrdata->nContHeight == old_vh) {
pscrdata->nContHeight = pscrdata->visibleHeight;
//should refresh the whole window
scrolled_set_content (hWnd, pscrdata, TRUE);
}
scrolled_set_hscrollinfo (hWnd, pscrdata);
scrolled_set_vscrollinfo (hWnd, pscrdata);
}
void scrolled_hscroll (HWND hWnd, PSCRDATA pscrdata, WPARAM wParam, LPARAM lParam)
{
int hscroll = 0, newpos = -1;
if (wParam == SB_LINERIGHT)
hscroll = pscrdata->hScrollVal;
else if (wParam == SB_LINELEFT)
hscroll = -pscrdata->hScrollVal;
else if (wParam == SB_PAGERIGHT)
hscroll = pscrdata->hScrollPageVal;
else if (wParam == SB_PAGELEFT)
hscroll = -pscrdata->hScrollPageVal;
else if (wParam == SB_THUMBTRACK)
newpos = lParam;
else if (wParam == SB_THUMBPOSITION) {
newpos = lParam;
}
svHScroll (hscroll, newpos);
}
void scrolled_vscroll (HWND hWnd, PSCRDATA pscrdata, WPARAM wParam, LPARAM lParam)
{
int vscroll = 0, newpos = -1;
if (wParam == SB_LINEDOWN)
vscroll = pscrdata->vScrollVal;
else if (wParam == SB_LINEUP)
vscroll = -pscrdata->vScrollVal;
else if (wParam == SB_PAGEDOWN)
vscroll = pscrdata->vScrollPageVal;
else if (wParam == SB_PAGEUP)
vscroll = -pscrdata->vScrollPageVal;
else if (wParam == SB_THUMBTRACK) {
newpos = lParam;
}
else if (wParam == SB_THUMBPOSITION) {
newpos = lParam;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -