initial implementation of scrollable dialog items on WIN32
- scroll window has 16 visible items and the virtual size is not limited - CPUID parameter list now using this feature - FIXME #1: scroll window is not resized if browse button column is present - FIXME #2: only one scroll window per dialog is supported
This commit is contained in:
parent
0dfd73dd15
commit
a4a275848f
@ -2443,7 +2443,7 @@ case $target in
|
||||
LIBS="$LIBS comctl32.lib"
|
||||
fi
|
||||
fi
|
||||
DIALOG_OBJS="win32dialog.o win32paramdlg.o"
|
||||
DIALOG_OBJS="win32dialog.o win32paramdlg.o scrollwin.o"
|
||||
EXPORT_DYNAMIC=""
|
||||
;;
|
||||
*-cygwin* | *-mingw*)
|
||||
|
141
bochs/gui/scrollwin.cc
Normal file
141
bochs/gui/scrollwin.cc
Normal file
@ -0,0 +1,141 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2013 Volker Ruppert
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
LRESULT CALLBACK ScrollWinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
SCROLLINFO si;
|
||||
BOOL pull = FALSE, redraw = FALSE;
|
||||
static int vsize = 0, wsize = 0;
|
||||
static int starty = 0, scrolly = 0;
|
||||
int oldy = 0;
|
||||
RECT R;
|
||||
|
||||
switch (msg) {
|
||||
case WM_CREATE:
|
||||
GetClientRect(hwnd, &R);
|
||||
wsize = R.bottom;
|
||||
vsize = wsize;
|
||||
si.cbSize = sizeof(SCROLLINFO);
|
||||
si.fMask = SIF_POS | SIF_PAGE | SIF_RANGE | SIF_DISABLENOSCROLL;
|
||||
si.nMin = 0;
|
||||
si.nMax = vsize - 1;
|
||||
si.nPage = wsize;
|
||||
si.nPos = starty;
|
||||
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
|
||||
break;
|
||||
case WM_VSCROLL:
|
||||
oldy = starty;
|
||||
switch (LOWORD(wParam)) {
|
||||
case SB_LINEDOWN:
|
||||
if (starty < (vsize - wsize)) {
|
||||
starty++;
|
||||
redraw = TRUE;
|
||||
}
|
||||
break;
|
||||
case SB_LINEUP:
|
||||
if (starty > 0) {
|
||||
starty--;
|
||||
redraw = TRUE;
|
||||
}
|
||||
break;
|
||||
case SB_PAGEDOWN:
|
||||
if (starty < (vsize - wsize)) {
|
||||
starty += wsize;
|
||||
if (starty > (vsize - wsize)) {
|
||||
starty = vsize - wsize;
|
||||
}
|
||||
redraw = TRUE;
|
||||
}
|
||||
break;
|
||||
case SB_PAGEUP:
|
||||
if (starty > 0) {
|
||||
starty -= wsize;
|
||||
if (starty < 0) starty = 0;
|
||||
redraw = TRUE;
|
||||
}
|
||||
break;
|
||||
case SB_TOP:
|
||||
if (starty > 0) {
|
||||
starty = 0;
|
||||
redraw = TRUE;
|
||||
}
|
||||
break;
|
||||
case SB_BOTTOM:
|
||||
starty = vsize - wsize;
|
||||
redraw = TRUE;
|
||||
break;
|
||||
case SB_THUMBPOSITION:
|
||||
redraw = TRUE;
|
||||
break;
|
||||
case SB_THUMBTRACK:
|
||||
starty = HIWORD(wParam);
|
||||
SetScrollPos(hwnd, SB_VERT, starty, TRUE);
|
||||
pull = TRUE;
|
||||
redraw = (starty != oldy);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_USER:
|
||||
if (wParam == 0x1234) {
|
||||
vsize = (int)lParam;
|
||||
si.cbSize = sizeof(SCROLLINFO);
|
||||
si.fMask = SIF_RANGE | SIF_DISABLENOSCROLL;
|
||||
si.nMin = 0;
|
||||
si.nMax = vsize - 1;
|
||||
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
|
||||
redraw = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (redraw) {
|
||||
if (!pull) {
|
||||
SetScrollPos(hwnd, SB_VERT, starty, TRUE);
|
||||
}
|
||||
scrolly = oldy - starty;
|
||||
if (scrolly != 0) {
|
||||
ScrollWindowEx(hwnd, 0, scrolly, NULL, NULL, NULL, NULL, SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN);
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return DefWindowProc(hwnd, msg, wParam,lParam);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL RegisterScrollWindow(HINSTANCE hinst)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
|
||||
memset(&wc,0,sizeof(WNDCLASS));
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = (WNDPROC)ScrollWinProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hinst;
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "ScrollWin";
|
||||
|
||||
return (RegisterClass(&wc) != 0);
|
||||
}
|
27
bochs/gui/scrollwin.h
Normal file
27
bochs/gui/scrollwin.h
Normal file
@ -0,0 +1,27 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2013 Volker Ruppert
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
#ifndef SCROLLWIN_H
|
||||
|
||||
#define SCROLLWIN_H
|
||||
|
||||
BOOL RegisterScrollWindow(HINSTANCE hinst);
|
||||
|
||||
#endif
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "bochs.h"
|
||||
#include "win32res.h"
|
||||
#include "scrollwin.h"
|
||||
|
||||
#define ID_LABEL 100
|
||||
#define ID_PARAM 1000
|
||||
@ -363,6 +364,14 @@ LRESULT CALLBACK EditHexWndProc(HWND Window, UINT msg, WPARAM wParam, LPARAM lPa
|
||||
return CallWindowProc(DefEditWndProc, Window, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
BOOL IsScrollWindow(HWND hwnd)
|
||||
{
|
||||
char classname[80];
|
||||
|
||||
GetClassName(hwnd, classname, 80);
|
||||
return (!lstrcmp(classname, "ScrollWin"));
|
||||
}
|
||||
|
||||
HWND CreateLabel(HWND hDlg, UINT cid, UINT xpos, UINT ypos, UINT width, BOOL hide, const char *text)
|
||||
{
|
||||
HWND Label;
|
||||
@ -374,7 +383,11 @@ HWND CreateLabel(HWND hDlg, UINT cid, UINT xpos, UINT ypos, UINT width, BOOL hid
|
||||
r.top = ypos + 2;
|
||||
r.right = r.left + width;
|
||||
r.bottom = r.top + 16;
|
||||
MapDialogRect(hDlg, &r);
|
||||
if (IsScrollWindow(hDlg)) {
|
||||
MapDialogRect(GetParent(hDlg), &r);
|
||||
} else {
|
||||
MapDialogRect(hDlg, &r);
|
||||
}
|
||||
Label = CreateWindow("STATIC", text, WS_CHILD, r.left, r.top, r.right-r.left+1, r.bottom-r.top+1, hDlg, (HMENU)code, NULL, NULL);
|
||||
SendMessage(Label, WM_SETFONT, (WPARAM)DlgFont, TRUE);
|
||||
ShowWindow(Label, hide ? SW_HIDE : SW_SHOW);
|
||||
@ -446,7 +459,11 @@ HWND CreateBrowseButton(HWND hDlg, UINT cid, UINT xpos, UINT ypos, BOOL hide)
|
||||
r.top = ypos;
|
||||
r.right = r.left + 50;
|
||||
r.bottom = r.top + 14;
|
||||
MapDialogRect(hDlg, &r);
|
||||
if (IsScrollWindow(hDlg)) {
|
||||
MapDialogRect(GetParent(hDlg), &r);
|
||||
} else {
|
||||
MapDialogRect(hDlg, &r);
|
||||
}
|
||||
Button = CreateWindow("BUTTON", "Browse...", WS_CHILD, r.left, r.top, r.right-r.left+1, r.bottom-r.top+1, hDlg, (HMENU)code, NULL, NULL);
|
||||
SendMessage(Button, WM_SETFONT, (WPARAM)DlgFont, TRUE);
|
||||
ShowWindow(Button, hide ? SW_HIDE : SW_SHOW);
|
||||
@ -464,7 +481,11 @@ HWND CreateCheckbox(HWND hDlg, UINT cid, UINT xpos, UINT ypos, BOOL hide, bx_par
|
||||
r.top = ypos;
|
||||
r.right = r.left + 20;
|
||||
r.bottom = r.top + 14;
|
||||
MapDialogRect(hDlg, &r);
|
||||
if (IsScrollWindow(hDlg)) {
|
||||
MapDialogRect(GetParent(hDlg), &r);
|
||||
} else {
|
||||
MapDialogRect(hDlg, &r);
|
||||
}
|
||||
Checkbox = CreateWindow("BUTTON", "", BS_AUTOCHECKBOX | WS_CHILD | WS_TABSTOP,
|
||||
r.left, r.top, r.right-r.left+1, r.bottom-r.top+1,
|
||||
hDlg, (HMENU)code, NULL, NULL);
|
||||
@ -510,7 +531,11 @@ HWND CreateInput(HWND hDlg, UINT cid, UINT xpos, UINT ypos, BOOL hide, bx_param_
|
||||
r.top = ypos;
|
||||
r.right = r.left + 100;
|
||||
r.bottom = r.top + 14;
|
||||
MapDialogRect(hDlg, &r);
|
||||
if (IsScrollWindow(hDlg)) {
|
||||
MapDialogRect(GetParent(hDlg), &r);
|
||||
} else {
|
||||
MapDialogRect(hDlg, &r);
|
||||
}
|
||||
Input = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_NOPARENTNOTIFY, "EDIT", buffer,
|
||||
style, r.left, r.top, r.right-r.left+1,
|
||||
r.bottom-r.top+1, hDlg, (HMENU)code, NULL, NULL);
|
||||
@ -541,7 +566,11 @@ HWND CreateCombobox(HWND hDlg, UINT cid, UINT xpos, UINT ypos, BOOL hide, bx_par
|
||||
r.top = ypos;
|
||||
r.right = r.left + 100;
|
||||
r.bottom = r.top + 14 * ((int)(eparam->get_max() - eparam->get_min()) + 1);
|
||||
MapDialogRect(hDlg, &r);
|
||||
if (IsScrollWindow(hDlg)) {
|
||||
MapDialogRect(GetParent(hDlg), &r);
|
||||
} else {
|
||||
MapDialogRect(hDlg, &r);
|
||||
}
|
||||
Combo = CreateWindow("COMBOBOX", "", WS_CHILD | WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST,
|
||||
r.left, r.top, r.right-r.left+1, r.bottom-r.top+1, hDlg, (HMENU)code, NULL, NULL);
|
||||
j = 0;
|
||||
@ -557,6 +586,25 @@ HWND CreateCombobox(HWND hDlg, UINT cid, UINT xpos, UINT ypos, BOOL hide, bx_par
|
||||
return Combo;
|
||||
}
|
||||
|
||||
|
||||
HWND CreateScrollWindow(HWND hDlg, int xpos, int ypos, int width, int height)
|
||||
{
|
||||
RECT r;
|
||||
HWND scrollwin;
|
||||
|
||||
r.left = xpos;
|
||||
r.top = ypos;
|
||||
r.right = r.left + width;
|
||||
r.bottom = r.top + height;
|
||||
MapDialogRect(hDlg, &r);
|
||||
scrollwin = CreateWindowEx(WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT, "ScrollWin",
|
||||
"scrollwin", WS_CHILD | WS_CLIPCHILDREN | WS_TABSTOP | WS_VSCROLL,
|
||||
r.left, r.top, r.right-r.left+1, r.bottom-r.top+1,
|
||||
hDlg, NULL, NULL, NULL);
|
||||
ShowWindow(scrollwin, SW_SHOW);
|
||||
return scrollwin;
|
||||
}
|
||||
|
||||
void EnableParam(HWND hDlg, UINT cid, bx_param_c *param, BOOL val)
|
||||
{
|
||||
HWND Button, Updown;
|
||||
@ -617,6 +665,8 @@ SIZE CreateParamList(HWND hDlg, UINT lid, UINT xpos, UINT ypos, BOOL hide, bx_li
|
||||
int options;
|
||||
UINT cid, i, items, lw, w1, x0, x1, x2, y;
|
||||
BOOL ihide;
|
||||
HWND scrollwin = NULL, hParent;
|
||||
RECT vrect;
|
||||
|
||||
items = list->get_size();
|
||||
options = list->get_options();
|
||||
@ -626,6 +676,10 @@ SIZE CreateParamList(HWND hDlg, UINT lid, UINT xpos, UINT ypos, BOOL hide, bx_li
|
||||
if (options & list->USE_TAB_WINDOW) {
|
||||
y = ypos + 15;
|
||||
size.cy = 18;
|
||||
} else if (options & list->USE_SCROLL_WINDOW) {
|
||||
x0 = 5;
|
||||
y = 5;
|
||||
size.cy = 8;
|
||||
} else {
|
||||
y = ypos + 10;
|
||||
size.cy = 13;
|
||||
@ -649,6 +703,16 @@ SIZE CreateParamList(HWND hDlg, UINT lid, UINT xpos, UINT ypos, BOOL hide, bx_li
|
||||
if (size.cx < (int)(x2 + 5)) {
|
||||
size.cx = x2 + 5;
|
||||
}
|
||||
if ((items > 16) && (options & list->USE_SCROLL_WINDOW)) {
|
||||
size.cx += 20;
|
||||
scrollwin = CreateScrollWindow(hDlg, xpos, ypos, size.cx, 325);
|
||||
vrect.left = vrect.top = 0;
|
||||
vrect.right = size.cx;
|
||||
vrect.bottom = size.cy;
|
||||
hParent = scrollwin;
|
||||
} else {
|
||||
hParent = hDlg;
|
||||
}
|
||||
// create controls
|
||||
for (i = 0; i < items; i++) {
|
||||
param = list->get(i);
|
||||
@ -669,18 +733,18 @@ SIZE CreateParamList(HWND hDlg, UINT lid, UINT xpos, UINT ypos, BOOL hide, bx_li
|
||||
}
|
||||
} else {
|
||||
lw = GetLabelText(param, list, buffer);
|
||||
/* HWND ltext = */ CreateLabel(hDlg, cid, x0, y, w1, hide, buffer);
|
||||
CreateLabel(hParent, cid, x0, y, w1, hide, buffer);
|
||||
if (param->get_type() == BXT_PARAM_BOOL) {
|
||||
/* HWND control = */ CreateCheckbox(hDlg, cid, x1, y, hide, (bx_param_bool_c*)param);
|
||||
CreateCheckbox(hParent, cid, x1, y, hide, (bx_param_bool_c*)param);
|
||||
} else if (param->get_type() == BXT_PARAM_ENUM) {
|
||||
/* HWND control = */ CreateCombobox(hDlg, cid, x1, y, hide, (bx_param_enum_c*)param);
|
||||
CreateCombobox(hParent, cid, x1, y, hide, (bx_param_enum_c*)param);
|
||||
} else if (param->get_type() == BXT_PARAM_NUM) {
|
||||
/* HWND control = */ CreateInput(hDlg, cid, x1, y, hide, param);
|
||||
CreateInput(hParent, cid, x1, y, hide, param);
|
||||
} else if (param->get_type() == BXT_PARAM_STRING) {
|
||||
/* HWND control = */ CreateInput(hDlg, cid, x1, y, hide, param);
|
||||
CreateInput(hParent, cid, x1, y, hide, param);
|
||||
sparam = (bx_param_string_c*)param;
|
||||
if (sparam->get_options() & sparam->IS_FILENAME) {
|
||||
/* HWND browse = */ CreateBrowseButton(hDlg, cid, x2, y, hide);
|
||||
CreateBrowseButton(hParent, cid, x2, y, hide);
|
||||
if (size.cx < (int)(x2 + 60)) {
|
||||
size.cx = x2 + 60;
|
||||
}
|
||||
@ -690,13 +754,21 @@ SIZE CreateParamList(HWND hDlg, UINT lid, UINT xpos, UINT ypos, BOOL hide, bx_li
|
||||
EnableParam(hDlg, cid, param, FALSE);
|
||||
}
|
||||
y += 20;
|
||||
size.cy += 20;
|
||||
if ((scrollwin == NULL) || (i < 16)) {
|
||||
size.cy += 20;
|
||||
}
|
||||
if (scrollwin != NULL) {
|
||||
vrect.bottom += 20;
|
||||
}
|
||||
}
|
||||
}
|
||||
cid++;
|
||||
}
|
||||
if (options & list->USE_TAB_WINDOW) {
|
||||
CreateTabControl(hDlg, lid, xpos, ypos, size, hide, list);
|
||||
} else if (scrollwin != NULL) {
|
||||
MapDialogRect(hDlg, &vrect);
|
||||
SendMessage(scrollwin, WM_USER, 0x1234, vrect.bottom);
|
||||
} else {
|
||||
CreateGroupbox(hDlg, lid, xpos, ypos, size, hide, list);
|
||||
}
|
||||
@ -717,6 +789,9 @@ void SetParamList(HWND hDlg, bx_list_c *list)
|
||||
|
||||
lid = findDlgListBaseID(list);
|
||||
items = list->get_size();
|
||||
if (list->get_options() & list->USE_SCROLL_WINDOW) {
|
||||
hDlg = FindWindowEx(hDlg, NULL, "ScrollWin", NULL);
|
||||
}
|
||||
for (i = 0; i < items; i++) {
|
||||
cid = lid + i;
|
||||
param = list->get(i);
|
||||
@ -975,6 +1050,7 @@ int win32ParamDialog(HWND parent, const char *menu)
|
||||
INT_PTR ret;
|
||||
|
||||
InitDlgFont();
|
||||
RegisterScrollWindow(NULL);
|
||||
ret = DialogBoxParam(NULL, MAKEINTRESOURCE(PARAM_DLG), parent, (DLGPROC)ParamDlgProc, (LPARAM)menu);
|
||||
DeleteObject(DlgFont);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user