dhewm3/neo/tools/materialeditor/ToggleListView.cpp
Daniel Gibson c3d480afe4 Rename GetWindowScalingFactor() to Win_GetW.., support older Win versions
Minimum required Windows version is XP again (instead of Win10).
Win_GetWindowScalingFactor() tries to use two dynamically loaded functions
from newer windows versions (8.1+, Win10 1607+) and has a fallback for
older versions that also seems to work (at least if all displays have
the same DPI).

Moved the function to win_main.cpp so the dynamically loaded functions
can be loaded at startup; so edit_gui_common.cpp could be removed again.
2021-05-10 03:18:24 +02:00

303 lines
8.9 KiB
C++

/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
Doom 3 Source Code 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 3 of the License, or
(at your option) any later version.
Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "tools/edit_gui_common.h"
#include "ToggleListView.h"
#define TOGGLELIST_ITEMHEIGHT 22
#define TEXT_OFFSET 6
IMPLEMENT_DYNCREATE(ToggleListView, CListView)
BEGIN_MESSAGE_MAP(ToggleListView, CListView)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_MEASUREITEM_REFLECT()
ON_NOTIFY_REFLECT(NM_CLICK, OnNMClick)
END_MESSAGE_MAP()
/**
* Protected constructor used by dynamic creation.
*/
ToggleListView::ToggleListView() {
onIcon = NULL;
offIcon = NULL;
disabledIcon = NULL;
}
/**
* Destructor.
*/
ToggleListView::~ToggleListView() {
}
/**
* Sets the tree icons to dispay for each of the three states. Sets the
* icons to display for each of the three states. The values passed in
* are the resource name that can be generated using MAKEINTRESOUCE. If
* the value passed in is NULL then an icon will not be drawn for that
* state.
* @param disabled The icon to draw when the state is TOGGLE_STATE_DISABLED.
* @param on The icon to draw when the state is TOGGLE_STATE_ON.
* @param off The icon to draw when the state is TOGGLE_STATE_OFF.
*/
void ToggleListView::SetToggleIcons(LPCSTR disabled, LPCSTR on, LPCSTR off) {
if(on) {
onIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), on, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
} else {
onIcon = NULL;
}
if(off) {
offIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), off, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
} else {
offIcon = NULL;
}
if(disabled) {
disabledIcon = (HICON)LoadImage ( AfxGetInstanceHandle(), disabled, IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR|LR_LOADMAP3DCOLORS );
} else {
disabledIcon = NULL;
}
}
/**
* Sets the state of an item in the list.
* @param index Index of the item whose state should be changed.
* @param toggleState The state to set
* @param notify Determines if the notification method OnStateChanged should
* be called. OnStateChanged will also not be called if the state has not changed.
*/
void ToggleListView::SetToggleState(int index, int toggleState, bool notify) {
CListCtrl& list = GetListCtrl();
assert(index >= 0 && index < list.GetItemCount());
int oldState = GetToggleState(index);
list.SetItemData(index, toggleState);
if(notify && oldState != toggleState)
OnStateChanged(index, toggleState);
}
/**
* Gets the state of an item in the list
* @param index Index of the item of which to retreive the state.
*/
int ToggleListView::GetToggleState(int index) {
CListCtrl& list = GetListCtrl();
assert(index >= 0 && index < list.GetItemCount());
DWORD data = list.GetItemData(index);
return data;
}
/**
* Called as the window is being created and initializes icons and window styles
*/
int ToggleListView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CListView::OnCreate(lpCreateStruct) == -1)
return -1;
CListCtrl& list = GetListCtrl();
list.SetExtendedStyle(LVS_EX_FULLROWSELECT);
//Turn off the horizontal scroll bar
//Todo: Figure out why the damn scroll bar pops up
list.ModifyStyle(WS_HSCROLL, 0L);
//Insert the one column
LVCOLUMN col;
col.mask = 0;
list.InsertColumn(0, &col);
SetToggleIcons();
return 0;
}
/**
* Called when the window is being resized.
*/
void ToggleListView::OnSize(UINT nType, int cx, int cy) {
CListView::OnSize(nType, cx, cy);
CListCtrl& list = GetListCtrl();
list.SetColumnWidth(0, cx-1);
}
/**
* Returns the size of each item in the toggle list.
*/
void ToggleListView::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
float scaling_factor = Win_GetWindowScalingFactor(GetSafeHwnd());
lpMeasureItemStruct->itemHeight = TOGGLELIST_ITEMHEIGHT * scaling_factor;
}
/**
* Toggles the state of an item when the user clicks in the window.
*/
void ToggleListView::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult) {
CListCtrl& list = GetListCtrl();
DWORD dwpos = GetMessagePos();
LVHITTESTINFO info;
info.pt.x = LOWORD(dwpos);
info.pt.y = HIWORD(dwpos);
::MapWindowPoints(HWND_DESKTOP, pNMHDR->hwndFrom, &info.pt, 1);
int index = list.HitTest(&info);
if ( index != -1 ) {
int toggleState = GetToggleState(index);
if(toggleState != TOGGLE_STATE_DISABLED) {
RECT rItem;
list.GetItemRect(index, &rItem, LVIR_BOUNDS);
if ( info.pt.x < TOGGLELIST_ITEMHEIGHT ) {
if(toggleState == TOGGLE_STATE_ON) {
SetToggleState(index, TOGGLE_STATE_OFF, true);
} else {
SetToggleState(index, TOGGLE_STATE_ON, true);
}
}
}
}
*pResult = 0;
}
/**
* Sets some window styles before the window is created.
*/
BOOL ToggleListView::PreCreateWindow(CREATESTRUCT& cs) {
//Set the required style for the toggle view
cs.style &= ~LVS_TYPEMASK;
cs.style |= LVS_REPORT | LVS_OWNERDRAWFIXED | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS;
return CListView::PreCreateWindow(cs);
}
/**
* Responsible for drawing each list item.
*/
void ToggleListView::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
CListCtrl& ListCtrl=GetListCtrl();
int nItem = lpDrawItemStruct->itemID;
// get item data
LV_ITEM lvi;
_TCHAR szBuff[MAX_PATH];
memset(&lvi, 0, sizeof(LV_ITEM));
lvi.mask = LVIF_TEXT;
lvi.iItem = nItem;
lvi.pszText = szBuff;
lvi.cchTextMax = sizeof(szBuff);
ListCtrl.GetItem(&lvi);
RECT rDraw;
CopyRect ( &rDraw, &lpDrawItemStruct->rcItem );
rDraw.right = rDraw.left + TOGGLELIST_ITEMHEIGHT;
rDraw.top ++;
rDraw.right ++;
FrameRect ( lpDrawItemStruct->hDC, &rDraw, (HBRUSH)GetStockObject ( BLACK_BRUSH ) );
rDraw.right --;
FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DFACE ) );
Draw3dRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DHILIGHT ), GetSysColorBrush ( COLOR_3DSHADOW ) );
InflateRect ( &rDraw, -3, -3 );
Draw3dRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_3DSHADOW ), GetSysColorBrush ( COLOR_3DHILIGHT ) );
switch(GetToggleState(lvi.iItem)) {
case TOGGLE_STATE_DISABLED:
if(disabledIcon) {
DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, disabledIcon, 16, 16,0, NULL, DI_NORMAL );
}
break;
case TOGGLE_STATE_ON:
if(onIcon) {
DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, onIcon, 16, 16,0, NULL, DI_NORMAL );
}
break;
case TOGGLE_STATE_OFF:
if(offIcon) {
DrawIconEx ( lpDrawItemStruct->hDC, rDraw.left, rDraw.top, offIcon, 16, 16,0, NULL, DI_NORMAL );
}
break;
};
CopyRect ( &rDraw, &lpDrawItemStruct->rcItem );
rDraw.left += TOGGLELIST_ITEMHEIGHT;
rDraw.left += 1;
if ( lpDrawItemStruct->itemState & ODS_SELECTED ) {
FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_HIGHLIGHT ) );
} else {
FillRect ( lpDrawItemStruct->hDC, &rDraw, GetSysColorBrush ( COLOR_WINDOW ) );
}
rDraw.left += TEXT_OFFSET;
int colorIndex = ( (lpDrawItemStruct->itemState & ODS_SELECTED ) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT );
SetTextColor ( lpDrawItemStruct->hDC, GetSysColor ( colorIndex ) );
DrawText ( lpDrawItemStruct->hDC, szBuff, strlen(szBuff), &rDraw, DT_LEFT|DT_VCENTER|DT_SINGLELINE );
}
/**
* Draws a 3d rectangle using the given brushes this code was taken from the gui editor
*/
void ToggleListView::Draw3dRect (HDC hDC, RECT* rect, HBRUSH topLeft, HBRUSH bottomRight) {
RECT rOut;
SetRect ( &rOut, rect->left, rect->top, rect->right - 1, rect->top + 1 );
FillRect ( hDC,&rOut, topLeft );
SetRect ( &rOut, rect->left, rect->top, rect->left + 1, rect->bottom );
FillRect( hDC,&rOut, topLeft );
SetRect ( &rOut, rect->right, rect->top, rect->right -1, rect->bottom );
FillRect( hDC,&rOut, bottomRight );
SetRect ( &rOut, rect->left, rect->bottom, rect->right, rect->bottom - 1 );
FillRect( hDC,&rOut, bottomRight );
}