diff -r 903a71d761f4 lib/irrlicht/include/IEventReceiver.h --- a/lib/irrlicht/include/IEventReceiver.h Sun Aug 31 21:11:22 2008 +0200 +++ b/lib/irrlicht/include/IEventReceiver.h Sun Aug 31 23:11:14 2008 +0200 @@ -199,7 +199,13 @@ //! mouse wheel delta, usually 1.0 or -1.0. /** Only valid if event was EMIE_MOUSE_WHEEL */ - f32 Wheel; + f32 Wheel; + + //! true if shift was also pressed + bool Shift; + + //! true if ctrl was also pressed + bool Control; //! Type of mouse event EMOUSE_INPUT_EVENT Event; diff -r 903a71d761f4 lib/irrlicht/include/IGUIListBox.h --- a/lib/irrlicht/include/IGUIListBox.h Sun Aug 31 21:11:22 2008 +0200 +++ b/lib/irrlicht/include/IGUIListBox.h Sun Aug 31 23:11:14 2008 +0200 @@ -28,7 +28,28 @@ EGUI_LBC_ICON_HIGHLIGHT, //! Not used, just counts the number of available colors EGUI_LBC_COUNT - }; + }; + + enum EGUI_LISTBOX_SELECTION + { + //! no lines can be selected + EGUI_LBS_NOT_SELECTABLE, + + //! only single lines can be selected (this is default) + EGUI_LBS_SINGLE_SELECTION, + + //! multiple lines can be selected + EGUI_LBS_MULTI_SELECTION + }; + + //! Names for selection modes + const c8* const GUIListBoxSelectionNames[] = + { + "notSelectable", + "singleSelection", + "multiSelection", + 0 + }; //! Default list box GUI element. @@ -112,7 +133,37 @@ virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon) = 0; //! Swap the items at the given indices - virtual void swapItems(u32 index1, u32 index2) = 0; + virtual void swapItems(u32 index1, u32 index2) = 0; + + //! Set the current selection mode for the listbox lines + virtual void setSelectionMode(EGUI_LISTBOX_SELECTION selection) = 0; + + //! Get the current selection mode for the listbox lines + virtual EGUI_LISTBOX_SELECTION getSelectionMode() const = 0; + + //! Get the number of items which are currently selected + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual u32 getMultiSelectedItemCount() const = 0; + + //! Get the id of the next item with set selection flag + //! returns the first item with selection flag when id=-1 + //! return -1 when no item was found + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual s32 getNextMultiSelectedItem(s32 id=-1) const = 0; + + //! Set the selection flag for the item with given id + //! Usually that will be done automatically when the users clicks. + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual void setItemMultiSelection(u32 id, bool selected) = 0; + + //! Get the selection flag for the item with given id + //! return true when the item is selected, otherwise returns false + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual bool getItemMultiSelection(u32 id) const = 0; + + //! Clear the selection flags for all items + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual void clearAllItemMultiSelections() = 0; }; diff -r 903a71d761f4 lib/irrlicht/source/Irrlicht/CGUIListBox.cpp --- a/lib/irrlicht/source/Irrlicht/CGUIListBox.cpp Sun Aug 31 21:11:22 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CGUIListBox.cpp Sun Aug 31 23:11:14 2008 +0200 @@ -27,7 +27,8 @@ TotalItemHeight(0), ItemsIconWidth(0), Font(0), IconBank(0), ScrollBar(0), Selecting(false), DrawBack(drawBack), MoveOverSelect(moveOverSelect), selectTime(0), AutoScroll(true), - KeyBuffer(), LastKeyTime(0), HighlightWhenNotFocused(true) + KeyBuffer(), LastKeyTime(0), HighlightWhenNotFocused(true) + , SelectionMode(EGUI_LBS_SINGLE_SELECTION) { #ifdef _DEBUG setDebugName("CGUIListBox"); @@ -200,7 +201,8 @@ switch(event.EventType) { case EET_KEY_INPUT_EVENT: - if (event.KeyInput.PressedDown && + if (SelectionMode == EGUI_LBS_SINGLE_SELECTION && + event.KeyInput.PressedDown && (event.KeyInput.Key == KEY_DOWN || event.KeyInput.Key == KEY_UP || event.KeyInput.Key == KEY_HOME || @@ -268,7 +270,8 @@ } return true; } - else if (event.KeyInput.PressedDown && event.KeyInput.Char) + else if (SelectionMode == EGUI_LBS_SINGLE_SELECTION && + event.KeyInput.PressedDown && event.KeyInput.Char) { // change selection based on text as it is typed. u32 now = os::Timer::getTime(); @@ -384,17 +387,17 @@ Selecting = false; if (isPointInside(p)) - selectNew(event.MouseInput.Y); + selectNew(event.MouseInput.Y, false, event.MouseInput.Shift, event.MouseInput.Control ); return true; - } - + } + case EMIE_MOUSE_MOVED: - if (Selecting || MoveOverSelect) + if ( Selecting || (MoveOverSelect && SelectionMode == EGUI_LBS_SINGLE_SELECTION) ) { if (isPointInside(p)) { - selectNew(event.MouseInput.Y, true); + selectNew(event.MouseInput.Y, true, event.MouseInput.Shift, event.MouseInput.Control ); return true; } } @@ -413,14 +416,47 @@ } -void CGUIListBox::selectNew(s32 ypos, bool onlyHover) -{ +void CGUIListBox::selectNew(s32 ypos, bool onlyHover, bool shift, bool ctrl) +{ + if ( SelectionMode == EGUI_LBS_NOT_SELECTABLE ) + return; u32 now = os::Timer::getTime(); s32 oldSelected = Selected; // find new selected item. if (ItemHeight!=0) - Selected = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight; + Selected = ((ypos - AbsoluteRect.UpperLeftCorner.Y - 1) + ScrollBar->getPos()) / ItemHeight; + + // set the multiselection flag. The other stuff like active selected can just be ignored. + if ( EGUI_LBS_MULTI_SELECTION == SelectionMode + && Selected < (s32)Items.size() + ) + { + if ( shift ) + { + clearAllItemMultiSelections(); + s32 start = core::min_(Selected, oldSelected); + if ( start < 0 ) + start = 0; + s32 end = core::max_(Selected, oldSelected); + if ( end >= (s32)Items.size() ) + end = Items.size()-1; + for ( s32 i=start; i <= end; ++i ) + { + Items[i].IsMultiSelected = true; + } + Selected = oldSelected; // Selection does not change when shift is pressed + } + else if ( ctrl ) + { + Items[Selected].IsMultiSelected = Items[Selected].IsMultiSelected ? false : true; + } + else + { + clearAllItemMultiSelections(); + Items[Selected].IsMultiSelected = true; + } + } if (Selected<0) Selected = 0; @@ -437,7 +473,7 @@ event.EventType = EET_GUI_EVENT; event.GUIEvent.Caller = this; event.GUIEvent.Element = 0; - event.GUIEvent.EventType = (Selected == oldSelected && now < selectTime + 500) ? EGET_LISTBOX_SELECTED_AGAIN : EGET_LISTBOX_CHANGED; + event.GUIEvent.EventType = (Selected != oldSelected) || (EGUI_LBS_MULTI_SELECTION == SelectionMode) ? EGET_LISTBOX_CHANGED : EGET_LISTBOX_SELECTED_AGAIN; Parent->OnEvent(event); } selectTime = now; @@ -489,69 +525,64 @@ if (ScrollBar->isVisible()) frameRect.LowerRightCorner.X = AbsoluteRect.LowerRightCorner.X - skin->getSize(EGDS_SCROLLBAR_SIZE); - frameRect.LowerRightCorner.Y = AbsoluteRect.UpperLeftCorner.Y + ItemHeight; - frameRect.UpperLeftCorner.Y -= ScrollBar->getPos(); - frameRect.LowerRightCorner.Y -= ScrollBar->getPos(); bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); for (s32 i=0; i<(s32)Items.size(); ++i) - { + { + bool highlightSelected = (SelectionMode != EGUI_LBS_MULTI_SELECTION && i == Selected && hl) + || (SelectionMode == EGUI_LBS_MULTI_SELECTION && Items[i].IsMultiSelected ); + + frameRect.LowerRightCorner.Y = frameRect.UpperLeftCorner.Y + ItemHeight; + if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) { - if (i == Selected && hl) + if ( highlightSelected ) skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip); core::rect textRect = frameRect; textRect.UpperLeftCorner.X += 3; - if (Font) - { - if (IconBank && (Items[i].icon > -1)) - { - core::position2di iconPos = textRect.UpperLeftCorner; - iconPos.Y += textRect.getHeight() / 2; - iconPos.X += ItemsIconWidth/2; - - if ( i==Selected && hl ) - { - IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, - hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? - getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), - selectTime, os::Timer::getTime(), false, true); - } - else - { - IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, - hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), - 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); - } - } - + if (IconBank && (Items[i].icon > -1)) + { + core::position2di iconPos = textRect.UpperLeftCorner; + iconPos.Y += textRect.getHeight() / 2; + iconPos.X += ItemsIconWidth/2; + + if ( highlightSelected ) + { + IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) ? + getItemOverrideColor(i, EGUI_LBC_ICON_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_ICON_HIGHLIGHT), + selectTime, os::Timer::getTime(), false, true); + } + else + { + IconBank->draw2DSprite( (u32)Items[i].icon, iconPos, &clientClip, + hasItemOverrideColor(i, EGUI_LBC_ICON) ? getItemOverrideColor(i, EGUI_LBC_ICON) : getItemDefaultColor(EGUI_LBC_ICON), + 0 , (i==Selected) ? os::Timer::getTime() : 0, false, true); + } + } + + if (Font) + { textRect.UpperLeftCorner.X += ItemsIconWidth+3; - - if ( i==Selected && hl ) - { - Font->draw(Items[i].text.c_str(), textRect, - hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? - getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT), - false, true, &clientClip); - } - else - { - Font->draw(Items[i].text.c_str(), textRect, - hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT), - false, true, &clientClip); - } + + video::SColor textCol; + if ( highlightSelected ) + textCol = hasItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) ? getItemOverrideColor(i, EGUI_LBC_TEXT_HIGHLIGHT) : getItemDefaultColor(EGUI_LBC_TEXT_HIGHLIGHT); + else + textCol = hasItemOverrideColor(i, EGUI_LBC_TEXT) ? getItemOverrideColor(i, EGUI_LBC_TEXT) : getItemDefaultColor(EGUI_LBC_TEXT); + + Font->draw(Items[i].text.c_str(), textRect, textCol, false, true, &clientClip); textRect.UpperLeftCorner.X -= ItemsIconWidth+3; } } - frameRect.UpperLeftCorner.Y += ItemHeight; - frameRect.LowerRightCorner.Y += ItemHeight; + frameRect.UpperLeftCorner.Y = frameRect.LowerRightCorner.Y; } IGUIElement::draw(); @@ -651,7 +682,8 @@ // todo: out->addString ("IconBank", IconBank->getName?); out->addBool ("DrawBack", DrawBack); out->addBool ("MoveOverSelect", MoveOverSelect); - out->addBool ("AutoScroll", AutoScroll); + out->addBool ("AutoScroll", AutoScroll); + out->addEnum ("SelectionMode", SelectionMode, GUIListBoxSelectionNames ); out->addInt("ItemCount", Items.size()); for (u32 i=0;igetAttributeAsBool("DrawBack"); MoveOverSelect = in->getAttributeAsBool("MoveOverSelect"); - AutoScroll = in->getAttributeAsBool("AutoScroll"); + AutoScroll = in->getAttributeAsBool("AutoScroll"); + SelectionMode = (EGUI_LISTBOX_SELECTION) in->getAttributeAsEnumeration("SelectionMode", GUIListBoxSelectionNames ); IGUIListBox::deserializeAttributes(in,options); @@ -853,6 +886,72 @@ return video::SColor(); } } + +void CGUIListBox::setSelectionMode(EGUI_LISTBOX_SELECTION selection) +{ + SelectionMode = selection; + if ( SelectionMode != EGUI_LBS_SINGLE_SELECTION ) + setSelected(-1); +} + +EGUI_LISTBOX_SELECTION CGUIListBox::getSelectionMode() const +{ + return SelectionMode; +} + +//! Get the number of items which are currently selected +//! This works only in EGUI_LBS_MULTI_SELECTION mode +u32 CGUIListBox::getMultiSelectedItemCount() const +{ + u32 count = 0; + for ( u32 i = 0; i < Items.size(); ++i ) + if ( Items[i].IsMultiSelected ) + ++count; + + return count; +} + +//! Get the id of the next item with set selection flag +//! returns the first item with selection flag when id=-1 +//! return -1 when no item was found +//! This works only in EGUI_LBS_MULTI_SELECTION mode +s32 CGUIListBox::getNextMultiSelectedItem(s32 id) const +{ + for ( s32 i = id+1; i < (s32)Items.size(); ++i ) + if ( Items[i].IsMultiSelected ) + return i; + + return -1; +} + +//! Set the selection flag for the item with given id +//! Usually that will be done automatically when the users clicks. +//! This works only in EGUI_LBS_MULTI_SELECTION mode +void CGUIListBox::setItemMultiSelection(u32 id, bool selected) +{ + if ( id >= Items.size() ) + return; + + Items[id].IsMultiSelected = selected; +} + +//! Get the selection flag for the item with given id +//! This works only in EGUI_LBS_MULTI_SELECTION mode +bool CGUIListBox::getItemMultiSelection(u32 id) const +{ + if ( id >= Items.size() ) + return false; + + return Items[id].IsMultiSelected; +} + +//! Clear the selection flags for all items +//! This works only in EGUI_LBS_MULTI_SELECTION mode +void CGUIListBox::clearAllItemMultiSelections() +{ + for ( u32 i = 0; i < Items.size(); ++i ) + Items[i].IsMultiSelected = false; +} } // end namespace gui diff -r 903a71d761f4 lib/irrlicht/source/Irrlicht/CGUIListBox.h --- a/lib/irrlicht/source/Irrlicht/CGUIListBox.h Sun Aug 31 21:11:22 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CGUIListBox.h Sun Aug 31 23:11:14 2008 +0200 @@ -117,17 +117,48 @@ virtual s32 insertItem(u32 index, const wchar_t* text, s32 icon); //! Swap the items at the given indices - virtual void swapItems(u32 index1, u32 index2); + virtual void swapItems(u32 index1, u32 index2); + + //! Set the current selection mode for the listbox lines + virtual void setSelectionMode(EGUI_LISTBOX_SELECTION selection); + + //! Get the current selection mode for the listbox lines + virtual EGUI_LISTBOX_SELECTION getSelectionMode() const; + + //! Get the number of items which are currently selected + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual u32 getMultiSelectedItemCount() const; + + //! Get the id of the next item with set selection flag + //! returns the first item with selection flag when id=-1 + //! return -1 when no item was found + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual s32 getNextMultiSelectedItem(s32 id=-1) const; + + //! Set the selection flag for the item with given id + //! Usually that will be done automatically when the users clicks. + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual void setItemMultiSelection(u32 id, bool selected); + + //! Get the selection flag for the item with given id + //! return true when the item is selected, otherwise returns false + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual bool getItemMultiSelection(u32 id) const; + + //! Clear the selection flags for all items + //! This works only in EGUI_LBS_MULTI_SELECTION mode + virtual void clearAllItemMultiSelections(); private: struct ListItem - { - ListItem() : icon(-1) + { + ListItem() : icon(-1), IsMultiSelected(false) {} core::stringw text; - s32 icon; + s32 icon; + bool IsMultiSelected; // A multicolor extension struct ListItemOverrideColor @@ -140,7 +171,7 @@ }; void recalculateItemHeight(); - void selectNew(s32 ypos, bool onlyHover=false); + void selectNew(s32 ypos, bool onlyHover=false, bool shift=false, bool ctrl=false); void recalculateScrollPos(); // extracted that function to avoid copy&paste code @@ -164,7 +195,8 @@ bool AutoScroll; core::stringw KeyBuffer; u32 LastKeyTime; - bool HighlightWhenNotFocused; + bool HighlightWhenNotFocused; + EGUI_LISTBOX_SELECTION SelectionMode; }; diff -r 903a71d761f4 lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp Sun Aug 31 21:11:22 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp Sun Aug 31 23:11:14 2008 +0200 @@ -742,7 +742,9 @@ irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; irrevent.MouseInput.Event = irr::EMIE_MOUSE_MOVED; irrevent.MouseInput.X = event.xbutton.x; - irrevent.MouseInput.Y = event.xbutton.y; + irrevent.MouseInput.Y = event.xbutton.y; + irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0; + irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0; postEventFromUser(irrevent); break; @@ -752,7 +754,9 @@ irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT; irrevent.MouseInput.X = event.xbutton.x; - irrevent.MouseInput.Y = event.xbutton.y; + irrevent.MouseInput.Y = event.xbutton.y; + irrevent.MouseInput.Control = (event.xkey.state & ControlMask) != 0; + irrevent.MouseInput.Shift = (event.xkey.state & ShiftMask) != 0; irrevent.MouseInput.Event = irr::EMIE_COUNT; diff -r 903a71d761f4 lib/irrlicht/source/Irrlicht/CIrrDeviceWin32.cpp --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceWin32.cpp Sun Aug 31 21:11:22 2008 +0200 +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceWin32.cpp Sun Aug 31 23:11:14 2008 +0200 @@ -124,7 +124,9 @@ p.x = 0; p.y = 0; ClientToScreen(hWnd, &p); event.MouseInput.X = LOWORD(lParam) - p.x; - event.MouseInput.Y = HIWORD(lParam) - p.y; + event.MouseInput.Y = HIWORD(lParam) - p.y; + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) @@ -137,7 +139,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) dev->postEventFromUser(event); @@ -153,7 +157,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_LMOUSE_LEFT_UP; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) dev->postEventFromUser(event); @@ -165,7 +171,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_RMOUSE_PRESSED_DOWN; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) dev->postEventFromUser(event); @@ -181,7 +189,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_RMOUSE_LEFT_UP; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) dev->postEventFromUser(event); @@ -193,7 +203,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_MMOUSE_PRESSED_DOWN; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) dev->postEventFromUser(event); @@ -209,7 +221,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_MMOUSE_LEFT_UP; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev) dev->postEventFromUser(event); @@ -219,7 +233,9 @@ event.EventType = irr::EET_MOUSE_INPUT_EVENT; event.MouseInput.Event = irr::EMIE_MOUSE_MOVED; event.MouseInput.X = (short)LOWORD(lParam); - event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Y = (short)HIWORD(lParam); + event.MouseInput.Shift = LOWORD(wParam) & MK_SHIFT; + event.MouseInput.Control = LOWORD(wParam) & MK_CONTROL; dev = getDeviceFromHWnd(hWnd); if (dev)