This commit is contained in:
Matt Raykowski 2010-07-14 12:13:37 -05:00
commit 7577118db5
17 changed files with 332 additions and 99 deletions

View file

@ -186,6 +186,9 @@ public:
/// Set the title of the NeL window
virtual void setWindowTitle(const ucstring &title)=0;
/// Set icon(s) of the NeL window
virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)=0;
/// Set the position of the NeL window
virtual void setWindowPos(sint32 x, sint32 y)=0;

View file

@ -148,6 +148,9 @@ public:
/// Set the title of the NeL window
virtual void setWindowTitle(const ucstring &title);
/// Set icon(s) of the NeL window
virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps);
/// Set the position of the NeL window
virtual void setWindowPos(sint32 x, sint32 y);

View file

@ -34,7 +34,7 @@ namespace NL3D {
template <>
const char *CPSAttribMaker<NLMISC::CRGBA>::getType() { return "CRGBA"; }
inline const char *CPSAttribMaker<NLMISC::CRGBA>::getType() { return "CRGBA"; }
// Depending on the driver, the format of colors in vertex buffer may change. We don't want to change the format for each data that is (dynamically) in vertex buffer, so

View file

@ -28,7 +28,7 @@
namespace NL3D {
template <>
const char *CPSAttribMaker<float>::getType() { return "float"; }
inline const char *CPSAttribMaker<float>::getType() { return "float"; }
/// these are some attribute makers for float
/// This is a float blender class. It just blend between 2 values

View file

@ -26,7 +26,7 @@
namespace NL3D {
template <>
const char *CPSAttribMaker<uint32>::getType() { return "int32"; }
inline const char *CPSAttribMaker<uint32>::getType() { return "int32"; }
/// these are some attribute makers for int

View file

@ -28,7 +28,7 @@
namespace NL3D {
template <>
const char *CPSAttribMaker<CPlaneBasis>::getType() { return "CPlaneBasis";}
inline const char *CPSAttribMaker<CPlaneBasis>::getType() { return "CPlaneBasis";}
/** these are some attribute makers for plane_basis
* This is a plane basis class. It just blend between 2 plane by linearly interpolating the normal

View file

@ -186,6 +186,9 @@ public:
/// Set the title of the NeL window
virtual void setWindowTitle(const ucstring &title)=0;
/// Set icon(s) of the NeL window
virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)=0;
/// Set the position of the NeL window
virtual void setWindowPos(sint32 x, sint32 y)=0;

View file

@ -621,6 +621,10 @@ public:
void getDibData(uint8*& extractData);
#ifdef NL_OS_WINDOWS
HICON getHICON(sint iconWidth, sint iconHeight, sint iconDepth, const NLMISC::CRGBA &col = NLMISC::CRGBA::White, sint hotSpotX = 0, sint hotSpotY = 0, bool cursor = false) const;
#endif
CBitmap& operator= (const CBitmap& from)
{
if (&from == this)

View file

@ -34,7 +34,7 @@ namespace NL3D
{
// ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x67; // changed window pos from uint32 to sint32
const uint32 IDriver::InterfaceVersion = 0x68; // added setWindowIcon
// ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )

View file

@ -1712,6 +1712,10 @@ bool CDriverD3D::release()
if (_HWnd)
{
// make sure window icons are deleted
std::vector<NLMISC::CBitmap> bitmaps;
setWindowIcon(bitmaps);
if (_DestroyWindow)
DestroyWindow (_HWnd);
_HWnd = NULL;
@ -2177,6 +2181,73 @@ void CDriverD3D::setWindowTitle(const ucstring &title)
SetWindowTextW(_HWnd,(WCHAR*)title.c_str());
}
// ***************************************************************************
void CDriverD3D::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
{
if (!_HWnd)
return;
static HICON winIconBig = NULL;
static HICON winIconSmall = NULL;
if (winIconBig)
{
DestroyIcon(winIconBig);
winIconBig = NULL;
}
if (winIconSmall)
{
DestroyIcon(winIconSmall);
winIconSmall = NULL;
}
sint smallIndex = -1;
uint smallWidth = GetSystemMetrics(SM_CXSMICON);
uint smallHeight = GetSystemMetrics(SM_CYSMICON);
sint bigIndex = -1;
uint bigWidth = GetSystemMetrics(SM_CXICON);
uint bigHeight = GetSystemMetrics(SM_CYICON);
// find icons with the exact size
for(uint i = 0; i < bitmaps.size(); ++i)
{
if (smallIndex == -1 && bitmaps[i].getWidth() == smallWidth && bitmaps[i].getHeight() == smallHeight)
smallIndex = i;
if (bigIndex == -1 && bitmaps[i].getWidth() == bigWidth && bitmaps[i].getHeight() == bigHeight)
bigIndex = i;
}
// find icons with taller size (we will resize them)
for(uint i = 0; i < bitmaps.size(); ++i)
{
if (smallIndex == -1 && bitmaps[i].getWidth() >= smallWidth && bitmaps[i].getHeight() >= smallHeight)
smallIndex = i;
if (bigIndex == -1 && bitmaps[i].getWidth() >= bigWidth && bitmaps[i].getHeight() >= bigHeight)
bigIndex = i;
}
if (smallIndex > -1)
winIconSmall = bitmaps[smallIndex].getHICON(smallWidth, smallHeight, 32);
if (bigIndex > -1)
winIconBig = bitmaps[bigIndex].getHICON(bigWidth, bigHeight, 32);
if (winIconBig)
{
SendMessage(_HWnd, WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)winIconSmall);
SendMessage(_HWnd, WM_SETICON, 1 /* ICON_BIG */, (LPARAM)winIconBig);
}
else
{
SendMessage(_HWnd, WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)winIconSmall);
SendMessage(_HWnd, WM_SETICON, 1 /* ICON_BIG */, (LPARAM)winIconSmall);
}
}
// ***************************************************************************
void CDriverD3D::setWindowPos(sint32 x, sint32 y)
{

View file

@ -759,6 +759,9 @@ public:
/// Set the title of the NeL window
virtual void setWindowTitle(const ucstring &title);
/// Set icon(s) of the NeL window
virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps);
/// Set the position of the NeL window
virtual void setWindowPos(sint32 x, sint32 y);

View file

@ -294,10 +294,13 @@ public:
virtual void beginDialogMode();
virtual void endDialogMode();
/// Set the title of the NeL window
/// Set title of the NeL window
virtual void setWindowTitle(const ucstring &title);
/// Set the position of the NeL window
/// Set icon(s) of the NeL window
virtual void setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps);
/// Set position of the NeL window
virtual void setWindowPos(sint32 x, sint32 y);
/// Show or hide the NeL window

View file

@ -35,11 +35,13 @@
# ifdef XRANDR
# include <X11/extensions/Xrandr.h>
# endif
# include <X11/Xatom.h>
#endif // NL_OS_UNIX
#include "nel/misc/mouse_device.h"
#include "nel/misc/di_event_emitter.h"
#include "nel/3d/u_driver.h"
#include "nel/misc/file.h"
using namespace std;
using namespace NLMISC;
@ -296,6 +298,123 @@ bool CDriverGL::unInit()
return true;
}
void CDriverGL::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
{
if (_win == EmptyWindow)
return;
#if defined(NL_OS_WINDOWS)
static HICON winIconBig = NULL;
static HICON winIconSmall = NULL;
if (winIconBig)
{
DestroyIcon(winIconBig);
winIconBig = NULL;
}
if (winIconSmall)
{
DestroyIcon(winIconSmall);
winIconSmall = NULL;
}
sint smallIndex = -1;
uint smallWidth = GetSystemMetrics(SM_CXSMICON);
uint smallHeight = GetSystemMetrics(SM_CYSMICON);
sint bigIndex = -1;
uint bigWidth = GetSystemMetrics(SM_CXICON);
uint bigHeight = GetSystemMetrics(SM_CYICON);
// find icons with the exact size
for(uint i = 0; i < bitmaps.size(); ++i)
{
if (smallIndex == -1 && bitmaps[i].getWidth() == smallWidth && bitmaps[i].getHeight() == smallHeight)
smallIndex = i;
if (bigIndex == -1 && bitmaps[i].getWidth() == bigWidth && bitmaps[i].getHeight() == bigHeight)
bigIndex = i;
}
// find icons with taller size (we will resize them)
for(uint i = 0; i < bitmaps.size(); ++i)
{
if (smallIndex == -1 && bitmaps[i].getWidth() >= smallWidth && bitmaps[i].getHeight() >= smallHeight)
smallIndex = i;
if (bigIndex == -1 && bitmaps[i].getWidth() >= bigWidth && bitmaps[i].getHeight() >= bigHeight)
bigIndex = i;
}
if (smallIndex > -1)
winIconSmall = bitmaps[smallIndex].getHICON(smallWidth, smallHeight, 32);
if (bigIndex > -1)
winIconBig = bitmaps[bigIndex].getHICON(bigWidth, bigHeight, 32);
if (winIconBig)
{
SendMessage(_win, WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)winIconSmall);
SendMessage(_win, WM_SETICON, 1 /* ICON_BIG */, (LPARAM)winIconBig);
}
else
{
SendMessage(_win, WM_SETICON, 0 /* ICON_SMALL */, (LPARAM)winIconSmall);
SendMessage(_win, WM_SETICON, 1 /* ICON_BIG */, (LPARAM)winIconSmall);
}
#elif defined(NL_OS_MAC)
// nothing to do
#elif defined(NL_OS_UNIX)
std::vector<long> icon_data;
if (!bitmaps.empty())
{
// process each bitmap
for(uint i = 0; i < bitmaps.size(); ++i)
{
// get bitmap width and height
uint width = bitmaps[i].getWidth();
uint height = bitmaps[i].getHeight();
// icon_data position for bitmap
uint pos = (uint)icon_data.size();
// extend icon_data size for bitmap
icon_data.resize(pos + 2 + width*height);
// set bitmap width and height
icon_data[pos++] = width;
icon_data[pos++] = height;
// convert RGBA to ARGB
CObjectVector<uint8> pixels = bitmaps[i].getPixels();
for(uint j = 0; j < pixels.size(); j+=4)
icon_data[pos++] = pixels[j] << 16 | pixels[j+1] << 8 | pixels[j+2] | pixels[j+3] << 24;
}
}
Atom _NET_WM_ICON = XInternAtom(_dpy, "_NET_WM_ICON", False);
if (!icon_data.empty())
{
// change window icon
XChangeProperty(_dpy, _win, _NET_WM_ICON, XA_CARDINAL, 32, PropModeReplace, (const unsigned char *) &icon_data[0], icon_data.size());
}
else
{
// delete window icon if no bitmap is available
XDeleteProperty(_dpy, _win, _NET_WM_ICON);
}
#endif // NL_OS_WINDOWS
}
// --------------------------------------------------
bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool resizeable) throw(EBadDisplay)
{
@ -967,7 +1086,7 @@ bool CDriverGL::setScreenMode(const GfxMode &mode)
if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
nlwarning("Fullscreen mode switch failed");
nlwarning("3D: Fullscreen mode switch failed");
return false;
}
@ -1135,6 +1254,10 @@ bool CDriverGL::destroyWindow()
{
H_AUTO_OGL(CDriverGL_destroyWindow)
// make sure window icons are deleted
std::vector<NLMISC::CBitmap> bitmaps;
setWindowIcon(bitmaps);
#ifdef NL_OS_WINDOWS
// Then delete.

View file

@ -809,49 +809,46 @@ void submitEvents(NLMISC::CEventServer& server,
continue;
}
// convert the modifiers for nel to pass them with the events
NLMISC::TKeyButton modifiers =
modifierFlagsToNelKeyButton([event modifierFlags]);
switch(event.type)
{
case NSLeftMouseDown:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers),
eventEmitter));
}
break;
case NSLeftMouseUp:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers),
eventEmitter));
break;
}
case NSRightMouseDown:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseDown(
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers),
eventEmitter));
break;
}
case NSRightMouseUp:
{
/*
TODO modifiers with mouse events
*/
server.postEvent(new NLMISC::CEventMouseUp(
mouseX, mouseY, NLMISC::rightButton /* modifiers */, eventEmitter));
mouseX, mouseY,
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers),
eventEmitter));
break;
}
case NSMouseMoved:
{
/*
TODO modifiers with mouse events
*/
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
@ -861,17 +858,14 @@ void submitEvents(NLMISC::CEventServer& server,
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
(NLMISC::TMouseButton)0 /* modifiers */, eventEmitter);
nelEvent = new NLMISC::CEventMouseMove(
mouseX, mouseY, (NLMISC::TMouseButton)modifiers, eventEmitter);
server.postEvent(nelEvent);
break;
}
case NSLeftMouseDragged:
{
/*
TODO modifiers with mouse events
*/
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
@ -882,16 +876,14 @@ void submitEvents(NLMISC::CEventServer& server,
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
NLMISC::leftButton /* modifiers */, eventEmitter);
(NLMISC::TMouseButton)(NLMISC::leftButton | modifiers),
eventEmitter);
server.postEvent(nelEvent);
break;
}
case NSRightMouseDragged:
{
/*
TODO modifiers with mouse events
*/
NLMISC::CEvent* nelEvent;
// when emulating raw mode, send the delta in a CGDMouseMove event
@ -902,7 +894,8 @@ void submitEvents(NLMISC::CEventServer& server,
// normally send position in a CEventMouseMove
else
nelEvent = new NLMISC::CEventMouseMove(mouseX, mouseY,
NLMISC::rightButton /* modifiers */, eventEmitter);
(NLMISC::TMouseButton)(NLMISC::rightButton | modifiers),
eventEmitter);
server.postEvent(nelEvent);
break;
@ -951,12 +944,9 @@ void submitEvents(NLMISC::CEventServer& server,
case NSCursorUpdate:break;
case NSScrollWheel:
{
/*
TODO modifiers with mouse events
*/
if(fabs(event.deltaY) > 0.1)
server.postEvent(new NLMISC::CEventMouseWheel(
mouseX, mouseY, (NLMISC::TMouseButton)0 /* modifiers */,
mouseX, mouseY, (NLMISC::TMouseButton)modifiers,
(event.deltaY > 0), eventEmitter));
break;

View file

@ -332,6 +332,13 @@ void CDriverUser::setWindowTitle(const ucstring &title)
_Driver->setWindowTitle(title);
}
// ***************************************************************************
void CDriverUser::setWindowIcon(const std::vector<NLMISC::CBitmap> &bitmaps)
{
NL3D_HAUTO_UI_DRIVER;
_Driver->setWindowIcon(bitmaps);
}
// ***************************************************************************
void CDriverUser::setWindowPos(sint32 x, sint32 y)
{

View file

@ -1500,7 +1500,7 @@ uint32 CBitmap::getHeight(uint32 mipMap) const
/*-------------------------------------------------------------------*\
getHeight
getSize
\*-------------------------------------------------------------------*/
uint32 CBitmap::getSize(uint32 numMipMap) const
{
@ -4107,5 +4107,84 @@ void CBitmap::getDibData(uint8*& extractData)
}
#ifdef NL_OS_WINDOWS
HICON CBitmap::getHICON(sint iconWidth, sint iconHeight, sint iconDepth, const NLMISC::CRGBA &col, sint hotSpotX, sint hotSpotY, bool cursor) const
{
HICON result = NULL;
CBitmap src = *this;
// resample bitmap if necessary
if (_Width != iconWidth || _Height != iconHeight)
{
src.resample(iconWidth, iconHeight);
}
CBitmap colorBm;
colorBm.resize(iconWidth, iconHeight, CBitmap::RGBA);
const CRGBA *srcColorPtr = (CRGBA *) &(src.getPixels()[0]);
const CRGBA *srcColorPtrLast = srcColorPtr + (iconWidth * iconHeight);
CRGBA *destColorPtr = (CRGBA *) &(colorBm.getPixels()[0]);
static volatile uint8 alphaThreshold = 127;
do
{
destColorPtr->modulateFromColor(*srcColorPtr, col);
std::swap(destColorPtr->R, destColorPtr->B);
++ srcColorPtr;
++ destColorPtr;
}
while (srcColorPtr != srcColorPtrLast);
//
HBITMAP colorHbm = NULL;
HBITMAP maskHbm = NULL;
//
if (iconDepth == 16)
{
std::vector<uint16> colorBm16(iconWidth * iconHeight);
const CRGBA *src32 = (const CRGBA *) &colorBm.getPixels(0)[0];
for (uint k = 0; k < colorBm16.size(); ++k)
{
colorBm16[k] = ((uint16)(src32[k].R&0xf8)>>3) | ((uint16)(src32[k].G&0xfc)<<3) | ((uint16)(src32[k].B & 0xf8)<<8);
}
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 16, &colorBm16[0]);
std::vector<uint8> bitMask((iconWidth * iconHeight + 7) / 8, 0);
for (uint k = 0;k < colorBm16.size(); ++k)
{
if (src32[k].A <= 120)
{
bitMask[k / 8] |= (0x80 >> (k & 7));
}
}
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 1, &bitMask[0]);
}
else
{
colorHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
maskHbm = CreateBitmap(iconWidth, iconHeight, 1, 32, &colorBm.getPixels(0)[0]);
}
ICONINFO iconInfo;
iconInfo.fIcon = cursor ? FALSE:TRUE;
iconInfo.xHotspot = (DWORD) hotSpotX;
iconInfo.yHotspot = (DWORD) hotSpotY;
iconInfo.hbmMask = maskHbm;
iconInfo.hbmColor = colorHbm;
if (colorHbm && maskHbm)
{
result = CreateIconIndirect(&iconInfo);
}
//
if (colorHbm) DeleteObject(colorHbm);
if (maskHbm) DeleteObject(maskHbm);
return result;
}
#endif
} // NLMISC

View file

@ -370,7 +370,6 @@ HICON CCustomMouse::buildCursor(const CBitmap &src, NLMISC::CRGBA col, uint8 rot
uint mouseH = GetSystemMetrics(SM_CYCURSOR);
nlassert(src.getWidth() == mouseW);
nlassert(src.getHeight() == mouseH);
HICON result = 0;
CBitmap rotSrc = src;
if (rot > 3) rot = 3; // mimic behavior of 'CViewRenderer::drawRotFlipBitmapTiled' (why not rot & 3 ??? ...)
switch(rot)
@ -380,62 +379,7 @@ HICON CCustomMouse::buildCursor(const CBitmap &src, NLMISC::CRGBA col, uint8 rot
case 2: rotSrc.rot90CW(); rotSrc.rot90CW(); break;
case 3: rotSrc.rot90CCW(); break;
}
CBitmap colorBm;
colorBm.resize(mouseW, mouseH, CBitmap::RGBA);
const CRGBA *srcColorPtr = (CRGBA *) &(rotSrc.getPixels()[0]);
const CRGBA *srcColorPtrLast = srcColorPtr + (mouseW * mouseH);
CRGBA *destColorPtr = (CRGBA *) &(colorBm.getPixels()[0]);
static volatile uint8 alphaThreshold = 127;
do
{
destColorPtr->modulateFromColor(*srcColorPtr, col);
std::swap(destColorPtr->R, destColorPtr->B);
++ srcColorPtr;
++ destColorPtr;
}
while (srcColorPtr != srcColorPtrLast);
//
HBITMAP colorHbm = 0;
HBITMAP maskHbm = 0;
//
if (_ColorDepth == ColorDepth16)
{
std::vector<uint16> colorBm16(colorBm.getWidth() * colorBm.getHeight());
const CRGBA *src32 = (const CRGBA *) &colorBm.getPixels(0)[0];
for (uint k = 0;k < colorBm16.size(); ++k)
{
colorBm16[k] = ((uint16)(src32[k].R&0xf8)>>3) | ((uint16)(src32[k].G&0xfc)<<3) | ((uint16)(src32[k].B & 0xf8)<<8);
}
colorHbm = CreateBitmap(mouseW, mouseH, 1, 16, &colorBm16[0]);
std::vector<uint8> bitMask((colorBm.getWidth() * colorBm.getHeight() + 7) / 8, 0);
for (uint k = 0;k < colorBm16.size(); ++k)
{
if (src32[k].A <= 120)
{
bitMask[k / 8] |= (0x80 >> (k & 7));
}
}
maskHbm = CreateBitmap(mouseW, mouseH, 1, 1, &bitMask[0]);
}
else
{
colorHbm = CreateBitmap(mouseW, mouseH, 1, 32, &colorBm.getPixels(0)[0]);
maskHbm = CreateBitmap(mouseW, mouseH, 1, 32, &colorBm.getPixels(0)[0]);
}
ICONINFO iconInfo;
iconInfo.fIcon = FALSE;
iconInfo.xHotspot = (DWORD) hotSpotX;
iconInfo.yHotspot = (DWORD) hotSpotY;
iconInfo.hbmMask = maskHbm;
iconInfo.hbmColor = colorHbm;
if (colorHbm && maskHbm)
{
result = CreateIconIndirect(&iconInfo);
}
//
if (colorHbm) DeleteObject(colorHbm);
if (maskHbm) DeleteObject(maskHbm);
return result;
return rotSrc.getHICON(mouseW, mouseH, _ColorDepth == ColorDepth16 ? 16:32, col, hotSpotX, hotSpotY, true);
}