W340-3 menu columns
In some menus the options columns didn't line up perfectly when very long items were present.
This commit is contained in:
@@ -74,6 +74,7 @@ Platform- and/or Interface-Specific Fixes
|
|||||||
win32: win32 build no longer defines MICRO
|
win32: win32 build no longer defines MICRO
|
||||||
win32: allow error save files to be generated
|
win32: allow error save files to be generated
|
||||||
win32gui: make error() work; it was essentially non-operative in 3.4.0
|
win32gui: make error() work; it was essentially non-operative in 3.4.0
|
||||||
|
win32gui: fix alignment of columns in menu windows
|
||||||
win32tty: honour the use_inverse option and default to ATR_BOLD if disabled
|
win32tty: honour the use_inverse option and default to ATR_BOLD if disabled
|
||||||
win32tty: respond only to mouse clicks not mouse movement
|
win32tty: respond only to mouse clicks not mouse movement
|
||||||
X11: restore support for non-square tiles when USE_XPM is defined
|
X11: restore support for non-square tiles when USE_XPM is defined
|
||||||
|
|||||||
+107
-46
@@ -11,9 +11,11 @@
|
|||||||
#include "mhfont.h"
|
#include "mhfont.h"
|
||||||
#include "mhdlg.h"
|
#include "mhdlg.h"
|
||||||
|
|
||||||
#define MENU_MARGIN 0
|
#define MENU_MARGIN 0
|
||||||
#define NHMENU_STR_SIZE BUFSZ
|
#define NHMENU_STR_SIZE BUFSZ
|
||||||
#define MIN_TABSTOP_SIZE 8
|
#define MIN_TABSTOP_SIZE 0
|
||||||
|
#define NUMTABS 15
|
||||||
|
#define TAB_SEPARATION 10 /* pixels between each tab stop */
|
||||||
|
|
||||||
#define DEFAULT_COLOR_BG_TEXT COLOR_WINDOW
|
#define DEFAULT_COLOR_BG_TEXT COLOR_WINDOW
|
||||||
#define DEFAULT_COLOR_FG_TEXT COLOR_WINDOWTEXT
|
#define DEFAULT_COLOR_FG_TEXT COLOR_WINDOWTEXT
|
||||||
@@ -21,14 +23,14 @@
|
|||||||
#define DEFAULT_COLOR_FG_MENU COLOR_WINDOWTEXT
|
#define DEFAULT_COLOR_FG_MENU COLOR_WINDOWTEXT
|
||||||
|
|
||||||
typedef struct mswin_menu_item {
|
typedef struct mswin_menu_item {
|
||||||
int glyph;
|
int glyph;
|
||||||
ANY_P identifier;
|
ANY_P identifier;
|
||||||
CHAR_P accelerator;
|
CHAR_P accelerator;
|
||||||
CHAR_P group_accel;
|
CHAR_P group_accel;
|
||||||
int attr;
|
int attr;
|
||||||
char str[NHMENU_STR_SIZE];
|
char str[NHMENU_STR_SIZE];
|
||||||
BOOLEAN_P presel;
|
BOOLEAN_P presel;
|
||||||
int count;
|
int count;
|
||||||
BOOL has_focus;
|
BOOL has_focus;
|
||||||
} NHMenuItem, *PNHMenuItem;
|
} NHMenuItem, *PNHMenuItem;
|
||||||
|
|
||||||
@@ -38,13 +40,13 @@ typedef struct mswin_nethack_menu_window {
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
struct menu_list {
|
struct menu_list {
|
||||||
int size; /* number of items in items[] */
|
int size; /* number of items in items[] */
|
||||||
int allocated; /* number of allocated slots in items[] */
|
int allocated; /* number of allocated slots in items[] */
|
||||||
PNHMenuItem items; /* menu items */
|
PNHMenuItem items; /* menu items */
|
||||||
char gacc[QBUFSZ]; /* group accelerators */
|
char gacc[QBUFSZ]; /* group accelerators */
|
||||||
BOOL counting; /* counting flag */
|
BOOL counting; /* counting flag */
|
||||||
char prompt[QBUFSZ]; /* menu prompt */
|
char prompt[QBUFSZ]; /* menu prompt */
|
||||||
int tab_stop_size; /* for options menu we use tabstops to align option values */
|
int tab_stop_size[NUMTABS];/* tabstops to align option values */
|
||||||
} menu;
|
} menu;
|
||||||
|
|
||||||
struct menu_text {
|
struct menu_text {
|
||||||
@@ -488,6 +490,8 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MSNH_MSG_STARTMENU:
|
case MSNH_MSG_STARTMENU:
|
||||||
|
{
|
||||||
|
int i;
|
||||||
if( data->type!=MENU_TYPE_MENU )
|
if( data->type!=MENU_TYPE_MENU )
|
||||||
SetMenuType(hWnd, MENU_TYPE_MENU);
|
SetMenuType(hWnd, MENU_TYPE_MENU);
|
||||||
|
|
||||||
@@ -498,14 +502,18 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
data->menu.allocated = 0;
|
data->menu.allocated = 0;
|
||||||
data->done = 0;
|
data->done = 0;
|
||||||
data->result = 0;
|
data->result = 0;
|
||||||
data->menu.tab_stop_size = MIN_TABSTOP_SIZE;
|
for (i = 0; i < NUMTABS; ++i)
|
||||||
break;
|
data->menu.tab_stop_size[i] = MIN_TABSTOP_SIZE;
|
||||||
|
} break;
|
||||||
|
|
||||||
case MSNH_MSG_ADDMENU:
|
case MSNH_MSG_ADDMENU:
|
||||||
{
|
{
|
||||||
PMSNHMsgAddMenu msg_data = (PMSNHMsgAddMenu)lParam;
|
PMSNHMsgAddMenu msg_data = (PMSNHMsgAddMenu)lParam;
|
||||||
char *p, *p1;
|
char *p, *p1;
|
||||||
int new_item;
|
int new_item;
|
||||||
|
HDC hDC;
|
||||||
|
int column;
|
||||||
|
HFONT saveFont;
|
||||||
|
|
||||||
if( data->type!=MENU_TYPE_MENU ) break;
|
if( data->type!=MENU_TYPE_MENU ) break;
|
||||||
if( strlen(msg_data->str)==0 ) break;
|
if( strlen(msg_data->str)==0 ) break;
|
||||||
@@ -526,14 +534,33 @@ void onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
data->menu.items[new_item].presel = msg_data->presel;
|
data->menu.items[new_item].presel = msg_data->presel;
|
||||||
|
|
||||||
/* calculate tabstop size */
|
/* calculate tabstop size */
|
||||||
|
hDC = GetDC(hWnd);
|
||||||
|
saveFont = SelectObject(hDC, mswin_get_font(NHW_MENU, msg_data->attr, hDC, FALSE));
|
||||||
p1 = data->menu.items[new_item].str;
|
p1 = data->menu.items[new_item].str;
|
||||||
p = strchr(data->menu.items[new_item].str, '\t');
|
p = strchr(data->menu.items[new_item].str, '\t');
|
||||||
while( p ) {
|
column = 0;
|
||||||
data->menu.tab_stop_size =
|
for (;;) {
|
||||||
max( data->menu.tab_stop_size, p - p1 + 1 );
|
TCHAR wbuf[BUFSZ];
|
||||||
p1 = p;
|
RECT drawRect;
|
||||||
p = strchr(p+1, '\t');
|
SetRect ( &drawRect, 0, 0, 1, 1 );
|
||||||
|
if (p != NULL) *p = '\0'; /* for time being, view tab field as zstring */
|
||||||
|
DrawText(hDC,
|
||||||
|
NH_A2W(p1, wbuf, BUFSZ),
|
||||||
|
strlen(p1),
|
||||||
|
&drawRect,
|
||||||
|
DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_EXPANDTABS | DT_SINGLELINE
|
||||||
|
);
|
||||||
|
data->menu.tab_stop_size[column] =
|
||||||
|
max( data->menu.tab_stop_size[column], drawRect.right - drawRect.left );
|
||||||
|
if (p != NULL) *p = '\t';
|
||||||
|
else /* last string so, */ break;
|
||||||
|
|
||||||
|
++column;
|
||||||
|
p1 = p + 1;
|
||||||
|
p = strchr(p1, '\t');
|
||||||
}
|
}
|
||||||
|
SelectObject(hDC, saveFont);
|
||||||
|
ReleaseDC(hWnd, hDC);
|
||||||
|
|
||||||
/* increment size */
|
/* increment size */
|
||||||
data->menu.size++;
|
data->menu.size++;
|
||||||
@@ -757,10 +784,10 @@ BOOL onMeasureItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
BOOL onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
BOOL onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LPDRAWITEMSTRUCT lpdis;
|
LPDRAWITEMSTRUCT lpdis;
|
||||||
PNHMenuItem item;
|
PNHMenuItem item;
|
||||||
PNHMenuWindow data;
|
PNHMenuWindow data;
|
||||||
TEXTMETRIC tm;
|
TEXTMETRIC tm;
|
||||||
HGDIOBJ saveFont;
|
HGDIOBJ saveFont;
|
||||||
HDC tileDC;
|
HDC tileDC;
|
||||||
short ntile;
|
short ntile;
|
||||||
@@ -770,6 +797,8 @@ BOOL onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
RECT drawRect;
|
RECT drawRect;
|
||||||
DRAWTEXTPARAMS dtp;
|
DRAWTEXTPARAMS dtp;
|
||||||
COLORREF OldBg, OldFg, NewBg;
|
COLORREF OldBg, OldFg, NewBg;
|
||||||
|
char *p, *p1;
|
||||||
|
int column;
|
||||||
|
|
||||||
lpdis = (LPDRAWITEMSTRUCT) lParam;
|
lpdis = (LPDRAWITEMSTRUCT) lParam;
|
||||||
|
|
||||||
@@ -844,18 +873,30 @@ BOOL onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|||||||
x += TILE_X + 5;
|
x += TILE_X + 5;
|
||||||
|
|
||||||
/* draw item text */
|
/* draw item text */
|
||||||
SetRect( &drawRect, x, lpdis->rcItem.top, lpdis->rcItem.right, lpdis->rcItem.bottom );
|
|
||||||
|
|
||||||
ZeroMemory(&dtp, sizeof(dtp));
|
p1 = item->str;
|
||||||
dtp.cbSize = sizeof(dtp);
|
p = strchr(item->str, '\t');
|
||||||
dtp.iTabLength = max(MIN_TABSTOP_SIZE, data->menu.tab_stop_size);
|
column = 0;
|
||||||
DrawTextEx(lpdis->hDC,
|
SetRect( &drawRect, x, lpdis->rcItem.top, min(x + data->menu.tab_stop_size[0], lpdis->rcItem.right),
|
||||||
NH_A2W(item->str, wbuf, BUFSZ),
|
lpdis->rcItem.bottom );
|
||||||
strlen(item->str),
|
for (;;) {
|
||||||
&drawRect,
|
TCHAR wbuf[BUFSZ];
|
||||||
DT_LEFT | DT_VCENTER | DT_EXPANDTABS | DT_SINGLELINE | DT_TABSTOP,
|
if (p != NULL) *p = '\0'; /* for time being, view tab field as zstring */
|
||||||
&dtp
|
DrawText(lpdis->hDC,
|
||||||
);
|
NH_A2W(p1, wbuf, BUFSZ),
|
||||||
|
strlen(p1),
|
||||||
|
&drawRect,
|
||||||
|
DT_LEFT | DT_VCENTER | DT_SINGLELINE
|
||||||
|
);
|
||||||
|
if (p != NULL) *p = '\t';
|
||||||
|
else /* last string so, */ break;
|
||||||
|
|
||||||
|
p1 = p + 1;
|
||||||
|
p = strchr(p1, '\t');
|
||||||
|
drawRect.left = drawRect.right + TAB_SEPARATION;
|
||||||
|
++column;
|
||||||
|
drawRect.right = min (drawRect.left + data->menu.tab_stop_size[column], lpdis->rcItem.right);
|
||||||
|
}
|
||||||
|
|
||||||
/* draw focused item */
|
/* draw focused item */
|
||||||
if( item->has_focus ) {
|
if( item->has_focus ) {
|
||||||
@@ -1247,21 +1288,41 @@ void mswin_menu_window_size (HWND hWnd, LPSIZE sz)
|
|||||||
for(i=0; i<data->menu.size; i++ ) {
|
for(i=0; i<data->menu.size; i++ ) {
|
||||||
DRAWTEXTPARAMS dtp;
|
DRAWTEXTPARAMS dtp;
|
||||||
RECT drawRect;
|
RECT drawRect;
|
||||||
|
LONG menuitemwidth = 0;
|
||||||
|
int column;
|
||||||
|
char *p, *p1;
|
||||||
|
|
||||||
SetRect(&drawRect, 0, 0, 1, 1);
|
p1 = data->menu.items[i].str;
|
||||||
ZeroMemory(&dtp, sizeof(dtp));
|
p = strchr(data->menu.items[i].str, '\t');
|
||||||
dtp.cbSize = sizeof(dtp);
|
column = 0;
|
||||||
dtp.iTabLength = max(MIN_TABSTOP_SIZE, data->menu.tab_stop_size);
|
for (;;) {
|
||||||
DrawTextEx(hdc,
|
TCHAR wbuf[BUFSZ];
|
||||||
NH_A2W(data->menu.items[i].str, wbuf, BUFSZ),
|
RECT tabRect;
|
||||||
strlen(data->menu.items[i].str),
|
SetRect ( &tabRect, 0, 0, 1, 1 );
|
||||||
&drawRect,
|
if (p != NULL) *p = '\0'; /* for time being, view tab field as zstring */
|
||||||
DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_EXPANDTABS | DT_SINGLELINE | DT_TABSTOP,
|
DrawText(hdc,
|
||||||
&dtp
|
NH_A2W(p1, wbuf, BUFSZ),
|
||||||
);
|
strlen(p1),
|
||||||
|
&tabRect,
|
||||||
|
DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_SINGLELINE
|
||||||
|
);
|
||||||
|
/* it probably isn't necessary to recompute the tab width now, but do so
|
||||||
|
* just in case, honoring the previously computed value
|
||||||
|
*/
|
||||||
|
menuitemwidth += max(data->menu.tab_stop_size[column],
|
||||||
|
tabRect.right - tabRect.left);
|
||||||
|
if (p != NULL) *p = '\t';
|
||||||
|
else /* last string so, */ break;
|
||||||
|
/* add the separation only when not the last item */
|
||||||
|
/* in the last item, we break out of the loop, in the statement just above */
|
||||||
|
menuitemwidth += TAB_SEPARATION;
|
||||||
|
++column;
|
||||||
|
p1 = p + 1;
|
||||||
|
p = strchr(p1, '\t');
|
||||||
|
}
|
||||||
|
|
||||||
sz->cx = max(sz->cx,
|
sz->cx = max(sz->cx,
|
||||||
(LONG)(2*TILE_X + (drawRect.right - drawRect.left) + tm.tmAveCharWidth*12 + tm.tmOverhang));
|
(LONG)(2*TILE_X + menuitemwidth + tm.tmAveCharWidth*12 + tm.tmOverhang));
|
||||||
}
|
}
|
||||||
SelectObject(hdc, saveFont);
|
SelectObject(hdc, saveFont);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user