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