1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along
- // with this program; if not, write to the Free Software Foundation, Inc.,
- // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // EDIT.CPP
- //
- // History:
- // 08/15/96 JMI Started.
- //
- // 09/24/96 JMI Changed all BLU_MB?_* macros to RSP_MB?_* macros.
- //
- // 10/02/96 JMI No longer checks ms_szText for NULL before calling
- // m_print stuff and updating m_aptTextPos.
- //
- // 10/27/96 MJR Fixed "unused variable" warnings.
- //
- // 10/31/96 JMI Changed:
- // Old label: New label:
- // ========= =========
- // CEdit REdit
- // CTxt RTxt
- // CImage RImage
- // CGuiItem RGuiItem
- // LEFT RGuiItem::Left
- // MULTILINE Multiline
- // NUMBERS_ONLY NumbersOnly
- // POINT Point
- // EDITNOTIFY EditNotify
- //
- // Moved #include <string.h> to the beginning.
- //
- // 10/30/96 JMI Changed:
- // Old label: New label:
- // ========= =========
- // Rect RRect
- //
- // 11/12/96 MJR Added RSP_ prefix to GK keyboard macros.
- //
- // 11/14/96 JMI DrawText() now attempts to clip the string to the edit
- // box.
- //
- // 11/27/96 JMI Added initialization of m_type to identify this type
- // of GUI item.
- //
- // 12/04/96 JMI Do() can no longer optionally poll for input, does not
- // call rspGetKey(), and does not return that key. Instead,
- // you pass the a pointer to the rspGetKeys() formatted key
- // you want Do() to process. The key will be zeroed if it
- // is "absorbed" by the edit box.
- //
- // 12/19/96 JMI Uses new m_justification (as m_sJustification) and
- // upgraded to new RFont/RPrint.
- //
- // 12/31/96 JMI Do() now calls base implementation in RGuiItem.
- //
- // 01/01/97 JMI DrawText() now draws a space with transparent back and
- // foreground colors so that the positions array will be
- // updated so we can use the caret position.
- // Also, now clips caret.
- //
- // 01/04/97 JMI Upgraded HotCall() to new CursorEvent(). This upgrade
- // is in response to RGuiItem now using relative RHots.
- // Now m_hot.m_sX/Y is parent item relative just like
- // m_sX/Y. This should simplify a lot of stuff and even
- // fix some odd features like being able to click a GUI
- // item that exceeds the boundary of its parent. This fix
- // will be essential for the not-yet-existent RListBox since
- // it will most likely scroll many children through a small
- // client area.
- // Now there are two regions associated with cursor events.
- // The first is the 'hot' area. This is the area that m_hot
- // is set to include. Child items can only receive cursor
- // events through this area. The second is the 'event' area.
- // This is the area where the item really is actually con-
- // cerned with cursor events. Example: For a Dlg, the
- // entire window is the 'hot' area and the title bar is the
- // 'event' area.
- //
- // 01/08/97 JMI There were some typos in Draw() involving clipping.
- // Fixed.
- //
- // 01/18/97 JMI Converted Do() to take an RInputEvent* instead of a
- // long*.
- //
- // 01/20/97 JMI Made very few changes for overriding Read/WriteMembers.
- // Should not change functionality. Checked in to use at
- // home.
- //
- // 01/21/97 JMI Added ReadMembers() and WriteMembers() overloads to read
- // and write members of this class. Note that they call the
- // base class version to read/write base class members.
- // Support exists for versions 0 and 1. Version 0 did not
- // contain other than RGuiItem members.
- //
- // 01/23/97 JMI Added escape to keys we don't want to process during Do().
- //
- // 01/23/97 JMI Now sets m_sShowFocus to FALSE in constructor. Focus is
- // shown via caret anyhow.
- //
- // 02/05/97 JMI Changed position of default: case in ReadMembers().
- //
- // 03/14/97 JMI Added ClipCaret().
- //
- // 03/19/97 JMI Converted to using the RHot::m_iecUser (was using
- // RHot::m_epcUser) so HotCall and CursorEvent now take
- // RInputEvent ptrs.
- //
- // 03/28/97 JMI RSP_MB0_DOUBLECLICK is now treated the same as
- // RSP_MB0_PRESSED.
- //
- // 04/10/97 JMI DrawText() considers new m_sFontCellHeight member.
- // Now uses m_sFontCellHeight instead of GetPos() to get
- // cell height.
- //
- // 04/24/97 JMI Added m_u32TextShadowColor.
- //
- // 07/07/97 JMI Now calls SetTextEffects() before drawing text in
- // DrawText() and Draw().
- //
- // 08/25/97 JMI Added m_sFirstVisibleCharIndex which is the first visible
- // character in the field.
- // Now automagically scrolls left or right based on caret
- // positions.
- //
- // 08/25/97 JMI Was not handling the case where the text was truncated by
- // an outside source. Now handled by calling ClipCaret() in
- // DrawText().
- //
- // 08/25/97 JMI Added macros to define extra space on each side of text
- // in the edit field to make sure it doesn't butt up against
- // stuff.
- // Also, effects, justification, size, and word-wrappage
- // were not being set before drawing the caret in Draw().
- //
- // 08/25/97 JMI Now scrolls half the field to the left if the caret
- // passes the left edge (used to only scroll one character).
- //
- // 08/30/97 JMI Now repaginates if the caret position is less than the
- // first visible character.
- //
- // 09/01/97 JMI Now Do() only functions if this is activated.
- //
- // 01/15/98 JMI Added numeric keypad support in Do().
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // This a GUI item that is based on the CTxt item.
- // This overrides CursorEvent() to get information about where a click it
- // occurred.
- // This overrides DrawText() to store the postion of each character.
- // This overrides Draw() to add a cursor.
- //
- // Enhancements/Uses:
- // To change the look of the text, you may want to override DrawText()
- // in a derived class or see CTxt for other overridables
- // To change the background of the text item, see CGuiItem.
- // To get a callback on a click/release pair in the text item, see CTxt.
- //
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Headers.
- //////////////////////////////////////////////////////////////////////////////
- #include <string.h>
- #include "Blue.h"
- #ifdef PATHS_IN_INCLUDES
- #include "ORANGE/GUI/edit.h"
- #else
- #include "edit.h"
- #endif // PATHS_IN_INCLUDES
- //////////////////////////////////////////////////////////////////////////////
- // Module specific macros.
- //////////////////////////////////////////////////////////////////////////////
- // Sets val to def if val is -1.
- #define DEF(val, def) ((val == -1) ? def : val)
- // Number of pixels to reserve as non-client on each vertical edge.
- #define VERT_EDGE_RESERVED 1
- #define EXTRA_NONCLIENT_EDGE (m_sShowFocus ? m_sBorderThickness + VERT_EDGE_RESERVED : VERT_EDGE_RESERVED)
- //////////////////////////////////////////////////////////////////////////////
- // Module specific typedefs.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Module specific (static) variables.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Construction/Destruction.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- //
- // Default constructor.
- //
- //////////////////////////////////////////////////////////////////////////////
- REdit::REdit()
- {
- ///////////////////////////////////////////////////////////////////////////
- // Defaults:
- ///////////////////////////////////////////////////////////////////////////
-
- m_cCaretChar = '_'; // Character to use as caret.
- m_u32CaretColor = 255; // Color to use for caret.
- m_sCaretPos = 0; // Text position of caret.
- m_lCaretBlinkRate = 500; // Rate at which character blinks in ms. Can be
- // 0 indicating no blinkage.
- m_sMaxText = GUI_MAX_STR; // Maximum text to allow. Limited to
- // GUI_MAX_STR.
- m_sBehavior = 0; // Flags. See enums in header.
- m_encCall = NULL; // Callback when a user input notification
- // should occur such as too much input or
- // invalid character generated (e.g., alphas
- // in NUMBERS_ONLY mode). A good place to
- // generate a beep or something.
- m_lNextCaretUpdate = 0; // Time in ms of next caret update.
- m_sCaretState = 0; // Current state the caret is in until
- // m_lNextCaretUpdate. (0 == hidden,
- // 1 == shown).
- m_sInvertedBorder = TRUE; // Override RGuiItem's default.
- m_type = Edit; // Indicates type of GUI item.
- m_sShowFocus = FALSE; // Focus is shown via the caret.
- m_sFirstVisibleCharIndex = 0; // First visible char in field.
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Destructor.
- //
- //////////////////////////////////////////////////////////////////////////////
- REdit::~REdit()
- {
- }
- ////////////////////////////////////////////////////////////////////////
- // Methods.
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- //
- // Draw this item and all its subitems into the provided RImage.
- // This override adds in the caret.
- //
- ////////////////////////////////////////////////////////////////////////
- short REdit::Draw( // Returns 0 on success.
- RImage* pimDst, // Destination image.
- short sDstX /*= 0*/, // X position in destination.
- short sDstY /*= 0*/, // Y position in destination.
- short sSrcX /*= 0*/, // X position in source.
- short sSrcY /*= 0*/, // Y position in source.
- short sW /*= 0*/, // Amount to draw.
- short sH /*= 0*/, // Amount to draw.
- RRect* prc /*= NULL*/) // Clip to.
- {
- short sRes = 0; // Assume success.
- // If visible . . .
- if (m_sVisible != FALSE)
- {
- // Call the base class.
- sRes = RGuiItem::Draw( pimDst, sDstX, sDstY,
- sSrcX, sSrcY, sW, sH, prc);
- // If the caret is shown . . .
- if (m_sCaretState != 0)
- {
- // Make sure the caret is inside the string.
- ClipCaret();
- // If the caret is less than the first visible index (this can happen
- // if an outside party sets the caret position) . . .
- if (m_sCaretPos < m_sFirstVisibleCharIndex)
- {
- // We'll need to 'repaginate' the field.
- Compose();
- }
- // Setup printer ////////////////////////////////
- // Word wrap must be off.
- short sWordWrapWas = (m_pprint->m_eModes & RPrint::WORD_WRAP) ? TRUE : FALSE;
- m_pprint->SetWordWrap(FALSE);
- // Text support is currently 8 bit only.
- m_pprint->SetColor((short)m_u32CaretColor, (short)0, (short)m_u32TextShadowColor);
- m_pprint->SetFont(m_sFontCellHeight);
- SetJustification();
- SetTextEffects();
- m_pprint->SetDestination(pimDst);
-
- // Done setting up printer //////////////////////
- short sClientX, sClientY, sClientW, sClientH;
- GetClient(&sClientX, &sClientY, &sClientW, &sClientH);
- short sClipW, sClipH;
- if (sW == 0)
- {
- // Use client.
- sClipW = sClientW;
- }
- else
- {
- // Adjust by blt position.
- sClipW = sW - (sClientX + m_sX);
- }
- if (sH == 0)
- {
- // Use client.
- sClipH = sClientH;
- }
- else
- {
- // Adjust by blt position.
- sClipH = sH - (sClientY + m_sY);
- }
- // Clip.
- m_pprint->SetColumn(
- sDstX + m_sX + sClientX + EXTRA_NONCLIENT_EDGE,
- sDstY + m_sY + sClientY,
- sClipW - EXTRA_NONCLIENT_EDGE * 2,
- sClipH);
- ASSERT(m_sCaretPos - m_sFirstVisibleCharIndex >= 0);
- m_pprint->print(
- sDstX + m_sX + m_aptTextPos[m_sCaretPos - m_sFirstVisibleCharIndex].sX,
- sDstY + m_sY + m_aptTextPos[m_sCaretPos - m_sFirstVisibleCharIndex].sY,
- "%c", m_cCaretChar);
- // Restore printer //////////////////////////////
- m_pprint->SetWordWrap(sWordWrapWas);
- }
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Draw text in m_szText in m_u32TextColor with transparent
- // background at sX, sY with sW and m_sJustification.
- // The only additional functionality this has over RGuiItem::DrawText is
- // that it blts the characters one at a time and tracks the position of
- // each character in m_aptTextPos.
- // If m_szText is empty, a space is printed with the foreground and
- // background colors set to transparent. This way, the array of
- // positions is set for the caret.
- //
- ////////////////////////////////////////////////////////////////////////
- short REdit::DrawText( // Returns 0 on success.
- short sX, // X position in image.
- short sY, // Y position in image.
- short sW /*= 0*/, // Width of text area.
- short sH /*= 0*/, // Height of test area.
- RImage* pim /*= NULL*/) // Destination image. NULL == use m_im.
- {
- short sRes = 0; // Assume success.
- if (pim == NULL)
- {
- // Use internal image.
- pim = &m_im;
- }
- char* pszText;
- U32 u32ForeColor;
- if (m_szText[0] != '\0')
- {
- // Use user supplied text.
- pszText = m_szText;
- // Use user supplied color.
- u32ForeColor = m_u32TextColor;
- }
- else
- {
- // Use fake text and colors so that the positions
- // array is updated. It would be handy if the
- // print command would update the array even for
- // printing "". Then this would not be necessary.
- static char szSpace[] = " ";
- // Display space so that we can guarantee that the
- // character positions array will be updated.
- pszText = szSpace;
- // Use transparent color (just in case actually has
- // some pixels).
- u32ForeColor = 0;
- }
- // Text support is currently 8 bit only.
- m_pprint->SetColor(u32ForeColor, 0, m_u32TextShadowColor);
-
- // Set size. Hopefully this won't do too much scaling for
- // caching purposes but I'm not sure.
- m_pprint->SetFont(m_sFontCellHeight);
- // Only left justified editting supported . . .
- if (m_justification == RGuiItem::Left)
- {
- // Added in extra space before starting text.
- sX += EXTRA_NONCLIENT_EDGE;
- // Remove extra space before starting text.
- sW -= EXTRA_NONCLIENT_EDGE * 2;
- // Keep the caret within bounds.
- ClipCaret();
- SetJustification();
- SetTextEffects();
- // Word wrap must be off.
- short sWordWrapWas = (m_pprint->m_eModes & RPrint::WORD_WRAP) ? TRUE : FALSE;
- m_pprint->SetWordWrap(FALSE);
- m_pprint->SetDestination(pim);
- m_pprint->SetColumn(sX, sY, sW, sH);
- m_pprint->GetWidth(pszText);
- long lLen = strlen(pszText);
- // Whenever the caret hits or passes the left edge, jump the first visible
- // character back.
- if (m_sCaretPos < m_sFirstVisibleCharIndex)
- {
- short sHalfWidth = sW / 2;
- // Go backward until we hit the beginning
- // or we get within half the field of the caret.
- while (m_sFirstVisibleCharIndex > 0)
- {
- if (m_pprint->ms_sCharPosX[m_sCaretPos] - m_pprint->ms_sCharPosX[m_sFirstVisibleCharIndex] >= sHalfWidth)
- {
- break;
- }
- m_sFirstVisibleCharIndex--;
- }
- }
- short sCaretWidth = m_pprint->GetBlitW(m_cCaretChar);
- // Whenever the caret hits or passes the right edge, jump the first
- // visible character forward.
- if (m_pprint->ms_sCharPosX[m_sCaretPos] - m_pprint->ms_sCharPosX[m_sFirstVisibleCharIndex] + sCaretWidth >= sW - EXTRA_NONCLIENT_EDGE)
- {
- short sHalfWidth = sW / 2;
- // Go forward until we hit the end
- // or we get within half the field of the caret.
- while (m_sFirstVisibleCharIndex < lLen)
- {
- if (m_pprint->ms_sCharPosX[m_sCaretPos] - m_pprint->ms_sCharPosX[m_sFirstVisibleCharIndex] <= sHalfWidth)
- {
- break;
- }
- m_sFirstVisibleCharIndex++;
- }
- }
- ASSERT(m_sFirstVisibleCharIndex <= lLen);
- ASSERT(m_sFirstVisibleCharIndex >= 0);
- m_pprint->print(sX, sY, "%s", pszText + m_sFirstVisibleCharIndex);
-
- REdit::Point* ppt = m_aptTextPos;
- long lIndex;
- for (lIndex = 0; lIndex < lLen; lIndex++, ppt++)
- {
- // Store its position in the pim.
- ppt->sX = m_pprint->ms_sCharPosX[lIndex];
- ppt->sY = sY; // Eventually will be available as above.
- }
- // Update last position for cursor.
- ppt->sX = m_pprint->ms_sCharPosX[lIndex];
- ppt->sY = sY; // Eventually will be available as above.
- m_pprint->SetWordWrap(sWordWrapWas);
- }
- else
- {
- TRACE("DrawText(): Only left justification supported by REdit "
- "currently.\n");
- sRes = -1;
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Does REdit stuff like check for keys, update caret, and add new
- // text.
- //
- ////////////////////////////////////////////////////////////////////////
- void REdit::Do( // Returns nothing.
- RInputEvent* pie) // In: Most recent user input event.
- // Out: pie->sUsed = TRUE, if used.
- {
- // Call base.
- RTxt::Do(pie);
- // Only if currenly active . . .
- if (IsActivated() != FALSE)
- {
- short sRedrawText = FALSE; // Redraw text if TRUE.
- short sRedrawItem = FALSE; // Redraw item if TRUE (for event driven
- // user).
-
- // If unused key event . . .
- if (pie->sUsed == FALSE && pie->type == RInputEvent::Key)
- {
- // Set the caret state to show.
- m_sCaretState = 1;
- // Get length of current text. Always handy.
- long lStrLen = strlen(m_szText);
- // Remember caret position.
- short sCaretPosIn = m_sCaretPos;
- // Char to add or 0.
- long lNewChar = 0;
- // Make sure the caret is inside the string.
- ClipCaret();
- // Switch on extended keys.
- switch (pie->lKey & 0x0000FF00)
- {
- case 0x00000000: // ASCII key.
- // Switch on ASCII key.
- switch (pie->lKey & 0x000000FF)
- {
- case '\b':
- if (m_sCaretPos > 0)
- {
- // Remove character at cursor.
- memmove( m_szText + m_sCaretPos - 1,
- m_szText + m_sCaretPos,
- lStrLen - m_sCaretPos + 1);
-
- m_sCaretPos--;
- // Need to redraw text.
- sRedrawText = TRUE;
- }
- else
- {
- NotifyCall();
- }
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case '\r':
- if (m_sBehavior & REdit::Multiline)
- {
- TRACE("Do(): REdit::Multiline NYI.\n");
- NotifyCall();
- // Absorb key.
- pie->sUsed = TRUE;
- }
- break;
- // Keys we don't want to process.
- case '\t':
- case 27:
- break;
- default:
- lNewChar = pie->lKey;
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- }
- break;
- // Numpad numeric keys.
- case RSP_GK_NUMPAD_0:
- case RSP_GK_NUMPAD_1:
- case RSP_GK_NUMPAD_2:
- case RSP_GK_NUMPAD_3:
- case RSP_GK_NUMPAD_4:
- case RSP_GK_NUMPAD_5:
- case RSP_GK_NUMPAD_6:
- case RSP_GK_NUMPAD_7:
- case RSP_GK_NUMPAD_8:
- case RSP_GK_NUMPAD_9:
- lNewChar = '0' + ( (pie->lKey - RSP_GK_NUMPAD_0) >> 8);
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- // Numpad other keys.
- // NOTE: This is essentially a table so, if it gets too large, let's use a real table
- // instead. Maybe there should be a function.
- case RSP_GK_NUMPAD_ASTERISK:
- lNewChar = '*';
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_NUMPAD_PLUS :
- lNewChar = '+';
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_NUMPAD_MINUS :
- lNewChar = '-';
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_NUMPAD_DECIMAL :
- lNewChar = '.';
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_NUMPAD_DIVIDE :
- lNewChar = '/';
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- // Single line caret movement.
- case RSP_GK_LEFT:
- if (m_sCaretPos > 0)
- {
- m_sCaretPos--;
- }
- else
- {
- NotifyCall();
- }
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_RIGHT:
- if (m_sCaretPos < lStrLen)
- {
- m_sCaretPos++;
- }
- else
- {
- NotifyCall();
- }
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_DELETE:
- if (m_sCaretPos < lStrLen)
- {
- // Remove character at cursor.
- memmove( m_szText + m_sCaretPos,
- m_szText + m_sCaretPos + 1,
- lStrLen - m_sCaretPos);
-
- // Need to redraw text.
- sRedrawText = TRUE;
- }
- else
- {
- NotifyCall();
- }
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_HOME:
- m_sCaretPos = 0;
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_END:
- m_sCaretPos = (short)lStrLen;
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- // Multiline caret movement.
- case RSP_GK_UP:
- if (m_sBehavior & REdit::Multiline)
- {
- TRACE("Do(): REdit::Multiline NYI.\n");
- NotifyCall();
- }
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- case RSP_GK_DOWN:
- if (m_sBehavior & REdit::Multiline)
- {
- TRACE("Do(): REdit::Multiline NYI.\n");
- NotifyCall();
- }
- // Absorb key.
- pie->sUsed = TRUE;
- break;
- }
- // If we should add a key . . .
- if (lNewChar)
- {
- if (lStrLen < m_sMaxText - 1)
- {
- // Add character to string.
- // Move existing characters (perhaps only '\0')
- // out of the way.
- memmove( m_szText + m_sCaretPos + 1,
- m_szText + m_sCaretPos,
- lStrLen - m_sCaretPos + 1);
- // Place character and advance caret position.
- m_szText[m_sCaretPos++] = (char)lNewChar;
- // Need to redraw text.
- sRedrawText = TRUE;
- }
- else
- {
- NotifyCall();
- }
- }
- // If change in caret pos . . .
- if (m_sCaretPos != sCaretPosIn)
- {
- // We must make sure the caret is visible.
- Compose();
- sRedrawItem = TRUE;
- }
- }
- if (m_lCaretBlinkRate != 0)
- {
- // If the next blink time has expired . . .
- long lCurTime = rspGetMilliseconds();
- if (lCurTime >= m_lNextCaretUpdate)
- {
- // Set next blink time.
- m_lNextCaretUpdate = lCurTime + m_lCaretBlinkRate;
- // If caret is to be shown . . .
- if (m_sCaretState == 1)
- {
- // Set caret state.
- m_sCaretState = 0;
- }
- else
- {
- // Set caret state.
- m_sCaretState = 1;
- }
- // Redraw needed.
- sRedrawItem = TRUE;
- }
- }
- else
- {
- m_sCaretState = 1;
- }
- // If we need to redraw the text . . .
- if (sRedrawText != FALSE)
- {
- // Recompose the item.
- Compose();
- sRedrawItem = TRUE;
- }
- // If a redraw is necessary . . .
- if (sRedrawItem != FALSE)
- {
- // Cause a redraw for the event driven user.
- Redraw();
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Cursor event notification.
- // Events in event area.
- // (virtual).
- //
- ////////////////////////////////////////////////////////////////////////
- void REdit::CursorEvent( // Returns nothing.
- RInputEvent* pie) // In: Most recent user input event.
- // Out: pie->sUsed = TRUE, if used.
- {
- RGuiItem::CursorEvent(pie);
- switch (pie->sEvent)
- {
- case RSP_MB0_DOUBLECLICK:
- case RSP_MB0_RELEASED:
- {
- // Set the caret position based on the area clicked.
- char* pszText = m_szText;
- Point* ppt = m_aptTextPos;
- m_sCaretPos = m_sFirstVisibleCharIndex;
- short sCellH = m_sFontCellHeight;
- // Adjust sPosY to bottom of line.
- short sPosY = pie->sPosY + sCellH;
- while (*pszText++ != '\0')
- {
- if (ppt->sX < pie->sPosX && ppt->sY < sPosY)
- {
- m_sCaretPos++;
- ppt++;
- }
- else
- {
- break;
- }
- }
- // Make sure it gets shown.
- m_lNextCaretUpdate = 0L;
- m_sCaretState = 0;
- // Note that we used it.
- pie->sUsed = TRUE;
- break;
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////
- // Internal.
- ////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////
- //
- // Read item's members from file.
- // (virtual/protected (overriden here)).
- //
- ////////////////////////////////////////////////////////////////////////
- short REdit::ReadMembers( // Returns 0 on success.
- RFile* pfile, // File to read from.
- U32 u32Version) // File format version to use.
- {
- short sRes = 0; // Assume success.
- // Invoke base class to read base members.
- sRes = RTxt::ReadMembers(pfile, u32Version);
- // If okay so far . . .
- if (sRes == 0)
- {
- ASSERT(pfile != NULL);
- ASSERT(pfile->IsOpen() != FALSE);
-
- // Switch on version.
- switch (u32Version)
- {
- default:
- // Insert additional version numbers here!
- // case 4: // Version 4 stuff.
- // case 3: // Version 3 stuff.
- case 2: // Version 2 stuff.
- case 1:
- // Read this class's members.
- pfile->Read(&m_cCaretChar);
- pfile->Read(&m_u32CaretColor);
- pfile->Read(&m_lCaretBlinkRate);
- pfile->Read(&m_sMaxText);
- pfile->Read(&m_sBehavior);
- case 0: // In version 0, only base class RGuiItem members were stored.
- // If successful . . .
- if (pfile->Error() == FALSE)
- {
- // Success.
- }
- else
- {
- TRACE("ReadMembers(): Error reading REdit members.\n");
- sRes = -1;
- }
- break;
- }
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////
- //
- // Write item's members to file.
- // (virtual/protected (overriden here)).
- //
- ////////////////////////////////////////////////////////////////////////
- short REdit::WriteMembers( // Returns 0 on success.
- RFile* pfile) // File to write to.
- {
- short sRes = 0; // Assume success.
- // Invoke base class to read base members.
- sRes = RTxt::WriteMembers(pfile);
- // If okay so far . . .
- if (sRes == 0)
- {
- ASSERT(pfile != NULL);
- ASSERT(pfile->IsOpen() != FALSE);
-
- // Write this class's members.
- pfile->Write(&m_cCaretChar);
- pfile->Write(&m_u32CaretColor);
- pfile->Write(&m_lCaretBlinkRate);
- pfile->Write(&m_sMaxText);
- pfile->Write(&m_sBehavior);
- // If successful . . .
- if (pfile->Error() == FALSE)
- {
- // Success.
- }
- else
- {
- TRACE("WriteMembers(): Error writing REdit members.\n");
- sRes = -1;
- }
- }
- return sRes;
- }
- ////////////////////////////////////////////////////////////////////////
- // Clips the caret to within the string length.
- ////////////////////////////////////////////////////////////////////////
- void REdit::ClipCaret(void) // Returns nothing.
- {
- long lLen = strlen(m_szText);
- if (m_sCaretPos > lLen)
- {
- // After last char.
- m_sCaretPos = (short)lLen;
- }
- }
- ////////////////////////////////////////////////////////////////////////
- // Querries.
- ////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // EOF
- //////////////////////////////////////////////////////////////////////////////
|