From 7504dc12380ea906194d4360b064b91b3c0f87bc Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 29 Sep 2014 20:29:04 +0200 Subject: [PATCH] From now on dragged widgets will be re-aligned on drop. They will find the nearest hotspot of the group they are dropped into, and calculate an offset so they will align to the hotspot and yet remain where they were dropped. --- code/nel/include/nel/gui/interface_element.h | 9 ++ code/nel/src/gui/interface_element.cpp | 91 ++++++++++++++++++++ code/nel/src/gui/widget_manager.cpp | 3 +- 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/code/nel/include/nel/gui/interface_element.h b/code/nel/include/nel/gui/interface_element.h index 048ec4b6e..3b095ac85 100644 --- a/code/nel/include/nel/gui/interface_element.h +++ b/code/nel/include/nel/gui/interface_element.h @@ -518,6 +518,15 @@ namespace NLGUI _YReal += y; } + /// Retrieves the coordinates of the specified hotspot + void getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const; + + /// Tells which hotspot is the closest to the specified element + void getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ); + + /// Aligns the element to the other element specified + void alignTo( CInterfaceElement *other ); + protected: bool editorSelected; diff --git a/code/nel/src/gui/interface_element.cpp b/code/nel/src/gui/interface_element.cpp index 981d93a9b..75fee53f2 100644 --- a/code/nel/src/gui/interface_element.cpp +++ b/code/nel/src/gui/interface_element.cpp @@ -1594,6 +1594,97 @@ namespace NLGUI } } + void CInterfaceElement::getHSCoords( const THotSpot &hs, sint32 &x, sint32 &y ) const + { + x = _XReal; + y = _YReal; + + if( ( hs & Hotspot_Mx ) != 0 ) + y += _HReal / 2; + else + if( ( hs & Hotspot_Tx ) != 0 ) + y += _HReal; + + + if( ( hs & Hotspot_xM ) != 0 ) + x += _WReal / 2; + else + if( ( hs & Hotspot_xR ) != 0 ) + x += _WReal; + } + + void CInterfaceElement::getClosestHotSpot( const CInterfaceElement *other, THotSpot &hs ) + { + /// Iterate over the following hotspots, calculate the distance and store the closest + + + static THotSpot hslist[] = + { + Hotspot_BL, + Hotspot_BR, + Hotspot_MM, + Hotspot_TL, + Hotspot_TR + }; + + int c = sizeof( hslist ) / sizeof( THotSpot ); + + int x,y,ox,oy,vx,vy; + float d; + float closestd = 9999999.0f; + THotSpot closestHS = Hotspot_TR; + + for( int i = 0; i < c; i++ ) + { + other->getHSCoords( hslist[ i ], ox, oy ); + getHSCoords( hslist[ i ], x, y ); + + // Make a vector between the two hotspots + vx = x - ox; + vy = y - oy; + + // Calculate length + d = sqrt( pow( vx, 2.0f ) + pow( vy, 2.0f ) ); + + // If these hotspots are the closest, store the hotspot + if( d < closestd ) + { + closestd = d; + closestHS = hslist[ i ]; + } + } + + hs = closestHS; + } + + void CInterfaceElement::alignTo( CInterfaceElement *other ) + { + if( other == this ) + return; + + // Check which hotspot is the closest + THotSpot hs; + other->getClosestHotSpot( this, hs ); + + // Get the hotspot coordinates + sint32 x, y, ox, oy; + getHSCoords( hs, x, y ); + other->getHSCoords( hs, ox, oy ); + + // Calculate the difference between the hotspot we found and our current position, + sint32 dx = ox - x; + sint32 dy = oy - y; + + // This difference is our offset, so we remain in the same position + setX( -1 * dx ); + setY( -1 * dy ); + + setPosRef( hs ); + setParentPosRef( hs ); + + invalidateCoords(); + } + CStringMapper* CStringShared::_UIStringMapper = NULL; diff --git a/code/nel/src/gui/widget_manager.cpp b/code/nel/src/gui/widget_manager.cpp index 65c3e101e..ec22798fb 100644 --- a/code/nel/src/gui/widget_manager.cpp +++ b/code/nel/src/gui/widget_manager.cpp @@ -2683,7 +2683,8 @@ namespace NLGUI e->setParentSize( g ); g->addElement( e ); - e->setName( "==MARKED==" ); + e->alignTo( g ); + //e->setName( "==MARKED==" ); draggedElement = NULL;