summaryrefslogtreecommitdiff
path: root/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp')
-rw-r--r--plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp857
1 files changed, 857 insertions, 0 deletions
diff --git a/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp b/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp
new file mode 100644
index 0000000000..ab5350ec86
--- /dev/null
+++ b/plugins/MirandaG15/LCDFramework/src/CLCDInput.cpp
@@ -0,0 +1,857 @@
+#include "stdafx.h"
+#include "CLCDInput.h"
+#include "CLCDOutputManager.h"
+
+//************************************************************************
+// CLCDInput::CLCDInput
+//************************************************************************
+CLCDInput::CLCDInput()
+{
+ m_lInputTime = 0;
+ m_iLinePosition = 0;
+ ZeroMemory(&m_Marker,2*sizeof(SMarker));
+
+ m_pScrollbar = NULL;
+ m_bShowSymbols = true;
+ m_iBreakKeys = KEYS_RETURN;
+ m_bShowMarker = false;
+ m_lBlinkTimer = 0;
+
+ m_iLineCount = 0;
+// SetScrollbarAlignment(TOP);
+ Reset();
+}
+
+
+//************************************************************************
+// CLCDInput::~CLCDInput
+//************************************************************************
+CLCDInput::~CLCDInput()
+{
+ m_vLineOffsets.clear();
+}
+
+//************************************************************************
+// CLCDInput::Initialize
+//************************************************************************
+bool CLCDInput::Initialize()
+{
+ if(!CLCDTextObject::Initialize())
+ return false;
+
+// m_pParent = pParent;
+ return true;
+}
+
+//************************************************************************
+// CLCDInput::Shutdown
+//************************************************************************
+bool CLCDInput::Shutdown()
+{
+ if(!CLCDTextObject::Shutdown())
+ return false;
+
+
+ return true;
+}
+//************************************************************************
+// CLCDInput::Update
+//************************************************************************
+void CLCDInput::SetScrollbar(CLCDBar *pScrollbar)
+{
+ m_pScrollbar = pScrollbar;
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+ m_pScrollbar->SetRange(0,m_vLineOffsets.size());
+ m_pScrollbar->ScrollTo(m_iLinePosition);
+ }
+}
+
+//************************************************************************
+// CLCDInput::GetLastInputTime
+//************************************************************************
+long CLCDInput::GetLastInputTime()
+{
+ return m_lInputTime;
+}
+
+//************************************************************************
+// CLCDInput::Update
+//************************************************************************
+bool CLCDInput::Update()
+{
+ if(!CLCDTextObject::Update())
+ return false;
+
+ if(m_lBlinkTimer + 500 <= GetTickCount())
+ {
+ m_bShowMarker = !m_bShowMarker;
+ m_lBlinkTimer = GetTickCount();
+ }
+
+ return true;
+}
+
+//************************************************************************
+// CLCDInput::Draw
+//************************************************************************
+bool CLCDInput::Draw(CLCDGfx *pGfx)
+{
+ if(!CLCDTextObject::Draw(pGfx))
+ return false;
+
+
+ SelectObject(pGfx->GetHDC(),m_hFont);
+
+ RECT rBoundary = { 0, 0,0 + GetWidth(), 0 + GetHeight() };
+ int iLine = m_iLinePosition;
+ int iEndLine = m_iLinePosition + m_iLineCount;
+ int iLen = 0;
+ TCHAR *pcOffset = NULL;
+ while(iLine < iEndLine && iLine < m_vLineOffsets.size())
+ {
+ // Calculate the text length
+ if(iLine < m_vLineOffsets.size() -1)
+ {
+ iLen = m_vLineOffsets[iLine+1].iOffset - m_vLineOffsets[iLine].iOffset;
+ // Draw the linebreak marker
+ if(m_bShowSymbols && m_vLineOffsets[iLine+1].bLineBreak)
+ pGfx->DrawFilledRect(m_vLineOffsets[iLine].iWidth+1,rBoundary.top+m_iFontHeight/3,m_iFontHeight/3,m_iFontHeight/3);
+ }
+ else
+ iLen = m_strText.length() - m_vLineOffsets[iLine].iOffset;
+
+ // Draw the text
+ pcOffset = (TCHAR*)m_strText.c_str() + m_vLineOffsets[iLine].iOffset;
+ DrawTextEx(pGfx->GetHDC(),
+ (LPTSTR)pcOffset,
+ iLen,
+ &rBoundary,
+ m_iTextFormat,
+ &m_dtp);
+
+ // Draw the input cursor
+ if(m_pInput && m_bShowMarker && m_Marker[0].iLine == iLine)
+ {
+ // insert-mode cursor
+ if(m_bInsert ||m_Marker[0].iXWidth == 1)
+ {
+ pGfx->DrawFilledRect(m_Marker[0].iXLine,
+ m_iFontHeight*(iLine-m_iLinePosition),
+ 1,
+ m_iFontHeight);
+ }
+ // replace-mode cursor
+ else
+ {
+ RECT rMarker = {m_Marker[0].iXLine,
+ m_iFontHeight*(iLine-m_iLinePosition),
+ m_Marker[0].iXLine+m_Marker[0].iXWidth,
+ m_iFontHeight*(iLine-m_iLinePosition+1)};
+ InvertRect(pGfx->GetHDC(),&rMarker);
+ }
+ }
+
+ rBoundary.top += m_iFontHeight;
+ rBoundary.bottom += m_iFontHeight;
+
+ iLine++;
+ }
+ return true;
+}
+
+//************************************************************************
+// CLCDInput::ShowSymbols
+//************************************************************************
+void CLCDInput::ShowSymbols(bool bShow)
+{
+ m_bShowSymbols = bShow;
+}
+
+//************************************************************************
+// CLCDInput::SetBreakKeys
+//************************************************************************
+void CLCDInput::SetBreakKeys(int iKeys)
+{
+ m_iBreakKeys = iKeys;
+}
+
+//************************************************************************
+// returns wether the input is currently active
+//************************************************************************
+bool CLCDInput::IsInputActive()
+{
+ return m_pInput != NULL;
+}
+
+
+//************************************************************************
+// CLCDInput::OnSizeChanged
+//************************************************************************
+void CLCDInput::OnSizeChanged(SIZE OldSize)
+{
+ // if the width has changed, offsets need to be recalculated
+ if(GetWidth() != OldSize.cx)
+ OnFontChanged();
+ // otherwise, just update scrollbar & linecount
+ else if(m_pScrollbar)
+ {
+ m_iLineCount = GetHeight() / m_iFontHeight;
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+ }
+}
+
+//************************************************************************
+// CLCDInput::OnFontChanged
+//************************************************************************
+void CLCDInput::OnFontChanged()
+{
+ if(m_iFontHeight == 0)
+ return;
+
+ if(m_pScrollbar)
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+
+ m_iLinePosition = 0;
+ m_iLineCount = GetHeight() / m_iFontHeight;
+
+ if(m_pScrollbar)
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+
+ m_Marker[0].iLine = 0;
+ m_Marker[0].iPosition = 0;
+ m_Marker[0].iPosition = m_strText.length();
+
+ // Delete all offsets and recalculate them
+ m_vLineOffsets.clear();
+ // Create a new offset
+ SLineEntry offset;
+ offset.bLineBreak = false;
+ offset.iOffset = 0;
+ m_vLineOffsets.push_back(offset);
+
+ UpdateOffsets(0);
+
+ UpdateMarker();
+ if(m_iLineCount > 0)
+ ScrollToMarker();
+}
+
+//************************************************************************
+// CLCDInput::ActivateInput
+//************************************************************************
+void CLCDInput::ActivateInput()
+{
+ if(m_pInput)
+ return;
+
+ CLCDConnection *pLCDCon = CLCDOutputManager::GetInstance()->GetLCDConnection();
+ pLCDCon->SetAsForeground(1);
+
+ m_hKBHook = SetWindowsHookEx(WH_KEYBOARD_LL, CLCDInput::KeyboardHook, GetModuleHandle(NULL), 0);
+ if(!m_hKBHook)
+ return;
+ m_pInput = this;
+ GetKeyboardState(m_acKeyboardState);
+}
+
+//************************************************************************
+// CLCDInput::DeactivateInput
+//************************************************************************
+void CLCDInput::DeactivateInput()
+{
+ if(!m_pInput)
+ return;
+ UnhookWindowsHookEx(m_hKBHook);
+ m_hKBHook = NULL;
+
+ m_pInput = NULL;
+
+ CLCDConnection *pLCDCon = CLCDOutputManager::GetInstance()->GetLCDConnection();
+ pLCDCon->SetAsForeground(0);
+}
+
+//************************************************************************
+// CLCDInput::KeyboardHook
+//************************************************************************
+CLCDInput* CLCDInput::m_pInput = NULL;
+
+LRESULT CALLBACK CLCDInput::KeyboardHook(int Code, WPARAM wParam, LPARAM lParam)
+{
+ return m_pInput->ProcessKeyEvent(Code,wParam,lParam);
+}
+
+//************************************************************************
+// CLCDInput::ProcessKeyEvent
+//************************************************************************
+LRESULT CLCDInput::ProcessKeyEvent(int Code, WPARAM wParam, LPARAM lParam)
+{
+ // Event verarbeiten
+ if(Code == HC_ACTION)
+ {
+ KBDLLHOOKSTRUCT *key = (KBDLLHOOKSTRUCT *)(lParam);
+
+ bool bKeyDown = !(key->flags & LLKHF_UP);
+ bool bToggled = (m_acKeyboardState[key->vkCode] & 0x0F);
+ if(bKeyDown)
+ bToggled = !bToggled;
+ m_acKeyboardState[key->vkCode] = (bKeyDown?0x80:0x00) | (bToggled?0x01:0x00);
+ if(key->vkCode == VK_LSHIFT || key->vkCode == VK_RSHIFT)
+ m_acKeyboardState[VK_SHIFT] = m_acKeyboardState[key->vkCode];
+ else if(key->vkCode == VK_LCONTROL || key->vkCode == VK_RCONTROL)
+ m_acKeyboardState[VK_CONTROL] = m_acKeyboardState[key->vkCode];
+ else if(key->vkCode == VK_LMENU || key->vkCode == VK_RMENU)
+ m_acKeyboardState[VK_MENU] = m_acKeyboardState[key->vkCode];
+
+ /*
+ if(bKeyDown)
+ TRACE(_T("Key pressed: %i\n"),key->vkCode);
+ else
+ TRACE(_T("Key released: %i\n"),key->vkCode);
+ */
+ // Only handle Keyup
+ if(bKeyDown)
+ {
+ // Actions with Control/Menu keys
+ if((m_acKeyboardState[VK_LMENU] & 0x80 || m_acKeyboardState[VK_CONTROL] & 0x80)
+ && m_acKeyboardState[VK_SHIFT] & 0x80)
+ {
+ ActivateKeyboardLayout((HKL)HKL_NEXT,0);//KLF_SETFORPROCESS);
+ TRACE(_T("Keyboardlayout switched!\n"));
+ return 1;
+ }
+
+ int res = 0,size = 0,dir = MARKER_HORIZONTAL,scroll = 0;
+/*
+ if(key->vkCode == VK_DELETE) {
+ dir = MARKER_HOLD;
+ res = -1;
+ if(m_strText[m_Marker[0].iPosition] == '\r')
+ res = -2;
+ if(m_strText.length() >= m_Marker[0].iPosition + -res) {
+ m_strText.erase(m_Marker[0].iPosition,-res);
+ scroll = 1;
+ size = 1;
+ } else {
+ res = 0;
+ }
+ }
+ else */if(key->vkCode == VK_BACK )
+ {
+ if(m_Marker[0].iPosition != 0)
+ {
+ res = -1;
+ if(m_strText[m_Marker[0].iPosition+res] == '\n')
+ res = -2;
+
+ m_strText.erase(m_Marker[0].iPosition+res,-res);
+ scroll = 1;
+ size = res;
+ }
+ }
+ // Marker navigation
+ else if (key->vkCode == VK_INSERT)
+ {
+ m_bInsert = !m_bInsert;
+ }
+ else if(key->vkCode == VK_HOME)
+ {
+ res = m_vLineOffsets[m_Marker[0].iLine].iOffset - m_Marker[0].iPosition;
+ scroll = 1;
+ }
+ else if(key->vkCode == VK_END)
+ {
+ if(m_vLineOffsets.size()-1 == m_Marker[0].iLine)
+ res = m_strText.length() - m_Marker[0].iPosition;
+ else
+ {
+ res = (m_vLineOffsets[m_Marker[0].iLine+1].iOffset - 1 - m_vLineOffsets[m_Marker[0].iLine+1].bLineBreak) -m_Marker[0].iPosition;
+ }
+ scroll = 1;
+ }
+ else if(key->vkCode == VK_UP)
+ {
+ res = -1;
+ dir = MARKER_VERTICAL;
+ }
+ else if(key->vkCode == VK_DOWN)
+ {
+ res = 1;
+ dir = MARKER_VERTICAL;
+ }
+ else if(key->vkCode == VK_LEFT)
+ res = -1;
+ else if(key->vkCode == VK_RIGHT)
+ res = 1;
+
+ else
+ {
+
+#ifdef _UNICODE
+ TCHAR output[4];
+#else
+ unsigned char output[2];
+#endif
+
+ if(key->vkCode == VK_RETURN)
+ {
+ bool bCtrlDown = (bool)(m_acKeyboardState[VK_CONTROL] & 0x80);
+ if( bCtrlDown != (m_iBreakKeys == KEYS_RETURN))
+ {
+ DeactivateInput();
+ //m_pParent->OnInputFinished();
+ return 1;
+ }
+ else
+ {
+ res = 2;
+ output[0] = '\r';
+ output[1] = '\n';
+ output[2] = 0;
+ }
+ }
+ else
+ {
+#ifdef _UNICODE
+ res = ToUnicode(key->vkCode,key->scanCode,m_acKeyboardState,output,4,0);
+#else
+ res = ToAscii( key->vkCode,key->scanCode,m_acKeyboardState,(WORD*)output,0);
+#endif
+ }
+
+ if(res <= 0)
+ res = 0;
+ else
+ {
+ if(output[0] != '\r' && output[0] <= 0x001F)
+ return 1;
+
+ if(m_bInsert || m_strText[m_Marker[0].iPosition] == '\r')
+ m_strText.insert(m_Marker[0].iPosition,(TCHAR*)output,res);
+ else
+ m_strText.replace(m_Marker[0].iPosition,res,(TCHAR*)output);
+
+ scroll = 1;
+ size = res;
+ }
+ }
+ if(res != 0)
+ {
+ if(dir != MARKER_HOLD) {
+ MoveMarker(dir,res);
+ }
+ UpdateOffsets(size);
+ UpdateMarker();
+ ScrollToMarker();
+ m_lInputTime = GetTickCount();
+ }
+ //WrapLine();
+ // ----
+
+
+
+ // Block this KeyEvent
+ }
+ return 1;
+ }
+ return CallNextHookEx(m_hKBHook, Code, wParam, lParam);
+}
+
+//************************************************************************
+// CLCDInput::MoveMarker
+//************************************************************************
+void CLCDInput::MoveMarker(int iDir,int iMove,bool bShift)
+{
+ // Just cursor
+ if(!bShift)
+ {
+ m_lBlinkTimer = GetTickCount();
+ m_bShowMarker = true;
+
+ if(iDir == MARKER_HORIZONTAL)
+ {
+ m_Marker[0].iPosition += iMove;
+
+ }
+ if(iDir == MARKER_VERTICAL)
+ {
+ if(iMove < 0 && m_Marker[0].iLine == 0)
+ return;
+ if(iMove > 0 && m_Marker[0].iLine == m_vLineOffsets.size()-1)
+ return;
+
+ m_Marker[0].iLine += iMove;
+
+ int iX = 0,iX2 = 0;
+
+ SIZE sizeChar = {0,0};
+ int iBegin = m_vLineOffsets[m_Marker[0].iLine].iOffset;
+ int iLen = 0;
+ if(m_Marker[0].iLine < m_vLineOffsets.size() -1)
+ iLen = m_vLineOffsets[m_Marker[0].iLine+1].iOffset - m_vLineOffsets[m_Marker[0].iLine].iOffset;
+ else
+ iLen = m_strText.length() - m_vLineOffsets[m_Marker[0].iLine].iOffset;
+
+ HDC hDC = CreateCompatibleDC(NULL);
+ if(NULL == hDC)
+ return;
+ SelectObject(hDC, m_hFont);
+ m_Marker[0].iXWidth = 1;
+ m_Marker[0].iPosition = -1;
+
+ int *piWidths = new int[iLen];
+ int iMaxChars;
+ int iChar=iBegin;
+
+ GetTextExtentExPoint(hDC,m_strText.c_str() + iBegin,iLen,GetWidth(),&iMaxChars,piWidths,&sizeChar);
+ for(;iChar<iBegin+iMaxChars;iChar++)
+ {
+ iX2 = iX;
+ iX = piWidths[iChar-iBegin];
+
+ if(m_Marker[0].iPosition >= 0 &&
+ iChar >= m_Marker[0].iPosition)
+ {
+ m_Marker[0].iXWidth = sizeChar.cx;
+ break;
+ }
+
+ if(iX >= m_Marker[0].iXLine || (iChar < iBegin+iLen -1 && m_strText[iChar+1] == 10))
+ {
+ if( m_Marker[0].iXLine - iX2 <= iX - m_Marker[0].iXLine)
+ {
+ m_Marker[0].iPosition = iChar;
+ m_Marker[0].iXLine = iX2;
+ m_Marker[0].iXWidth = sizeChar.cx;
+ break;
+ }
+ else
+ {
+ m_Marker[0].iPosition = iChar+1;
+ m_Marker[0].iXLine = iX;
+ }
+ }
+ }
+
+ free(piWidths);
+
+ if(m_Marker[0].iPosition == -1)
+ {
+ m_Marker[0].iPosition = iChar;
+ m_Marker[0].iXLine = iX;
+ }
+ DeleteObject(hDC);
+ }
+
+ for(int i=0;i<2;i++)
+ {
+ if(m_Marker[i].iPosition < 0)
+ m_Marker[i].iPosition = 0;
+ else if(m_Marker[i].iPosition > m_strText.length() )
+ m_Marker[i].iPosition = m_strText.length();
+ }
+ if(m_Marker[0].iPosition > 0 && m_strText[m_Marker[0].iPosition-1] == '\r')
+ m_Marker[0].iPosition+= (iDir == MARKER_HORIZONTAL && iMove>0)?1:-1;
+
+ }
+}
+
+//************************************************************************
+// CLCDInput::GetText
+//************************************************************************
+tstring CLCDInput::GetText()
+{
+ return m_strText;
+}
+
+//************************************************************************
+// CLCDInput::Reset
+//************************************************************************
+void CLCDInput::Reset()
+{
+ m_lInputTime = 0;
+ m_bInsert = true;
+
+ ZeroMemory(&m_Marker[0],sizeof(SMarker));
+
+ m_strText = _T("");
+ m_vLineOffsets.clear();
+ m_iLinePosition = 0;
+ SLineEntry offset;
+ offset.bLineBreak = false;
+ offset.iOffset = 0;
+ m_vLineOffsets.push_back(offset);
+
+ if(m_pScrollbar)
+ {
+ m_pScrollbar->ScrollTo(0);
+ m_pScrollbar->SetRange(0,0);
+ m_pScrollbar->SetSliderSize(m_iLineCount);
+ }
+}
+
+//************************************************************************
+// CLCDInput::UpdateOffsets
+//************************************************************************
+void CLCDInput::UpdateOffsets(int iModified)
+{
+ if(m_vLineOffsets.size() == 0 && m_strText.empty())
+ return;
+
+ // Reset the marker
+ m_Marker[0].iXLine = 0;
+ m_Marker[0].iXWidth = 1;
+
+ // Initialize variables
+ int iLen = m_strText.length();
+ int *piWidths = new int[iLen];
+ TCHAR *pszText = (TCHAR*)m_strText.c_str();
+ tstring::size_type pos = 0;
+ int iMaxChars = 0;
+
+ SIZE sizeWord = {0, 0};
+ SIZE sizeChar = {0, 0};
+ SIZE sizeLine = {0, 0};
+ HDC hDC = CreateCompatibleDC(NULL);
+ if(NULL == hDC)
+ return;
+ SelectObject(hDC, m_hFont);
+
+ int iLine = -1;
+ // Find the first line to update
+ for(int i=m_vLineOffsets.size()-1;i>=0;i--)
+ if(m_vLineOffsets[i].iOffset <= m_Marker[0].iPosition)
+ {
+ iLine = i;
+ break;
+ }
+
+ if(iModified < 0 && iLine-1 >= 0)
+ iLine--;
+
+ bool bLineClosed = false;
+
+ // TRACE(_T("InputText: Begin Update at #%i\n"),iLine);
+ for(;iLine<m_vLineOffsets.size();iLine++)
+ {
+ bLineClosed = false;
+
+ int iChar = m_vLineOffsets[iLine].iOffset;
+ int iWordOffset = iChar;
+
+ if(!(iLen == 0) && iChar > iLen)
+ {
+ // TRACE(_T("InputText: Deleted offset #%i\n"),iLine);
+ m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine);
+ continue;
+ }
+
+ sizeLine.cx = 0;
+ sizeWord.cx = 0;
+ iWordOffset = iChar+1;
+
+ while(iChar<iLen)
+ {
+ iWordOffset= iChar;
+
+ GetTextExtentExPoint(hDC,pszText+iChar,iLen-iChar,GetWidth(),&iMaxChars,piWidths,&sizeLine);
+ pos = m_strText.find(_T("\n"),iChar);
+ // check for linebreaks
+ if(pos != tstring::npos & pos >= iChar && pos <= iChar + iMaxChars)
+ {
+ iWordOffset = pos + 1;
+ iMaxChars = pos - iChar;
+ }
+ // if the string doesnt fit, try to wrap the last word to the next line
+ else
+ {
+ // find the last space in the line
+ pos = m_strText.rfind(_T(" "),iChar + iMaxChars);
+ if(pos != tstring::npos && pos >= iChar)
+ iWordOffset = pos +1;
+ else
+ iWordOffset = iChar+iMaxChars;
+ }
+
+ if(m_Marker[0].iPosition >= iChar && m_Marker[0].iPosition <= iChar + iMaxChars)
+ {
+ if(m_Marker[0].iPosition > iChar)
+ {
+ m_Marker[0].iXLine = piWidths[m_Marker[0].iPosition -1 - iChar];
+ if(m_strText[m_Marker[0].iPosition -1] == '\n' )
+ m_Marker[0].iXLine = 0;
+ }
+ if(m_Marker[0].iPosition < iChar + iMaxChars)
+ {
+ if(m_strText[m_Marker[0].iPosition] > 0x001F)
+ m_Marker[0].iXWidth = piWidths[m_Marker[0].iPosition - iChar]-m_Marker[0].iXLine;
+ }
+ }
+
+ iChar += iMaxChars;
+
+ if(m_strText[iChar] == '\n' || sizeLine.cx > GetWidth())
+ {
+
+ bLineClosed = true;
+
+ int iDistance = INFINITE;
+
+
+ // Check if a matching offset already exists
+ for(int iLine2 = iLine+1;iLine2<m_vLineOffsets.size();iLine2++)
+ {
+ if(m_vLineOffsets[iLine2].bLineBreak == (m_strText[iChar] == '\n'))
+ {
+ iDistance = iChar - (m_vLineOffsets[iLine2].iOffset-1);
+ if(m_vLineOffsets[iLine2].iOffset == iWordOffset || iDistance == iModified)
+ {
+ // if there are other offsets in front of this one, delete them
+ if(iLine2 != iLine + 1 )
+ {
+ // TRACE(_T("InputText: Deleted offsets #%i to #%i\n"),iLine+1,iLine2-1);
+ m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine+1,m_vLineOffsets.begin()+iLine2);
+ }
+ break;
+ }
+ }
+ }
+ // A matching offset was found
+ if(iDistance == iModified)
+ {
+ if(iModified != 0)
+ {
+ // Update line's width
+ if(iMaxChars > 0)
+ {
+ if(m_strText[iChar] == '\n' && iMaxChars >= 2)
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-2];
+ else
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-1];
+ }
+ else
+ m_vLineOffsets[iLine].iWidth = 0;
+
+ // TRACE(_T("InputText: shifted offsets #%i to end %i position(s)\n"),iLine+1,iDistance);
+ for(iLine++;iLine<m_vLineOffsets.size();iLine++)
+ m_vLineOffsets[iLine].iOffset += iDistance;
+
+ goto finished;
+ }
+ }
+ // if no matching offset was found, a new one has to be created
+ else if(iDistance != 0)
+ {
+ SLineEntry offset;
+ offset.bLineBreak = (m_strText[iChar] == '\n');
+ offset.iOffset = iWordOffset;
+ if(iLine == m_vLineOffsets.size()-1)
+ m_vLineOffsets.push_back(offset);
+ else
+ m_vLineOffsets.insert(m_vLineOffsets.begin()+iLine+1,offset);
+
+ // TRACE(_T("InputText: Inserted new %soffset at #%i\n"),m_strText[iChar] == '\n'?_T("linebreak "):_T(""),iLine+1);
+ }
+ break;
+ }
+ }
+ // Update line's width
+ if(iMaxChars > 0)
+ {
+ if(m_strText[iChar] == '\n' && iMaxChars >= 2)
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-2];
+ else
+ m_vLineOffsets[iLine].iWidth = piWidths[iMaxChars-1];
+ }
+ else
+ m_vLineOffsets[iLine].iWidth = 0;
+
+ if(iLine != m_vLineOffsets.size() - 1 && !bLineClosed)
+ {
+ // TRACE(_T("InputText: Deleted offsets #%i to #%i\n"),iLine+1,m_vLineOffsets.size()-1);
+ m_vLineOffsets.erase(m_vLineOffsets.begin()+iLine+1,m_vLineOffsets.end());
+ }
+
+ }
+
+finished:
+ free(piWidths);
+ DeleteObject(hDC);
+
+ if(m_pScrollbar)
+ m_pScrollbar->SetRange(0,m_vLineOffsets.size()-1);
+}
+
+//************************************************************************
+// CLCDInput::UpdateMarker
+//************************************************************************
+void CLCDInput::UpdateMarker()
+{
+ // Adjust the markers propertys
+ for(int i=m_vLineOffsets.size()-1;i>= 0;i--)
+ if(m_Marker[0].iPosition >= m_vLineOffsets[i].iOffset)
+ {
+ if(m_Marker[0].iPosition == m_vLineOffsets[i].iOffset)
+ m_Marker[0].iXLine = 0;
+ m_Marker[0].iLine = i;
+ break;
+ }
+}
+
+//************************************************************************
+// CLCDInput::ScrollLine
+//************************************************************************
+bool CLCDInput::ScrollLine(bool bDown)
+{
+ if(bDown && m_iLinePosition + (m_iLineCount-1) < m_vLineOffsets.size() -1)
+ m_iLinePosition++;
+ else if(!bDown && m_iLinePosition > 0)
+ m_iLinePosition--;
+ else
+ return false;
+
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollTo(m_iLinePosition);
+ return true;
+}
+
+
+//************************************************************************
+// CLCDInput::ScrollToMarker
+//************************************************************************
+void CLCDInput::ScrollToMarker()
+{
+ if(m_Marker[0].iLine < m_iLinePosition)
+ m_iLinePosition = m_Marker[0].iLine;
+ if(m_Marker[0].iLine > m_iLinePosition + (m_iLineCount-1))
+ {
+ ScrollLine();
+ if(m_Marker[0].iLine > m_iLinePosition + (m_iLineCount-1))
+ m_iLinePosition = (m_Marker[0].iLine / m_iLineCount )*m_iLineCount;
+ }
+
+ if(m_iLinePosition > m_vLineOffsets.size()-1)
+ m_iLinePosition = m_vLineOffsets.size() -1;
+ if(m_iLinePosition < 0)
+ m_iLinePosition = 0;
+
+ if(m_pScrollbar)
+ m_pScrollbar->ScrollTo(m_iLinePosition);
+}
+
+//************************************************************************
+// CLCDInput::GetLineCount
+//************************************************************************
+int CLCDInput::GetLineCount()
+{
+ return m_vLineOffsets.size();
+}
+
+//************************************************************************
+// CLCDInput::GetLine
+//************************************************************************
+int CLCDInput::GetLine()
+{
+ return m_iLinePosition;
+} \ No newline at end of file