Merge with experimental-ui-scaling
--HG-- branch : develop
This commit is contained in:
commit
8a18a5dade
22 changed files with 505 additions and 187 deletions
|
@ -38,6 +38,16 @@ namespace NLGUI
|
|||
class IActionHandler;
|
||||
class CGroupParagraph;
|
||||
|
||||
/**
|
||||
* Interface for UI scale change event
|
||||
*/
|
||||
class IInterfaceScaleWatcher
|
||||
{
|
||||
public:
|
||||
virtual ~IInterfaceScaleWatcher(){}
|
||||
virtual void onInterfaceScaleChanged()=0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A visitor to walk a tree of interface elements and apply a teartment on them.
|
||||
*
|
||||
|
@ -66,7 +76,7 @@ namespace NLGUI
|
|||
* \author Nevrax France
|
||||
* \date 2002
|
||||
*/
|
||||
class CInterfaceElement : public CReflectableRefPtrTarget, public NLMISC::IStreamable
|
||||
class CInterfaceElement : public IInterfaceScaleWatcher, public CReflectableRefPtrTarget, public NLMISC::IStreamable
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -409,6 +419,10 @@ namespace NLGUI
|
|||
*/
|
||||
virtual void onInvalidateContent() {}
|
||||
|
||||
/* Element UI scale change event callback
|
||||
*/
|
||||
virtual void onInterfaceScaleChanged() {}
|
||||
|
||||
// called by interfaceManager for master window only
|
||||
void resetInvalidCoords();
|
||||
|
||||
|
|
|
@ -176,6 +176,13 @@ namespace NLGUI
|
|||
*/
|
||||
void getScreenOOSize (float &oow, float &ooh);
|
||||
|
||||
/*
|
||||
* UI scaling
|
||||
*/
|
||||
void setInterfaceScale(float scale, sint32 width = 0, sint32 height = 0);
|
||||
float getInterfaceScale() const { return _InterfaceScale; }
|
||||
void setBilinearFiltering(bool b) { _Bilinear = b; }
|
||||
|
||||
/*
|
||||
* is the Screen minimized?
|
||||
*/
|
||||
|
@ -185,7 +192,7 @@ namespace NLGUI
|
|||
* drawBitmap : this is the interface with all the views
|
||||
*
|
||||
*/
|
||||
void drawRotFlipBitmap (sint layerId, sint32 x, sint32 y, sint32 width, sint32 height, uint8 rot, bool flipv,
|
||||
void drawRotFlipBitmap (sint layerId, float x, float y, float width, float height, uint8 rot, bool flipv,
|
||||
sint32 nTxId, const NLMISC::CRGBA &col = NLMISC::CRGBA(255,255,255,255));
|
||||
|
||||
/*
|
||||
|
@ -526,6 +533,14 @@ namespace NLGUI
|
|||
float _OneOverScreenW, _OneOverScreenH;
|
||||
bool _IsMinimized;
|
||||
|
||||
// UI scaling
|
||||
float _InterfaceScale;
|
||||
float _InterfaceUserScale;
|
||||
sint32 _InterfaceBaseW, _InterfaceBaseH;
|
||||
sint32 _EffectiveScreenW, _EffectiveScreenH;
|
||||
bool _Bilinear;
|
||||
|
||||
void updateInterfaceScale();
|
||||
|
||||
//map linking a uint to a bitmap. Used to display figurs
|
||||
std::vector<sint32> _IndexesToTextureIds;
|
||||
|
@ -596,7 +611,6 @@ namespace NLGUI
|
|||
/// Set of hw cursor images
|
||||
static std::set< std::string > *hwCursors;
|
||||
static float hwCursorScale;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ namespace NLGUI
|
|||
virtual void checkCoords();
|
||||
virtual void updateCoords();
|
||||
virtual void onAddToGroup();
|
||||
virtual void onInterfaceScaleChanged();
|
||||
|
||||
/// From CInterfaceElement
|
||||
sint32 getMaxUsedW() const;
|
||||
|
@ -90,6 +91,7 @@ namespace NLGUI
|
|||
void setShadowColor (const NLMISC::CRGBA &color);
|
||||
void setShadowOffset (sint x, sint y);
|
||||
void setLineMaxW (sint nMaxW, bool invalidate=true);
|
||||
void setOverflowText(const ucstring &text) { _OverflowText = text; }
|
||||
void setMultiLine (bool bMultiLine);
|
||||
void setMultiLineSpace (sint nMultiLineSpace);
|
||||
void setMultiLineMaxWOnly (bool state);
|
||||
|
@ -115,6 +117,7 @@ namespace NLGUI
|
|||
NLMISC::CRGBA getShadowColor() { return _ShadowColor; }
|
||||
void getShadowOffset(sint &x, sint &y) { x = _ShadowX; y = _ShadowY; }
|
||||
sint getLineMaxW() const { return _LineMaxW; }
|
||||
ucstring getOverflowText() const { return _OverflowText; }
|
||||
bool getMultiLine() const { return _MultiLine; }
|
||||
sint getMultiLineSpace() const { return _MultiLineSpace; }
|
||||
bool getMultiLineMaxWOnly() const { return _MultiLineMaxWOnly; }
|
||||
|
@ -128,6 +131,8 @@ namespace NLGUI
|
|||
uint getFontHeight() const;
|
||||
// get current font leg height, in pixels
|
||||
uint getFontLegHeight() const;
|
||||
// get current line height, in pixels
|
||||
float getLineHeight() const;
|
||||
// Set the display mode (supported with multiline only for now)
|
||||
void setTextMode(TTextMode mode);
|
||||
TTextMode getTextMode() const { return _TextMode; }
|
||||
|
@ -148,11 +153,11 @@ namespace NLGUI
|
|||
* When looking at standard edit box, we see that if a line is split accross to line with no
|
||||
* This also returns the height of the line
|
||||
*/
|
||||
void getCharacterPositionFromIndex(sint index, bool lineEnd, sint &x, sint &y, sint &height) const;
|
||||
void getCharacterPositionFromIndex(sint index, bool lineEnd, float &x, float &y, float &height) const;
|
||||
/** From a coordinate relative to the BR BR corner of the text, return the index of a character.
|
||||
* If no character is found at the given position, the closest character is returned (first or last character, for the line or the whole text)
|
||||
*/
|
||||
void getCharacterIndexFromPosition(sint x, sint y, uint &index, bool &lineEnd) const;
|
||||
void getCharacterIndexFromPosition(float x, float y, uint &index, bool &lineEnd) const;
|
||||
/** From a character index, get the index of the line it belongs to, or -1 if the index is invalid
|
||||
* \param cursorDisplayedAtEndOfPreviousLine true if the cursor is displayed at the end of the previous line that match its index
|
||||
*/
|
||||
|
@ -238,12 +243,14 @@ namespace NLGUI
|
|||
bool _Embolden;
|
||||
bool _Oblique;
|
||||
// width of the font in pixel. Just a Hint for tabing format (computed with '_')
|
||||
uint _FontWidth;
|
||||
float _FontWidth;
|
||||
// height of the font in pixel.
|
||||
// use getFontHeight
|
||||
uint _FontHeight;
|
||||
uint _FontLegHeight;
|
||||
float _FontHeight;
|
||||
float _FontLegHeight;
|
||||
float _SpaceWidth;
|
||||
/// last UI scale used to calculate font size
|
||||
float _Scale;
|
||||
/// the text color
|
||||
NLMISC::CRGBA _Color;
|
||||
/// the shadow mode
|
||||
|
@ -260,6 +267,7 @@ namespace NLGUI
|
|||
sint32 _LineMaxW;
|
||||
/// For single line, true if the text is clamped (ie displayed with "...")
|
||||
bool _SingleLineTextClamped;
|
||||
ucstring _OverflowText;
|
||||
|
||||
/// Multiple lines handling
|
||||
bool _MultiLine;
|
||||
|
@ -341,8 +349,8 @@ namespace NLGUI
|
|||
// Clear the line & remove text contexts
|
||||
void clear(NL3D::UTextContext &textContext);
|
||||
// Add a new word (and its context) in the line + a number of spaces to append at the end of the line
|
||||
void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, uint fontWidth, NL3D::UTextContext &textContext);
|
||||
void addWord(const CWord &word, uint fontWidth);
|
||||
void addWord(const ucstring &word, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext);
|
||||
void addWord(const CWord &word, float fontWidth);
|
||||
uint getNumWords() const { return (uint)_Words.size(); }
|
||||
CWord &getWord(uint index) { return _Words[index]; }
|
||||
float getSpaceWidth() const { return _SpaceWidth; }
|
||||
|
@ -402,7 +410,7 @@ namespace NLGUI
|
|||
uint _TextSelectionEnd;
|
||||
|
||||
// First line X coordinate
|
||||
sint _FirstLineX;
|
||||
float _FirstLineX;
|
||||
|
||||
/// Dynamic tooltips
|
||||
std::vector<CCtrlToolTip*> _Tooltips;
|
||||
|
|
|
@ -49,6 +49,7 @@ namespace NLGUI
|
|||
class CProcedure;
|
||||
class IEditorSelectionWatcher;
|
||||
class IWidgetAdditionWatcher;
|
||||
class IInterfaceScaleWatcher;
|
||||
|
||||
/**
|
||||
GUI Widget Manager
|
||||
|
@ -530,6 +531,11 @@ namespace NLGUI
|
|||
bool unGroupSelection();
|
||||
void setMultiSelection( bool b ){ multiSelection = b; }
|
||||
|
||||
float getInterfaceScale() const { return _InterfaceScale; }
|
||||
void notifyInterfaceScaleWatchers();
|
||||
void registerInterfaceScaleWatcher(IInterfaceScaleWatcher *watcher);
|
||||
void unregisterInterfaceScaleWatcher(IInterfaceScaleWatcher *watcher);
|
||||
|
||||
bool createNewGUI( const std::string &project, const std::string &window );
|
||||
|
||||
private:
|
||||
|
@ -615,6 +621,7 @@ namespace NLGUI
|
|||
|
||||
uint32 _ScreenH;
|
||||
uint32 _ScreenW;
|
||||
float _InterfaceScale;
|
||||
|
||||
std::vector< CInterfaceAnim* > activeAnims;
|
||||
|
||||
|
@ -622,6 +629,7 @@ namespace NLGUI
|
|||
std::vector< IOnWidgetsDrawnHandler* > onWidgetsDrawnHandlers;
|
||||
std::vector< IEditorSelectionWatcher* > selectionWatchers;
|
||||
std::vector< IWidgetWatcher* > widgetWatchers;
|
||||
std::vector< IInterfaceScaleWatcher* > scaleWatchers;
|
||||
|
||||
std::vector< std::string > editorSelection;
|
||||
bool _GroupSelection;
|
||||
|
|
|
@ -702,9 +702,9 @@ namespace NLGUI
|
|||
sint32 maxPos= max(_CursorPos, _SelectCursorPos) + (sint32)_Prompt.length();
|
||||
|
||||
// get its position on screen
|
||||
sint cxMinPos, cyMinPos;
|
||||
sint cxMaxPos, cyMaxPos;
|
||||
sint height;
|
||||
float cxMinPos, cyMinPos;
|
||||
float cxMaxPos, cyMaxPos;
|
||||
float height;
|
||||
_ViewText->getCharacterPositionFromIndex(minPos, false, cxMinPos, cyMinPos, height);
|
||||
_ViewText->getCharacterPositionFromIndex(maxPos, false, cxMaxPos, cyMaxPos, height);
|
||||
|
||||
|
@ -755,8 +755,8 @@ namespace NLGUI
|
|||
if (_BlinkState) // is the cursor shown ?
|
||||
{
|
||||
// get its position on screen
|
||||
sint cx, cy;
|
||||
sint height;
|
||||
float cx, cy;
|
||||
float height;
|
||||
_ViewText->getCharacterPositionFromIndex(_CursorPos + (sint)_Prompt.length(), _CursorAtPreviousLineEnd, cx, cy, height);
|
||||
// display the cursor
|
||||
// get the texture for the cursor
|
||||
|
@ -1482,7 +1482,7 @@ namespace NLGUI
|
|||
if (_ViewText->getWReal() > _WReal)
|
||||
{
|
||||
// Check if cursor visible
|
||||
sint xCursVT, xCurs, yTmp, hTmp;
|
||||
float xCursVT, xCurs, yTmp, hTmp;
|
||||
// Get the cursor pos from the BL of the viewtext
|
||||
_ViewText->getCharacterPositionFromIndex(_CursorPos+(sint)_Prompt.size(), false, xCursVT, yTmp, hTmp);
|
||||
// Get the cursor pos from the BL of the edit box
|
||||
|
|
|
@ -96,8 +96,23 @@ namespace NLGUI
|
|||
if(w!=0 && h!=0)
|
||||
{
|
||||
_IsMinimized= false;
|
||||
if (w != _ScreenW || h != _ScreenH)
|
||||
{
|
||||
_ScreenW = w;
|
||||
_ScreenH = h;
|
||||
|
||||
updateInterfaceScale();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep old coordinates (suppose resolution won't change, even if typically false wen we swithch from outgame to ingame)
|
||||
_IsMinimized= true;
|
||||
}
|
||||
}
|
||||
|
||||
void CViewRenderer::updateInterfaceScale()
|
||||
{
|
||||
if(_ScreenW>0)
|
||||
_OneOverScreenW = 1.0f / (float)_ScreenW;
|
||||
else
|
||||
|
@ -106,11 +121,27 @@ namespace NLGUI
|
|||
_OneOverScreenH = 1.0f / (float)_ScreenH;
|
||||
else
|
||||
_OneOverScreenH = 1000;
|
||||
|
||||
_InterfaceScale = _InterfaceUserScale;
|
||||
if (_InterfaceBaseW > 0 && _InterfaceBaseH > 0)
|
||||
{
|
||||
float wRatio = (float)_ScreenW / _InterfaceBaseW;
|
||||
float rRatio = (float)_ScreenH / _InterfaceBaseH;
|
||||
_InterfaceScale *= std::min(wRatio, rRatio);
|
||||
}
|
||||
|
||||
if (_InterfaceScale != 1.0f)
|
||||
{
|
||||
_OneOverScreenW *= _InterfaceScale;
|
||||
_OneOverScreenH *= _InterfaceScale;
|
||||
|
||||
_EffectiveScreenW = sint(_ScreenW / _InterfaceScale);
|
||||
_EffectiveScreenH = sint(_ScreenH / _InterfaceScale);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Keep old coordinates (suppose resolution won't change, even if typically false wen we swithch from outgame to ingame)
|
||||
_IsMinimized= true;
|
||||
_EffectiveScreenW = _ScreenW;
|
||||
_EffectiveScreenH = _ScreenH;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,8 +151,8 @@ namespace NLGUI
|
|||
*/
|
||||
void CViewRenderer::getScreenSize (uint32 &w, uint32 &h)
|
||||
{
|
||||
w = _ScreenW;
|
||||
h = _ScreenH;
|
||||
w = _EffectiveScreenW;
|
||||
h = _EffectiveScreenH;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -133,6 +164,20 @@ namespace NLGUI
|
|||
ooh= _OneOverScreenH;
|
||||
}
|
||||
|
||||
void CViewRenderer::setInterfaceScale(float scale, sint32 width/*=0*/, sint32 height/*=0*/)
|
||||
{
|
||||
// prevent #div/0
|
||||
if (sint(scale*100) > 0)
|
||||
_InterfaceUserScale = scale;
|
||||
else
|
||||
_InterfaceUserScale = 1.0f;
|
||||
|
||||
_InterfaceBaseW = width;
|
||||
_InterfaceBaseH = height;
|
||||
|
||||
updateInterfaceScale();
|
||||
}
|
||||
|
||||
void CViewRenderer::setup()
|
||||
{
|
||||
_ClipX = _ClipY = 0;
|
||||
|
@ -140,8 +185,10 @@ namespace NLGUI
|
|||
_ClipH = 600;
|
||||
_ScreenW = 800;
|
||||
_ScreenH = 600;
|
||||
_OneOverScreenW= 1.0f / (float)_ScreenW;
|
||||
_OneOverScreenH= 1.0f / (float)_ScreenH;
|
||||
_InterfaceScale = 1.0f;
|
||||
_InterfaceUserScale = 1.0f;
|
||||
_InterfaceBaseW = 0;
|
||||
_InterfaceBaseH = 0;
|
||||
_IsMinimized= false;
|
||||
_WFigurTexture= 0;
|
||||
_HFigurTexture= 0;
|
||||
|
@ -157,6 +204,9 @@ namespace NLGUI
|
|||
_EmptyLayer[i]= true;
|
||||
}
|
||||
_BlankGlobalTexture = NULL;
|
||||
_Bilinear = false;
|
||||
|
||||
updateInterfaceScale();
|
||||
}
|
||||
|
||||
|
||||
|
@ -499,7 +549,7 @@ namespace NLGUI
|
|||
/*
|
||||
* drawBitmap
|
||||
*/
|
||||
void CViewRenderer::drawRotFlipBitmap (sint layerId, sint32 x, sint32 y, sint32 width, sint32 height,
|
||||
void CViewRenderer::drawRotFlipBitmap (sint layerId, float x, float y, float width, float height,
|
||||
uint8 rot, bool flipv, sint32 nTxId, const CRGBA &col)
|
||||
{
|
||||
if (width <= 0 || height <= 0) return;
|
||||
|
@ -1283,7 +1333,7 @@ namespace NLGUI
|
|||
_Material.setTexture(0, ite->Texture);
|
||||
|
||||
// Special Case if _WorldSpaceTransformation and _WorldSpaceScale, enable bilinear
|
||||
if(_WorldSpaceTransformation && _WorldSpaceScale)
|
||||
if(_Bilinear || (_WorldSpaceTransformation && _WorldSpaceScale))
|
||||
ite->Texture->setFilterMode(UTexture::Linear, UTexture::LinearMipMapOff);
|
||||
|
||||
// draw quads and empty list
|
||||
|
@ -1300,7 +1350,7 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
// Special Case if _WorldSpaceTransformation and _WorldSpaceScale, reset
|
||||
if(_WorldSpaceTransformation && _WorldSpaceScale)
|
||||
if(_Bilinear || (_WorldSpaceTransformation && _WorldSpaceScale))
|
||||
ite->Texture->setFilterMode(UTexture::Nearest, UTexture::NearestMipMapOff);
|
||||
}
|
||||
if (!layer.FilteredAlphaBlendedQuads.empty() ||
|
||||
|
@ -1942,6 +1992,25 @@ namespace NLGUI
|
|||
|
||||
void CViewRenderer::drawText (sint layerId, float x, float y, uint wordIndex, float xmin, float ymin, float xmax, float ymax, UTextContext &textContext)
|
||||
{
|
||||
xmin = xmin * _OneOverScreenW;
|
||||
ymin = ymin * _OneOverScreenH;
|
||||
xmax = xmax * _OneOverScreenW;
|
||||
ymax = ymax * _OneOverScreenH;
|
||||
|
||||
if (_InterfaceScale != 1.0f && _InterfaceScale != 2.0f)
|
||||
{
|
||||
// align to screen pixel
|
||||
x *= _OneOverScreenW * _ScreenW;
|
||||
y *= _OneOverScreenH * _ScreenH;
|
||||
x = floorf(x) * 1.f / (float) _ScreenW;
|
||||
y = floorf(y) * 1.f / (float) _ScreenH;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = floorf(x) * _OneOverScreenW;
|
||||
y = floorf(y) * _OneOverScreenH;
|
||||
}
|
||||
|
||||
if (_WorldSpaceTransformation)
|
||||
{
|
||||
textContext.printClipAtUnProjected(*getStringRenderBuffer(layerId), _CameraFrustum, _WorldSpaceMatrix, x, y, _CurrentZ, wordIndex, xmin, ymin, xmax, ymax);
|
||||
|
|
|
@ -86,6 +86,7 @@ namespace NLGUI
|
|||
_MultiMaxLine = 0;
|
||||
_Index = 0xFFFFFFFF;
|
||||
|
||||
_Scale = CWidgetManager::getInstance()->getInterfaceScale();
|
||||
_FontWidth= 0;
|
||||
_FontHeight = 0;
|
||||
_FontLegHeight = 0;
|
||||
|
@ -104,6 +105,7 @@ namespace NLGUI
|
|||
|
||||
_AutoClamp = false;
|
||||
_ClampRight = true; // clamp on the right of the text
|
||||
_OverflowText = "...";
|
||||
|
||||
_LetterColors = NULL;
|
||||
_Setuped= false;
|
||||
|
@ -118,6 +120,8 @@ namespace NLGUI
|
|||
:CViewBase(param)
|
||||
{
|
||||
setupDefault ();
|
||||
|
||||
CWidgetManager::getInstance()->registerInterfaceScaleWatcher(this);
|
||||
}
|
||||
|
||||
///constructor
|
||||
|
@ -135,11 +139,15 @@ namespace NLGUI
|
|||
_ShadowOutline = ShadowOutline;
|
||||
setText(Text);
|
||||
computeFontSize ();
|
||||
|
||||
CWidgetManager::getInstance()->registerInterfaceScaleWatcher(this);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
CViewText::~CViewText()
|
||||
{
|
||||
CWidgetManager::getInstance()->unregisterInterfaceScaleWatcher(this);
|
||||
|
||||
if (_Index != 0xFFFFFFFF)
|
||||
CViewRenderer::getTextContext(_FontName)->erase (_Index);
|
||||
clearLines();
|
||||
|
@ -912,8 +920,9 @@ namespace NLGUI
|
|||
// ***************************************************************************
|
||||
sint CViewText::getCurrentMultiLineMaxW() const
|
||||
{
|
||||
sint maxw = ceilf(_LineMaxW * _Scale);
|
||||
if(_MultiLineMaxWOnly)
|
||||
return _LineMaxW;
|
||||
return maxw;
|
||||
else
|
||||
{
|
||||
sint offset = (sint)_XReal - (sint)_Parent->getXReal();
|
||||
|
@ -978,6 +987,31 @@ namespace NLGUI
|
|||
|
||||
CViewRenderer &rVR = *CViewRenderer::getInstance();
|
||||
|
||||
#if 0
|
||||
//rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(64,64,64,255));
|
||||
|
||||
// debug text with mouse hover
|
||||
if(CWidgetManager::getInstance()->getPointer())
|
||||
{
|
||||
// but must check first if mouse is over
|
||||
sint32 x = CWidgetManager::getInstance()->getPointer()->getX();
|
||||
sint32 y = CWidgetManager::getInstance()->getPointer()->getY();
|
||||
bool mouseIn;
|
||||
// use parent clip or self clip?
|
||||
if(_OverExtendViewTextUseParentRect)
|
||||
mouseIn= _Parent && _Parent->isIn(x,y);
|
||||
else
|
||||
mouseIn= isIn(x,y);
|
||||
// if the mouse cursor is in the clip area
|
||||
if(mouseIn) {
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255));
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_HReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255));
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255));
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(200,200,200,255));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// *** Out Of Clip?
|
||||
sint32 ClipX, ClipY, ClipW, ClipH;
|
||||
rVR.getClipWindow (ClipX, ClipY, ClipW, ClipH);
|
||||
|
@ -999,12 +1033,8 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
// *** Screen Minimized?
|
||||
uint32 w, h;
|
||||
float oow, ooh;
|
||||
rVR.getScreenSize (w, h);
|
||||
if (rVR.isMinimized())
|
||||
return;
|
||||
rVR.getScreenOOSize (oow, ooh);
|
||||
|
||||
NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName);
|
||||
|
||||
|
@ -1025,6 +1055,8 @@ namespace NLGUI
|
|||
shcol.A = (uint8)(((sint)shcol.A*((sint)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
|
||||
}
|
||||
|
||||
float oow, ooh;
|
||||
rVR.getScreenOOSize (oow, ooh);
|
||||
|
||||
// *** Draw multiline
|
||||
if ((_MultiLine)&&(_Parent != NULL))
|
||||
|
@ -1036,23 +1068,16 @@ namespace NLGUI
|
|||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setShadeColor (shcol);
|
||||
TextContext->setShadeExtent (_ShadowX*oow, _ShadowY*ooh);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
|
||||
float y = (float)(_YReal) * ooh; // y is expressed in scree, coordinates [0..1]
|
||||
//y += _LinesInfos[_LinesInfos.size()-1].StringLine / h;
|
||||
|
||||
// Y is the base line of the string, so it must be grown up.
|
||||
y += (float)_FontLegHeight * ooh;
|
||||
|
||||
sint y_line = _YReal+_FontLegHeight-2;
|
||||
float y = _YReal * _Scale + _FontLegHeight;
|
||||
|
||||
if (_MultiMinLine > _Lines.size())
|
||||
{
|
||||
uint dy = getMultiMinOffsetY();
|
||||
y += dy * ooh;
|
||||
y_line += dy;
|
||||
y += getMultiMinOffsetY() * _Scale;
|
||||
}
|
||||
|
||||
// special selection code
|
||||
|
@ -1093,7 +1118,7 @@ namespace NLGUI
|
|||
{
|
||||
CLine &currLine = *_Lines[i];
|
||||
// current x position
|
||||
float px = (float) (_XReal + ((i==0) ? (sint)_FirstLineX : 0));
|
||||
float px = (float) (_XReal * _Scale + ((i==0) ? (sint)_FirstLineX : 0));
|
||||
// draw each words of the line
|
||||
for(uint k = 0; k < currLine.getNumWords(); ++k)
|
||||
{
|
||||
|
@ -1120,25 +1145,25 @@ namespace NLGUI
|
|||
px += firstSpace;
|
||||
// skip tabulation before current word
|
||||
if(currWord.Format.TabX)
|
||||
px= max(px, (float)(_XReal + currWord.Format.TabX*_FontWidth));
|
||||
px= max(px, (float)(_XReal * _Scale + currWord.Format.TabX*_FontWidth));
|
||||
|
||||
// draw. We take floorf px to avoid filtering of letters that are not located on a pixel boundary
|
||||
rVR.drawText (_RenderLayer, floorf(px) * oow, y, currWord.Index, (float)ClipX * oow, (float)ClipY * ooh,
|
||||
(float)(ClipX+ClipW) * oow, (float)(ClipY+ClipH) * ooh, *TextContext);
|
||||
float fx = px / _Scale;
|
||||
float fy = y / _Scale;
|
||||
rVR.drawText (_RenderLayer, fx, fy, currWord.Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext);
|
||||
|
||||
// Draw a line
|
||||
if (_Underlined)
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line, line_width, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, fx, fy - _FontLegHeight*0.6f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col);
|
||||
|
||||
if (_StrikeThrough)
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, (sint)floorf(px), y_line + (_FontHeight / 2), line_width, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, fx, fy + _FontHeight*0.2f / _Scale, line_width / _Scale, 1.0f / _Scale, 0, false, rVR.getBlankTextureId(), col);
|
||||
|
||||
// skip word
|
||||
px += currWord.Info.StringWidth;
|
||||
}
|
||||
// go one line up
|
||||
y += (_FontHeight + _MultiLineSpace) * ooh;
|
||||
y_line += _FontHeight+_MultiLineSpace;
|
||||
y += (_FontHeight + _MultiLineSpace * _Scale);
|
||||
}
|
||||
|
||||
// reset selection
|
||||
|
@ -1164,22 +1189,17 @@ namespace NLGUI
|
|||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setShadeColor (shcol);
|
||||
TextContext->setShadeExtent (_ShadowX*oow, _ShadowY*ooh);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
|
||||
|
||||
if(_LetterColors!=NULL && !TextContext->isSameLetterColors(_LetterColors, _Index))
|
||||
{
|
||||
TextContext->setLetterColors(_LetterColors, _Index);
|
||||
}
|
||||
|
||||
|
||||
float x = (float)(_XReal) * oow;
|
||||
float y = (float)(_YReal) * ooh;
|
||||
|
||||
// Y is the base line of the string, so it must be grown up.
|
||||
y += (float)_FontLegHeight * ooh;
|
||||
float y = _YReal * _Scale + _FontLegHeight;
|
||||
|
||||
// special selection code
|
||||
if(_TextSelection)
|
||||
|
@ -1190,15 +1210,14 @@ namespace NLGUI
|
|||
TextContext->setStringColor(_Index, col);
|
||||
|
||||
// draw
|
||||
rVR.drawText (_RenderLayer, x, y, _Index, (float)ClipX * oow, (float)ClipY * ooh,
|
||||
(float)(ClipX+ClipW) * oow, (float)(ClipY+ClipH) * ooh, *TextContext);
|
||||
rVR.drawText (_RenderLayer, _XReal, y / _Scale, _Index, ClipX, ClipY, ClipX+ClipW, ClipY+ClipH, *TextContext);
|
||||
|
||||
// Draw a line
|
||||
if (_Underlined)
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_FontLegHeight-2, _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal - _FontLegHeight*0.3f/_Scale, _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||
|
||||
if (_StrikeThrough)
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+(_FontLegHeight/2), _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||
rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal + _FontHeight*0.2f / _Scale, _WReal, 1, 0, false, rVR.getBlankTextureId(), col);
|
||||
|
||||
// reset selection
|
||||
if(_TextSelection)
|
||||
|
@ -1247,7 +1266,6 @@ namespace NLGUI
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -1409,7 +1427,7 @@ namespace NLGUI
|
|||
sint32 value;
|
||||
if(CLuaIHM::popSINT32(ls, value))
|
||||
{
|
||||
setLineMaxW(value);
|
||||
setLineMaxW(ceilf(value / _Scale));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1445,19 +1463,25 @@ namespace NLGUI
|
|||
// ***************************************************************************
|
||||
uint CViewText::getFontWidth() const
|
||||
{
|
||||
return _FontWidth;
|
||||
return _FontWidth / _Scale;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
uint CViewText::getFontHeight() const
|
||||
{
|
||||
return _FontHeight;
|
||||
return _FontHeight / _Scale;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
uint CViewText::getFontLegHeight() const
|
||||
{
|
||||
return _FontLegHeight;
|
||||
return _FontLegHeight / _Scale;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
float CViewText::getLineHeight() const
|
||||
{
|
||||
return _FontHeight / _Scale + _MultiLineSpace;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -1468,7 +1492,7 @@ namespace NLGUI
|
|||
{
|
||||
// first line is always present even if _Lines is empty
|
||||
uint nbLines = _MultiMinLine - std::max((sint)1, (sint)_Lines.size());
|
||||
dy = nbLines * _FontHeight + (nbLines - 1) * _MultiLineSpace;
|
||||
dy = (nbLines * _FontHeight + (nbLines - 1) * _MultiLineSpace * _Scale) / _Scale;
|
||||
}
|
||||
return dy;
|
||||
}
|
||||
|
@ -1500,11 +1524,12 @@ namespace NLGUI
|
|||
ucstring ucCurrentWord;
|
||||
CFormatInfo wordFormat;
|
||||
// line state
|
||||
float rWidthCurrentLine = 0, rWidthLetter;
|
||||
float rWidthCurrentLine = 0;
|
||||
bool linePushed= false;
|
||||
// for all the text
|
||||
uint textSize= (uint)_Text.size();
|
||||
uint formatTagIndex= 0;
|
||||
nMaxWidth *= _Scale;
|
||||
for (i = 0; i < textSize; ++i)
|
||||
{
|
||||
if(isFormatTagChange(i, formatTagIndex))
|
||||
|
@ -1537,21 +1562,20 @@ namespace NLGUI
|
|||
ucstring ucStrLetter;
|
||||
ucStrLetter= ucLetter;
|
||||
si = TextContext->getStringInfo (ucStrLetter);
|
||||
rWidthLetter = (si.StringWidth);
|
||||
if ((rWidthCurrentLine + rWidthLetter) > nMaxWidth)
|
||||
if ((rWidthCurrentLine + si.StringWidth) > nMaxWidth)
|
||||
{
|
||||
flushWordInLine(ucCurrentWord, linePushed, wordFormat);
|
||||
|
||||
// reset line state, and begin with the cut letter
|
||||
linePushed= false;
|
||||
rWidthCurrentLine = rWidthLetter;
|
||||
rWidthCurrentLine = si.StringWidth;
|
||||
ucCurrentWord = ucLetter;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grow the current word
|
||||
ucCurrentWord += ucLetter;
|
||||
rWidthCurrentLine += rWidthLetter;
|
||||
rWidthCurrentLine += si.StringWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1625,12 +1649,13 @@ namespace NLGUI
|
|||
CFormatInfo wordFormat;
|
||||
uint formatTagIndex= 0;
|
||||
//
|
||||
nMaxWidth *= _Scale;
|
||||
while (currPos != _Text.length())
|
||||
{
|
||||
TCharPos spaceEnd;
|
||||
TCharPos wordEnd;
|
||||
uint numSpaces;
|
||||
float newLineWidth;
|
||||
float newLineWidth = 0;
|
||||
breakLine = false;
|
||||
//
|
||||
if (_Text[currPos] == (ucchar) '\n')
|
||||
|
@ -1903,7 +1928,7 @@ namespace NLGUI
|
|||
TextContext->setHotSpot (UTextContext::BottomLeft);
|
||||
TextContext->setShaded (_Shadow);
|
||||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
|
||||
|
@ -1912,7 +1937,7 @@ namespace NLGUI
|
|||
|
||||
if ((_MultiLine)&&(_Parent != NULL))
|
||||
{
|
||||
sint nMaxWidth = getCurrentMultiLineMaxW();
|
||||
float nMaxWidth = getCurrentMultiLineMaxW();
|
||||
_LastMultiLineMaxW = nMaxWidth;
|
||||
clearLines();
|
||||
if (nMaxWidth <= 0)
|
||||
|
@ -1935,26 +1960,30 @@ namespace NLGUI
|
|||
_Lines.back()->clear(*TextContext);
|
||||
_Lines.pop_back();
|
||||
}
|
||||
if (_OverflowText.size() > 0)
|
||||
{
|
||||
_Lines.pop_back();
|
||||
CViewText::CLine *endLine = new CViewText::CLine;
|
||||
CViewText::CWord w;
|
||||
w.build(string("..."), *TextContext);
|
||||
w.build(_OverflowText, *TextContext);
|
||||
endLine->addWord(w, _FontWidth);
|
||||
_Lines.push_back(TLineSPtr(endLine));
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate size
|
||||
float rMultiLineSpace = _MultiLineSpace * _Scale;
|
||||
float rTotalW = 0;
|
||||
for (uint i = 0; i < _Lines.size(); ++i)
|
||||
{
|
||||
rTotalW = std::max(_Lines[i]->getWidth() + ((i==0)?_FirstLineX:0), rTotalW);
|
||||
}
|
||||
_W = (sint)rTotalW;
|
||||
_H = std::max(_FontHeight, uint(_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * _MultiLineSpace));
|
||||
_W = (sint)ceilf(rTotalW / _Scale);
|
||||
_H = std::max(_FontHeight / _Scale, ceilf((_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * rMultiLineSpace) / _Scale));
|
||||
|
||||
// See if we should pretend to have at least X lines
|
||||
if (_MultiMinLine > 1)
|
||||
_H = std::max(_H, sint(_FontHeight * _MultiMinLine + (_MultiMinLine - 1) * _MultiLineSpace));
|
||||
_H = std::max(_H, sint((_FontHeight * _MultiMinLine + (_MultiMinLine - 1) * rMultiLineSpace)/_Scale));
|
||||
|
||||
// Compute tooltips size
|
||||
if (!_Tooltips.empty())
|
||||
|
@ -1963,7 +1992,6 @@ namespace NLGUI
|
|||
for (uint j=0 ; j<_Lines[i]->getNumWords() ; ++j)
|
||||
{
|
||||
CWord word = _Lines[i]->getWord(j);
|
||||
// float w = _Lines[i]->getWidth();
|
||||
|
||||
if (word.Format.IndexTt != -1)
|
||||
{
|
||||
|
@ -1971,7 +1999,7 @@ namespace NLGUI
|
|||
{
|
||||
CCtrlToolTip *pTooltip = _Tooltips[word.Format.IndexTt];
|
||||
|
||||
sint y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - i - 1));
|
||||
sint y = (sint) ceilf(((_FontHeight + rMultiLineSpace) * (_Lines.size() - i - 1))/_Scale);
|
||||
|
||||
pTooltip->setX(0);
|
||||
pTooltip->setY(y);
|
||||
|
@ -1990,10 +2018,10 @@ namespace NLGUI
|
|||
// Common case: no W clamp
|
||||
_Index = TextContext->textPush (_Text);
|
||||
_Info = TextContext->getStringInfo (_Index);
|
||||
_W = (sint)(_Info.StringWidth);
|
||||
_W = (sint)ceilf(_Info.StringWidth / _Scale);
|
||||
|
||||
// Rare case: clamp W => recompute slowly, cut letters
|
||||
if(_W>_LineMaxW)
|
||||
if(_Info.StringWidth > _LineMaxW)
|
||||
{
|
||||
TextContext->erase (_Index);
|
||||
|
||||
|
@ -2001,10 +2029,16 @@ namespace NLGUI
|
|||
UTextContext::CStringInfo si;
|
||||
ucstring ucCurrentLine;
|
||||
ucCurrentLine.reserve(_Text.size());
|
||||
|
||||
// Append ... to the end of line
|
||||
si = TextContext->getStringInfo (ucstring("..."));
|
||||
float dotWidth= si.StringWidth;
|
||||
float rWidthCurrentLine = 0, rWidthLetter;
|
||||
float dotWidth = 0.f;
|
||||
if (_OverflowText.size() > 0)
|
||||
{
|
||||
si = TextContext->getStringInfo (ucstring(_OverflowText));
|
||||
dotWidth = si.StringWidth;
|
||||
}
|
||||
|
||||
float rWidthCurrentLine = 0;
|
||||
// for all the text
|
||||
if (_ClampRight)
|
||||
{
|
||||
|
@ -2014,8 +2048,7 @@ namespace NLGUI
|
|||
ucstring ucStrLetter;
|
||||
ucStrLetter= ucLetter;
|
||||
si = TextContext->getStringInfo (ucStrLetter);
|
||||
rWidthLetter = (si.StringWidth);
|
||||
if ((rWidthCurrentLine + rWidthLetter + dotWidth) > _LineMaxW)
|
||||
if ((rWidthCurrentLine + si.StringWidth + dotWidth) > _LineMaxW)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -2023,12 +2056,15 @@ namespace NLGUI
|
|||
{
|
||||
// Grow the current line
|
||||
ucCurrentLine += ucLetter;
|
||||
rWidthCurrentLine += rWidthLetter;
|
||||
rWidthCurrentLine += si.StringWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the dots
|
||||
ucCurrentLine+= "...";
|
||||
if (_OverflowText.size() > 0)
|
||||
{
|
||||
ucCurrentLine += _OverflowText;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2038,8 +2074,7 @@ namespace NLGUI
|
|||
ucstring ucStrLetter;
|
||||
ucStrLetter= ucLetter;
|
||||
si = TextContext->getStringInfo (ucStrLetter);
|
||||
rWidthLetter = (si.StringWidth);
|
||||
if ((rWidthCurrentLine + rWidthLetter + dotWidth) > _LineMaxW)
|
||||
if ((rWidthCurrentLine + si.StringWidth + dotWidth) > _LineMaxW)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -2047,24 +2082,27 @@ namespace NLGUI
|
|||
{
|
||||
// Grow the current line
|
||||
ucCurrentLine = ucLetter + ucCurrentLine;
|
||||
rWidthCurrentLine += rWidthLetter;
|
||||
rWidthCurrentLine += si.StringWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Add the dots
|
||||
ucCurrentLine = "..." + ucCurrentLine;
|
||||
if (_OverflowText.size() > 0)
|
||||
{
|
||||
ucCurrentLine = _OverflowText + ucCurrentLine;
|
||||
}
|
||||
}
|
||||
|
||||
// And so setup this trunc text
|
||||
_Index = TextContext->textPush (ucCurrentLine);
|
||||
_Info = TextContext->getStringInfo (_Index);
|
||||
_W = (sint)(_Info.StringWidth);
|
||||
_W = (sint)ceilf(_Info.StringWidth / _Scale);
|
||||
|
||||
_SingleLineTextClamped= true;
|
||||
}
|
||||
|
||||
// same height always
|
||||
_H = _FontHeight;
|
||||
_H = (sint)ceilf(_FontHeight / _Scale);
|
||||
}
|
||||
|
||||
_InvalidTextContext= false;
|
||||
|
@ -2223,28 +2261,29 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::getCharacterPositionFromIndex(sint index, bool cursorAtPreviousLineEnd, sint &x, sint &y, sint &height) const
|
||||
void CViewText::getCharacterPositionFromIndex(sint index, bool cursorAtPreviousLineEnd, float &x, float &y, float &height) const
|
||||
{
|
||||
NLMISC::clamp(index, 0, (sint) _Text.length());
|
||||
NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName);
|
||||
TextContext->setHotSpot (UTextContext::BottomLeft);
|
||||
TextContext->setShaded (_Shadow);
|
||||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
// CViewRenderer &rVR = *CViewRenderer::getInstance();
|
||||
height = getFontHeight();
|
||||
height = getLineHeight();
|
||||
//
|
||||
if (_MultiLine)
|
||||
{
|
||||
uint dy = getMultiMinOffsetY();
|
||||
float fx, fy;
|
||||
float dy = getMultiMinOffsetY() * _Scale;
|
||||
float nMaxWidth = getCurrentMultiLineMaxW() * _Scale;
|
||||
|
||||
uint charIndex = 0;
|
||||
// special case for end of text
|
||||
if (index == (sint) _Text.length())
|
||||
{
|
||||
y = dy;
|
||||
fy = dy;
|
||||
if (_Lines.empty())
|
||||
{
|
||||
x = 0;
|
||||
|
@ -2252,10 +2291,12 @@ namespace NLGUI
|
|||
else
|
||||
{
|
||||
CLine &lastLine = *_Lines.back();
|
||||
x = (sint) (lastLine.getWidth() + lastLine.getEndSpaces() * lastLine.getSpaceWidth());
|
||||
sint nMaxWidth = getCurrentMultiLineMaxW();
|
||||
x = std::min(x, nMaxWidth);
|
||||
fx = lastLine.getWidth() + lastLine.getEndSpaces() * lastLine.getSpaceWidth();
|
||||
fx = std::min(fx, nMaxWidth);
|
||||
}
|
||||
|
||||
x = fx / _Scale;
|
||||
y = fy / _Scale;
|
||||
return;
|
||||
}
|
||||
for(sint i = 0; i < (sint) _Lines.size(); ++i)
|
||||
|
@ -2264,10 +2305,12 @@ namespace NLGUI
|
|||
{
|
||||
// should display the character at the end of previous line
|
||||
CLine &currLine = *_Lines[i - 1];
|
||||
y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - i) + dy);
|
||||
x = (sint) (currLine.getWidth() + currLine.getEndSpaces() * currLine.getSpaceWidth());
|
||||
sint nMaxWidth = getCurrentMultiLineMaxW();
|
||||
x = std::min(x, nMaxWidth);
|
||||
fy = (_FontHeight + _MultiLineSpace * _Scale) * (_Lines.size() - i) + dy;
|
||||
fx = currLine.getWidth() + currLine.getEndSpaces() * currLine.getSpaceWidth();
|
||||
fx = std::min(fx, nMaxWidth);
|
||||
|
||||
x = fx / _Scale;
|
||||
y = fy / _Scale;
|
||||
return;
|
||||
}
|
||||
CLine &currLine = *_Lines[i];
|
||||
|
@ -2275,14 +2318,16 @@ namespace NLGUI
|
|||
if ((sint) newCharIndex > index)
|
||||
{
|
||||
// ok, this line contains the character, now, see which word contains it.
|
||||
y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - 1 - i) + dy);
|
||||
fy = (_FontHeight + _MultiLineSpace * _Scale) * (_Lines.size() - 1 - i) + dy;
|
||||
// see if the index is in the spaces at the end of line
|
||||
if (index - charIndex >= currLine.getNumChars())
|
||||
{
|
||||
uint numSpaces = index - charIndex - currLine.getNumChars();
|
||||
x = (sint) (currLine.getWidth() + numSpaces * _SpaceWidth);
|
||||
sint nMaxWidth = getCurrentMultiLineMaxW();
|
||||
x = std::min(x, nMaxWidth);
|
||||
fx = currLine.getWidth() + numSpaces * _SpaceWidth;
|
||||
fx = std::min(fx, nMaxWidth);
|
||||
|
||||
x = fx / _Scale;
|
||||
y = fy / _Scale;
|
||||
return;
|
||||
}
|
||||
// now, search containing word in current line
|
||||
|
@ -2300,15 +2345,19 @@ namespace NLGUI
|
|||
ucstring subStr = currWord.Text.substr(0, index - charIndex - currWord.NumSpaces);
|
||||
// compute the size
|
||||
UTextContext::CStringInfo si = TextContext->getStringInfo(subStr);
|
||||
x = (sint) (px + si.StringWidth + currWord.NumSpaces * currLine.getSpaceWidth());
|
||||
height = getFontHeight();
|
||||
fx = px + si.StringWidth + currWord.NumSpaces * currLine.getSpaceWidth();
|
||||
|
||||
x = fx / _Scale;
|
||||
y = fy / _Scale;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// character is in the spaces preceding the word
|
||||
x = (sint) (px + currLine.getSpaceWidth() * (index - charIndex));
|
||||
height = getFontHeight();
|
||||
fx = px + currLine.getSpaceWidth() * (index - charIndex);
|
||||
|
||||
x = fx / _Scale;
|
||||
y = fy / _Scale;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2327,15 +2376,16 @@ namespace NLGUI
|
|||
// compute the size
|
||||
UTextContext::CStringInfo si = TextContext->getStringInfo(subStr);
|
||||
y = 0;
|
||||
x = (sint) si.StringWidth;
|
||||
x = (sint) ceilf(si.StringWidth / _Scale);
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// Tool fct : From a word and a x coordinate, give the matching character index
|
||||
// Tool fct : From a word and a x coordinate (font scale), give the matching character index
|
||||
static uint getCharacterIndex(const ucstring &textValue, float x, NL3D::UTextContext &textContext)
|
||||
{
|
||||
float px = 0.f;
|
||||
|
||||
UTextContext::CStringInfo si;
|
||||
ucstring singleChar(" ");
|
||||
uint i;
|
||||
|
@ -2349,7 +2399,7 @@ namespace NLGUI
|
|||
if (px > x)
|
||||
{
|
||||
// if the half of the character is after the cursor, then prefer select the next one (like in Word)
|
||||
if(px-si.StringWidth/2 < x)
|
||||
if(px-si.StringWidth/2.f < x)
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
|
@ -2358,15 +2408,18 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::getCharacterIndexFromPosition(sint x, sint y, uint &index, bool &cursorAtPreviousLineEnd) const
|
||||
void CViewText::getCharacterIndexFromPosition(float x, float y, uint &index, bool &cursorAtPreviousLineEnd) const
|
||||
{
|
||||
NL3D::UTextContext *TextContext = CViewRenderer::getTextContext(_FontName);
|
||||
|
||||
x *= _Scale;
|
||||
y = roundf(y * _Scale);
|
||||
|
||||
// setup the text context
|
||||
TextContext->setHotSpot (UTextContext::BottomLeft);
|
||||
TextContext->setShaded (_Shadow);
|
||||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
// find the line where the character is
|
||||
|
@ -2374,7 +2427,7 @@ namespace NLGUI
|
|||
uint charPos = 0;
|
||||
if (_MultiLine)
|
||||
{
|
||||
y -= getMultiMinOffsetY();
|
||||
y -= getMultiMinOffsetY() * _Scale;
|
||||
// seek the line
|
||||
float py = 0.f;
|
||||
if (py > y)
|
||||
|
@ -2386,7 +2439,7 @@ namespace NLGUI
|
|||
sint line;
|
||||
for (line = (uint)_Lines.size() - 1; line >= 0; --line)
|
||||
{
|
||||
float newPy = py + _FontHeight + _MultiLineSpace;
|
||||
float newPy = py + _FontHeight + _MultiLineSpace * _Scale;
|
||||
if (newPy > y)
|
||||
{
|
||||
break;
|
||||
|
@ -2419,6 +2472,7 @@ namespace NLGUI
|
|||
return;
|
||||
}
|
||||
|
||||
cursorAtPreviousLineEnd = false;
|
||||
float px = (float)_FirstLineX;
|
||||
for(uint k = 0; k < currLine.getNumWords(); ++k)
|
||||
{
|
||||
|
@ -2435,14 +2489,12 @@ namespace NLGUI
|
|||
: 0;
|
||||
clamp(numSpaces, 0, (sint)currWord.NumSpaces);
|
||||
index = numSpaces + charPos;
|
||||
cursorAtPreviousLineEnd = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the coord is in the word itself
|
||||
index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, (float) x - (px + spacesWidth), *TextContext);
|
||||
cursorAtPreviousLineEnd = false;
|
||||
index = charPos + currWord.NumSpaces + getCharacterIndex(currWord.Text, x - (px + spacesWidth), *TextContext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2450,7 +2502,6 @@ namespace NLGUI
|
|||
charPos += (uint)currWord.Text.length() + currWord.NumSpaces;
|
||||
}
|
||||
index = charPos;
|
||||
cursorAtPreviousLineEnd = false;
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -2466,7 +2517,7 @@ namespace NLGUI
|
|||
index = 0;
|
||||
return;
|
||||
}
|
||||
index = getCharacterIndex(_Text, (float) x, *TextContext);
|
||||
index = getCharacterIndex(_Text, x, *TextContext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2534,21 +2585,21 @@ namespace NLGUI
|
|||
// ***************************************************************************
|
||||
uint CViewText::getFirstLineX() const
|
||||
{
|
||||
return _FirstLineX;
|
||||
return _FirstLineX / _Scale;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
uint CViewText::getLastLineW () const
|
||||
{
|
||||
if (!_Lines.empty())
|
||||
return (uint)_Lines.back()->getWidth();
|
||||
return (uint)_Lines.back()->getWidth() / _Scale;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::setFirstLineX(sint firstLineX)
|
||||
{
|
||||
_FirstLineX = firstLineX;
|
||||
_FirstLineX = firstLineX * _Scale;
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
|
@ -2567,7 +2618,7 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, uint fontWidth, NL3D::UTextContext &textContext)
|
||||
void CViewText::CLine::addWord(const ucstring &text, uint numSpaces, const CFormatInfo &wordFormat, float fontWidth, NL3D::UTextContext &textContext)
|
||||
{
|
||||
CWord word;
|
||||
word.build(text, textContext, numSpaces);
|
||||
|
@ -2576,7 +2627,7 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::CLine::addWord(const CWord &word, uint fontWidth)
|
||||
void CViewText::CLine::addWord(const CWord &word, float fontWidth)
|
||||
{
|
||||
_Words.push_back(word);
|
||||
_NumChars += word.NumSpaces + uint(word.Text.length());
|
||||
|
@ -2586,7 +2637,7 @@ namespace NLGUI
|
|||
_StringLine = word.Info.StringLine;
|
||||
}
|
||||
// the width of the line must reach at least the Tab
|
||||
_WidthWithoutSpaces= max(_WidthWithoutSpaces, word.Format.TabX * float(fontWidth));
|
||||
_WidthWithoutSpaces= max(_WidthWithoutSpaces, word.Format.TabX * fontWidth);
|
||||
// append the text space
|
||||
_WidthWithoutSpaces += word.Info.StringWidth;
|
||||
}
|
||||
|
@ -2644,7 +2695,7 @@ namespace NLGUI
|
|||
TextContext->setHotSpot (UTextContext::BottomLeft);
|
||||
TextContext->setShaded (_Shadow);
|
||||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
|
||||
|
@ -2705,14 +2756,14 @@ namespace NLGUI
|
|||
linePos = lineEnd+1;
|
||||
}
|
||||
|
||||
return (sint32)maxWidth;
|
||||
return (sint32)ceilf(maxWidth / _Scale);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
sint32 CViewText::getMinUsedW() const
|
||||
{
|
||||
static const ucstring spaceOrLineFeedStr(" \n\t");
|
||||
sint32 maxWidth = 0;
|
||||
float maxWidth = 0.0f;
|
||||
|
||||
// Not multi line ? Same size than min
|
||||
if (!_MultiLine)
|
||||
|
@ -2722,7 +2773,7 @@ namespace NLGUI
|
|||
if (_TextMode == ClipWord)
|
||||
{
|
||||
// No largest font parameter, return the font height
|
||||
return _FontHeight;
|
||||
return (sint32)ceilf(_FontHeight / _Scale);
|
||||
}
|
||||
// If we can't clip the words, return the size of the largest word
|
||||
else if ((_TextMode == DontClipWord) || (_TextMode == Justified))
|
||||
|
@ -2731,7 +2782,7 @@ namespace NLGUI
|
|||
TextContext->setHotSpot (UTextContext::BottomLeft);
|
||||
TextContext->setShaded (_Shadow);
|
||||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize*_Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
|
||||
|
@ -2759,16 +2810,15 @@ namespace NLGUI
|
|||
si = TextContext->getStringInfo(wordValue);
|
||||
|
||||
// Larger ?
|
||||
sint32 stringWidth = (sint32)si.StringWidth;
|
||||
if (stringWidth>maxWidth)
|
||||
maxWidth = stringWidth;
|
||||
if (maxWidth < si.StringWidth)
|
||||
maxWidth = si.StringWidth;
|
||||
|
||||
// Next word
|
||||
currPos = wordEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return maxWidth;
|
||||
return ceilf(maxWidth / _Scale);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
@ -2782,6 +2832,17 @@ namespace NLGUI
|
|||
invalidateCoords();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::onInterfaceScaleChanged()
|
||||
{
|
||||
_Scale = CWidgetManager::getInstance()->getInterfaceScale();
|
||||
|
||||
computeFontSize ();
|
||||
invalidateContent();
|
||||
|
||||
CViewBase::onInterfaceScaleChanged();
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CViewText::computeFontSize ()
|
||||
{
|
||||
|
@ -2789,7 +2850,7 @@ namespace NLGUI
|
|||
TextContext->setHotSpot (UTextContext::BottomLeft);
|
||||
TextContext->setShaded (_Shadow);
|
||||
TextContext->setShadeOutline (_ShadowOutline);
|
||||
TextContext->setFontSize (_FontSize);
|
||||
TextContext->setFontSize (_FontSize * _Scale);
|
||||
TextContext->setEmbolden (_Embolden);
|
||||
TextContext->setOblique (_Oblique);
|
||||
|
||||
|
@ -2811,8 +2872,8 @@ namespace NLGUI
|
|||
si = TextContext->getStringInfo(chars);
|
||||
}
|
||||
// add a padding of 1 pixel else the top will be truncated
|
||||
_FontHeight = (uint) si.StringHeight+1;
|
||||
_FontLegHeight = (uint) si.StringLine;
|
||||
_FontHeight = si.StringHeight + 1;
|
||||
_FontLegHeight = si.StringLine;
|
||||
|
||||
// Space width
|
||||
si = TextContext->getStringInfo(ucstring(" "));
|
||||
|
@ -2820,7 +2881,7 @@ namespace NLGUI
|
|||
|
||||
// Font Width
|
||||
si = TextContext->getStringInfo(ucstring("_"));
|
||||
_FontWidth = (uint)si.StringWidth;
|
||||
_FontWidth = si.StringWidth;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1893,6 +1893,13 @@ namespace NLGUI
|
|||
}
|
||||
CViewRenderer::getInstance()->setClipWindow(0, 0, w, h);
|
||||
|
||||
bool scaleChanged = _InterfaceScale != CViewRenderer::getInstance()->getInterfaceScale();
|
||||
if (scaleChanged)
|
||||
{
|
||||
_InterfaceScale = CViewRenderer::getInstance()->getInterfaceScale();
|
||||
notifyInterfaceScaleWatchers();
|
||||
}
|
||||
|
||||
// If all conditions are OK, move windows so they fit correctly with new screen size
|
||||
// Do this work only InGame when Config is loaded
|
||||
moveAllWindowsToNewScreenSize(w,h,true);
|
||||
|
@ -3688,6 +3695,42 @@ namespace NLGUI
|
|||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CWidgetManager::notifyInterfaceScaleWatchers()
|
||||
{
|
||||
std::vector< IInterfaceScaleWatcher* >::iterator itr = scaleWatchers.begin();
|
||||
while( itr != scaleWatchers.end() )
|
||||
{
|
||||
(*itr)->onInterfaceScaleChanged();
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CWidgetManager::registerInterfaceScaleWatcher( IInterfaceScaleWatcher *watcher )
|
||||
{
|
||||
std::vector< IInterfaceScaleWatcher* >::const_iterator itr
|
||||
= std::find( scaleWatchers.begin(), scaleWatchers.end(), watcher );
|
||||
|
||||
if( itr != scaleWatchers.end() )
|
||||
return;
|
||||
|
||||
scaleWatchers.push_back( watcher );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CWidgetManager::unregisterInterfaceScaleWatcher( IInterfaceScaleWatcher *watcher )
|
||||
{
|
||||
std::vector< IInterfaceScaleWatcher* >::iterator itr
|
||||
= std::find( scaleWatchers.begin(), scaleWatchers.end(), watcher );
|
||||
|
||||
if( itr == scaleWatchers.end() )
|
||||
return;
|
||||
|
||||
scaleWatchers.erase( itr );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CWidgetManager::CWidgetManager()
|
||||
{
|
||||
LinkHack();
|
||||
|
@ -3724,6 +3767,7 @@ namespace NLGUI
|
|||
inGame = false;
|
||||
|
||||
setScreenWH(0, 0);
|
||||
_InterfaceScale = 1.0f;
|
||||
|
||||
_GroupSelection = false;
|
||||
multiSelection = false;
|
||||
|
|
|
@ -214,6 +214,7 @@ int main(int argc, char **argv)
|
|||
args.addArg("x", "extract", "", "Extract all interface elements from <output_filename> to <input_path>.");
|
||||
args.addAdditionalArg("output_filename", "PNG or TGA file to generate", true);
|
||||
args.addAdditionalArg("input_path", "Path that containts interfaces elements", false);
|
||||
args.addArg("b", "border", "", "Duplicate icon border to allow bilinear filtering");
|
||||
|
||||
if (!args.parse(argc, argv)) return 1;
|
||||
|
||||
|
@ -227,6 +228,13 @@ int main(int argc, char **argv)
|
|||
existingUVfilename = args.getArg("s").front();
|
||||
}
|
||||
|
||||
//
|
||||
uint borderSize = 0;
|
||||
if (args.haveArg("b"))
|
||||
{
|
||||
borderSize = 1;
|
||||
}
|
||||
|
||||
// extract all interface elements
|
||||
bool extractElements = args.haveArg("x");
|
||||
|
||||
|
@ -407,6 +415,18 @@ int main(int argc, char **argv)
|
|||
pBtmp->convertToType(CBitmap::RGBA);
|
||||
}
|
||||
|
||||
// duplicate icon border
|
||||
if (borderSize > 0)
|
||||
{
|
||||
NLMISC::CBitmap *tmp = new NLMISC::CBitmap;
|
||||
tmp->resize(pBtmp->getWidth(), pBtmp->getHeight());
|
||||
tmp->blit(pBtmp, 0, 0);
|
||||
tmp->resample(tmp->getWidth() + borderSize * 2, tmp->getHeight() + borderSize * 2);
|
||||
tmp->blit(pBtmp, borderSize, borderSize);
|
||||
delete pBtmp;
|
||||
pBtmp = tmp;
|
||||
}
|
||||
|
||||
AllMaps[i] = pBtmp;
|
||||
}
|
||||
catch (const NLMISC::Exception &e)
|
||||
|
@ -461,10 +481,10 @@ int main(int argc, char **argv)
|
|||
putIn (AllMaps[i], &GlobalTexture, x, y);
|
||||
putIn (AllMaps[i], &GlobalMask, x, y, false);
|
||||
|
||||
UVMin[i].U = (float)x;
|
||||
UVMin[i].V = (float)y;
|
||||
UVMax[i].U = (float)x+AllMaps[i]->getWidth();
|
||||
UVMax[i].V = (float)y+AllMaps[i]->getHeight();
|
||||
UVMin[i].U = (float)x + borderSize;
|
||||
UVMin[i].V = (float)y + borderSize;
|
||||
UVMax[i].U = (float)x + AllMaps[i]->getWidth() - borderSize;
|
||||
UVMax[i].V = (float)y + AllMaps[i]->getHeight() - borderSize;
|
||||
|
||||
#if 0
|
||||
// Do not remove this is useful for debugging
|
||||
|
|
|
@ -122,6 +122,8 @@
|
|||
|
||||
<command name="loot" action="inv_temp_all" params="" />
|
||||
|
||||
<command name="setuiscale" action="set_ui_scale" params="scale=$"/>
|
||||
|
||||
<command name="mapsearch" action="proc" params="map_search_show_set|+" />
|
||||
<command name="mapsearch" action="proc" params="map_search_show" />
|
||||
|
||||
|
|
|
@ -300,6 +300,9 @@ CClientConfig::CClientConfig()
|
|||
Luminosity = 0.f; // Default Monitor Luminosity.
|
||||
Gamma = 0.f; // Default Monitor Gamma.
|
||||
|
||||
InterfaceScale = 1.0f; // Resize UI
|
||||
BilinearUI = false;
|
||||
|
||||
VREnable = false;
|
||||
VRDisplayDevice = "Auto";
|
||||
VRDisplayDeviceId = "";
|
||||
|
@ -838,6 +841,10 @@ void CClientConfig::setValues()
|
|||
READ_FLOAT_FV(Luminosity)
|
||||
// Gamma
|
||||
READ_FLOAT_FV(Gamma)
|
||||
// UI scaling
|
||||
READ_FLOAT_FV(InterfaceScale);
|
||||
clamp(ClientCfg.InterfaceScale, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE);
|
||||
READ_BOOL_FV(BilinearUI);
|
||||
// 3D Driver
|
||||
varPtr = ClientCfg.ConfigFile.getVarPtr ("Driver3D");
|
||||
if (varPtr)
|
||||
|
|
|
@ -46,6 +46,9 @@ using NLMISC::CVector;
|
|||
using NLMISC::CRGBA;
|
||||
using std::string;
|
||||
|
||||
// limits for UI scale
|
||||
const float MIN_INTERFACE_SCALE = 0.8;
|
||||
const float MAX_INTERFACE_SCALE = 2.0;
|
||||
|
||||
//---------------------------------------------------
|
||||
// CClientConfig :
|
||||
|
@ -146,6 +149,10 @@ struct CClientConfig
|
|||
/// Monitor Gamma [-1 ~ 1], default 0
|
||||
float Gamma;
|
||||
|
||||
// UI scaling
|
||||
float InterfaceScale;
|
||||
bool BilinearUI;
|
||||
|
||||
// VR
|
||||
bool VREnable;
|
||||
std::string VRDisplayDevice;
|
||||
|
|
|
@ -227,6 +227,9 @@ void connectionRestoreVideoMode ()
|
|||
SetMouseCursor ();
|
||||
SetMouseSpeed (ClientCfg.CursorSpeed);
|
||||
SetMouseAcceleration (ClientCfg.CursorAcceleration);
|
||||
|
||||
// Restore user UI scaling
|
||||
CViewRenderer::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale);
|
||||
}
|
||||
|
||||
|
||||
|
@ -262,6 +265,8 @@ void setOutGameFullScreen()
|
|||
InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached);
|
||||
}
|
||||
|
||||
// Enable auto scaling in login window
|
||||
CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768);
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,6 +432,9 @@ bool connection (const string &cookie, const string &fsaddr)
|
|||
|
||||
firstConnection = false;
|
||||
|
||||
// Restore user UI scaling
|
||||
CViewRenderer::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale);
|
||||
|
||||
// Disable inputs
|
||||
Actions.enable(false);
|
||||
EditActions.enable(false);
|
||||
|
@ -558,6 +566,9 @@ bool reconnection()
|
|||
InterfaceState = globalMenu();
|
||||
}
|
||||
|
||||
// Restore user UI scaling
|
||||
CViewRenderer::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale);
|
||||
|
||||
// Disable inputs
|
||||
Actions.enable(false);
|
||||
EditActions.enable(false);
|
||||
|
|
|
@ -1332,6 +1332,8 @@ void prelogInit()
|
|||
|
||||
|
||||
CInterfaceManager::getInstance();
|
||||
CViewRenderer::getInstance()->setInterfaceScale(1.0f, 1024, 768);
|
||||
CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI);
|
||||
|
||||
// Yoyo: initialize NOW the InputHandler for Event filtering.
|
||||
CInputHandlerManager *InputHandlerManager = CInputHandlerManager::getInstance();
|
||||
|
|
|
@ -179,9 +179,9 @@ void SetMouseCursor (bool updatePos)
|
|||
// Get the last cursor
|
||||
float x = 0.5f, y = 0.5f;
|
||||
|
||||
// Window size
|
||||
uint width = Driver->getWindowWidth();
|
||||
uint height = Driver->getWindowHeight();
|
||||
// Screen size
|
||||
uint width, height;
|
||||
CViewRenderer::getInstance()->getScreenSize(width, height);
|
||||
|
||||
// Update the interface pointer
|
||||
CInterfaceManager *instance = CInterfaceManager::getInstance();
|
||||
|
|
|
@ -383,10 +383,10 @@ class CAHEditPreviousLine : public CAHEdit
|
|||
// .. so do nothing
|
||||
return;
|
||||
}
|
||||
sint cx, cy;
|
||||
sint height;
|
||||
float cx, cy;
|
||||
float height;
|
||||
_GroupEdit->getViewText()->getCharacterPositionFromIndex(cursorPosInText, _GroupEdit->isCursorAtPreviousLineEnd(), cx, cy, height);
|
||||
cy += height + _GroupEdit->getViewText()->getMultiLineSpace();
|
||||
cy += _GroupEdit->getViewText()->getLineHeight();
|
||||
uint newCharIndex;
|
||||
bool newLineEnd;
|
||||
_GroupEdit->getViewText()->getCharacterIndexFromPosition(cx, cy, newCharIndex, newLineEnd);
|
||||
|
@ -401,8 +401,8 @@ class CAHEditPreviousLine : public CAHEdit
|
|||
}
|
||||
_GroupEdit->setCursorAtPreviousLineEnd(false);
|
||||
// takes character whose X is closer to the current X
|
||||
sint cx0, cx1;
|
||||
sint cy0, cy1;
|
||||
float cx0, cx1;
|
||||
float cy0, cy1;
|
||||
_GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex, _GroupEdit->isCursorAtPreviousLineEnd(), cx0, cy0, height);
|
||||
_GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex + 1, _GroupEdit->isCursorAtPreviousLineEnd(), cx1, cy1, height);
|
||||
if (abs(cx0 - cx) < abs(cx1 - cx) || cy0 != cy1)
|
||||
|
@ -446,8 +446,8 @@ class CAHEditNextLine : public CAHEdit
|
|||
}
|
||||
else if (_GroupEdit->getViewText()->getMultiLine())
|
||||
{
|
||||
sint cx, cy;
|
||||
sint height;
|
||||
float cx, cy;
|
||||
float height;
|
||||
_GroupEdit->getViewText()->getCharacterPositionFromIndex(_GroupEdit->getCursorPos() + (sint)_GroupEdit->getPrompt().length(), _GroupEdit->isCursorAtPreviousLineEnd(), cx, cy, height);
|
||||
if (cy != 0)
|
||||
{
|
||||
|
@ -466,8 +466,8 @@ class CAHEditNextLine : public CAHEdit
|
|||
}
|
||||
_GroupEdit->setCursorAtPreviousLineEnd(false);
|
||||
// takes character whose X is closer to the current X
|
||||
sint cx0, cx1;
|
||||
sint cy0, cy1;
|
||||
float cx0, cx1;
|
||||
float cy0, cy1;
|
||||
_GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex, _GroupEdit->isCursorAtPreviousLineEnd(), cx0, cy0, height);
|
||||
_GroupEdit->getViewText()->getCharacterPositionFromIndex(newCharIndex + 1, _GroupEdit->isCursorAtPreviousLineEnd(), cx1, cy1, height);
|
||||
if (abs(cx0 - cx) < abs(cx1 - cx) || cy0 != cy1)
|
||||
|
|
|
@ -3732,6 +3732,34 @@ class CHandlerGameConfigChangeScreenRatioCustom : public IActionHandler
|
|||
};
|
||||
REGISTER_ACTION_HANDLER (CHandlerGameConfigChangeScreenRatioCustom, "game_config_change_screen_ratio_custom");
|
||||
|
||||
// ***************************************************************************
|
||||
class CHandlerSetInterfaceScale : public IActionHandler
|
||||
{
|
||||
virtual void execute (CCtrlBase *pCaller, const string &Params)
|
||||
{
|
||||
std::string s;
|
||||
s = getParam(Params, "scale");
|
||||
if (!s.empty()) {
|
||||
float scale;
|
||||
if (fromString(s, scale))
|
||||
{
|
||||
if (scale >= MIN_INTERFACE_SCALE && scale <= MAX_INTERFACE_SCALE)
|
||||
{
|
||||
ClientCfg.InterfaceScale = scale;
|
||||
ClientCfg.writeDouble("InterfaceScale", ClientCfg.InterfaceScale);
|
||||
|
||||
ClientCfg.IsInvalidated = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ucstring help("/setuiscale "+toString("%.1f .. %.1f", MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE));
|
||||
CInterfaceManager::getInstance()->displaySystemInfo(help);
|
||||
}
|
||||
};
|
||||
REGISTER_ACTION_HANDLER (CHandlerSetInterfaceScale, "set_ui_scale");
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
class CHandlerGameMissionAbandon : public IActionHandler
|
||||
|
|
|
@ -86,8 +86,10 @@ void CGroupInScene::computeWindowPos(sint32 &newX, sint32 &newY, CVector &newPro
|
|||
tmp = pVR.getFrustum().projectZ (tmp);
|
||||
|
||||
// Get the width and height
|
||||
tmp.x *= (float)CViewRenderer::getInstance()->getDriver()->getWindowWidth();
|
||||
tmp.y *= (float)CViewRenderer::getInstance()->getDriver()->getWindowHeight();
|
||||
uint32 width, height;
|
||||
CViewRenderer::getInstance()->getScreenSize(width, height);
|
||||
tmp.x *= width;
|
||||
tmp.y *= height;
|
||||
|
||||
// position without offset, in float
|
||||
newProjCenter.x= tmp.x;
|
||||
|
|
|
@ -680,9 +680,8 @@ CGroupInSceneBubbleManager::CPopupContext *CGroupInSceneBubbleManager::buildCont
|
|||
if (target)
|
||||
{
|
||||
// Find a position
|
||||
NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
|
||||
const uint width = Driver->getWindowWidth();
|
||||
const uint height = Driver->getWindowHeight();
|
||||
uint32 width, height;
|
||||
CViewRenderer::getInstance()->getScreenSize(width, height);
|
||||
h = (target->getXReal() < ((sint)width-target->getXReal()-target->getWReal()))?"l":"r";
|
||||
v = (target->getYReal() < ((sint)height-target->getYReal()-target->getHReal()))?"b":"t";
|
||||
target->setActive(true);
|
||||
|
|
|
@ -484,6 +484,8 @@ CInterfaceManager::CInterfaceManager()
|
|||
interfaceLinkUpdater = new CInterfaceLink::CInterfaceLinkUpdater();
|
||||
_ScreenW = _ScreenH = 0;
|
||||
_LastInGameScreenW = _LastInGameScreenH = 0;
|
||||
_InterfaceScaleChanged = false;
|
||||
_InterfaceScale = 1.0f;
|
||||
_DescTextTarget = NULL;
|
||||
_ConfigLoaded = false;
|
||||
_LogState = false;
|
||||
|
@ -1828,8 +1830,12 @@ bool CInterfaceManager::loadConfig (const string &filename)
|
|||
CWidgetManager::getInstance()->setScreenWH(_LastInGameScreenW, _LastInGameScreenH);
|
||||
// NB: we are typically InGame here (even though the _InGame flag is not yet set)
|
||||
// Use the screen size of the config file. Don't update current UI, just _Modes
|
||||
CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(ClientCfg.Width, ClientCfg.Height, false);
|
||||
updateDesktops( ClientCfg.Width, ClientCfg.Height );
|
||||
//
|
||||
// ClientCfg has W/H set to screen size, but interface expects scaled size
|
||||
sint32 scaledW = ClientCfg.Width / ClientCfg.InterfaceScale;
|
||||
sint32 scaledH = ClientCfg.Height / ClientCfg.InterfaceScale;
|
||||
CWidgetManager::getInstance()->moveAllWindowsToNewScreenSize(scaledW, scaledH, false);
|
||||
updateDesktops(scaledW, scaledH);
|
||||
}
|
||||
|
||||
// *** apply the current mode
|
||||
|
@ -2050,6 +2056,13 @@ void CInterfaceManager::drawViews(NL3D::UCamera camera)
|
|||
_CurrentPlayerCharac[i] = node ? node->getValue32() : 0;
|
||||
}
|
||||
|
||||
// scale must be updated right before widget manager checks it
|
||||
if (_InterfaceScaleChanged)
|
||||
{
|
||||
CViewRenderer::getInstance()->setInterfaceScale(_InterfaceScale);
|
||||
_InterfaceScaleChanged = false;
|
||||
}
|
||||
|
||||
CWidgetManager::getInstance()->drawViews( camera );
|
||||
|
||||
// flush obs
|
||||
|
@ -2938,7 +2951,6 @@ NLMISC_COMMAND(loadui, "Load an interface file", "<loadui [all]/interface.xml>")
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
void CInterfaceManager::displayWebWindow(const string & name, const string & url)
|
||||
{
|
||||
|
|
|
@ -549,6 +549,7 @@ public:
|
|||
NLMISC::CCDBNodeLeaf *_DB_UI_DUMMY_FACTION_TYPE;
|
||||
|
||||
void updateDesktops( uint32 newScreenW, uint32 newScreenH );
|
||||
void setInterfaceScale( float scale ) { _InterfaceScaleChanged = true; _InterfaceScale = scale; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -587,6 +588,8 @@ private:
|
|||
|
||||
uint32 _ScreenW, _ScreenH; // Change res detection
|
||||
sint32 _LastInGameScreenW, _LastInGameScreenH; // Resolution used for last InGame interface
|
||||
float _InterfaceScale;
|
||||
bool _InterfaceScaleChanged;
|
||||
|
||||
// Modes
|
||||
std::vector<CInterfaceConfig::CDesktopImage> _Modes;
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "input.h"
|
||||
#include "sound_manager.h"
|
||||
#include "camera.h"
|
||||
#include "interface_v3/interface_manager.h"
|
||||
|
||||
using namespace NLMISC;
|
||||
using namespace NL3D;
|
||||
|
@ -100,6 +101,12 @@ void updateFromClientCfg()
|
|||
Driver->forceTextureResize(1);
|
||||
}
|
||||
|
||||
if (ClientCfg.InterfaceScale != LastClientCfg.InterfaceScale)
|
||||
CInterfaceManager::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale);
|
||||
|
||||
if (ClientCfg.BilinearUI != LastClientCfg.BilinearUI)
|
||||
CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI);
|
||||
|
||||
//---------------------------------------------------
|
||||
if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue