diff --git a/src/kits/interface/BTextView/InlineInput.cpp b/src/kits/interface/BTextView/InlineInput.cpp index 68454002a2..d02eec26a5 100644 --- a/src/kits/interface/BTextView/InlineInput.cpp +++ b/src/kits/interface/BTextView/InlineInput.cpp @@ -1,19 +1,59 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2003-2004, Haiku, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: InlineInput.cpp +// Author: Stefano Ceccherini (burton666@libero.it) +// Description: Helper class to handle input method requests +//------------------------------------------------------------------------------ #include "InlineInput.h" #include +struct clause +{ + int32 start; + int32 end; +}; + + +/*! \brief Constructs a _BInlineInput_ object. + \param messenger The BMessenger of the input server method addon. +*/ _BInlineInput_::_BInlineInput_(BMessenger messenger) : fMessenger(messenger), fActive(false), fOffset(0), - fLength(0) + fLength(0), + fNumClauses(0), + fClauses(NULL) { } +/*! \brief Destructs the object, free the allocated memory. +*/ _BInlineInput_::~_BInlineInput_() { + ResetClauses(); } @@ -41,6 +81,8 @@ _BInlineInput_::SetActive(bool active) } +/*! \brief Return the length of the inputted text. +*/ int32 _BInlineInput_::Length() const { @@ -48,6 +90,10 @@ _BInlineInput_::Length() const } +/*! \brief Sets the length of the text inputted with the input method. + \param len The length of the text, extracted from the + B_INPUT_METHOD_CHANGED BMessage. +*/ void _BInlineInput_::SetLength(int32 len) { @@ -55,6 +101,8 @@ _BInlineInput_::SetLength(int32 len) } +/*! \brief Returns the offset into the BTextView of the text. +*/ int32 _BInlineInput_::Offset() const { @@ -62,8 +110,58 @@ _BInlineInput_::Offset() const } +/*! \brief Sets the offset into the BTextView of the text. + \param offset The offset where the text has been inserted. +*/ void _BInlineInput_::SetOffset(int32 offset) { fOffset = offset; } + + +/*! \brief Adds a clause (see "The Input Server" sez. for details). + \param start The offset into the string where the clause starts. + \param end The offset into the string where the clause finishes. +*/ +void +_BInlineInput_::AddClause(int32 start, int32 end) +{ + fClauses = (clause *)realloc(fClauses, ++fNumClauses * sizeof(clause)); + fClauses[fNumClauses - 1].start = start; + fClauses[fNumClauses - 1].end = end; +} + + +/*! \brief Gets the clause at the given index. + \param index The index of the clause to get. + \param start A pointer to an integer which will contain the clause's start offset. + \param end A pointer to an integer which will contain the clause's end offset. + \return \c true if the clause exists, \c false if not. +*/ +bool +_BInlineInput_::GetClause(int32 index, int32 *start, int32 *end) const +{ + bool result = false; + if (index >= 0 && index < fNumClauses) { + result = true; + clause *clause = &fClauses[index]; + if (start) + *start = clause->start; + if (end) + *end = clause->end; + } + + return result; +} + + +/*! \brief Deletes any added clause. +*/ +void +_BInlineInput_::ResetClauses() +{ + fNumClauses = 0; + free(fClauses); + fClauses = NULL; +} diff --git a/src/kits/interface/BTextView/InlineInput.h b/src/kits/interface/BTextView/InlineInput.h index 31f1e1ba68..8ec630a2c5 100644 --- a/src/kits/interface/BTextView/InlineInput.h +++ b/src/kits/interface/BTextView/InlineInput.h @@ -1,8 +1,34 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2003-2004, Haiku, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: InlineInput.h +// Author: Stefano Ceccherini (burton666@libero.it) +// Description: Helper class to handle input method requests +//------------------------------------------------------------------------------ #ifndef __INLINEINPUT_H #define __INLINEINPUT_H #include +struct clause; class _BInlineInput_ { public: _BInlineInput_(BMessenger); @@ -19,6 +45,11 @@ public: int32 Offset() const; void SetOffset(int32 offset); + void AddClause(int32, int32); + bool GetClause(int32 index, int32 *start, int32 *end) const; + + void ResetClauses(); + private: const BMessenger fMessenger; @@ -26,6 +57,9 @@ private: int32 fOffset; int32 fLength; + + int32 fNumClauses; + clause *fClauses; }; #endif //__INLINEINPUT_H diff --git a/src/kits/interface/BTextView/TextView.cpp b/src/kits/interface/BTextView/TextView.cpp index 473fb78754..acdad04637 100644 --- a/src/kits/interface/BTextView/TextView.cpp +++ b/src/kits/interface/BTextView/TextView.cpp @@ -1610,8 +1610,6 @@ BTextView::SetFontAndColor(int32 startOffset, int32 endOffset, const rgb_color *inColor) { CALLED(); - printf("SetFontAndColor(%ld, %ld, %p, mode: 0x%x, %p)\n", - startOffset, endOffset, inFont, inMode, inColor); // hide the caret/unhilite the selection if (fActive) { if (startOffset != endOffset) @@ -3551,7 +3549,6 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset, { // TODO: Draw on the "fOffscreen" BBitmap, then draw it on the view - CALLED(); // clip the text BRect clipRect = Bounds() & fTextRect; clipRect.InsetBy(-1, -1); @@ -3635,28 +3632,30 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset, } } - // TODO: Revisit this as it isn't working so good, and it looks ugly + // TODO: Revisit this as it looks ugly // and add clauses support (red highlighing) - if (fInline && fInline->IsActive() && (fInline->Offset() >= offset - && fInline->Offset() + fInline->Length() <= offset + length)) { - float height; - BPoint leftTop = PointAt(fInline->Offset(), &height); - BPoint rightBottom = PointAt(fInline->Offset() + fInline->Length()); - rightBottom.y += height; - BRect rect(leftTop, rightBottom); - - PushState(); - - rgb_color blue = {152, 203, 255}; - //rgb_color red = {255, 152, 152}; - SetHighColor(blue); - SetLowColor(blue); - FillRect(rect); - - PopState(); + if (fInline && fInline->IsActive()) { + int32 inlineOffset = fInline->Offset(); + int32 inlineLength = fInline->Length(); + if (inlineOffset >= offset && + inlineOffset + inlineLength <= offset + length) { + float height; + BPoint rightBottom = PointAt(inlineOffset + inlineLength, &height); + rightBottom.y += height; + BRect rect(PointAt(inlineOffset), rightBottom); + + PushState(); + + rgb_color blue = {152, 203, 255}; + //rgb_color red = {255, 152, 152}; + SetHighColor(blue); + SetLowColor(blue); + FillRect(rect); + + PopState(); + } } - DrawString(fText->GetString(offset, tabChars), tabChars); if (foundTab) { @@ -3693,7 +3692,6 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset, } ConstrainClippingRegion(NULL); - Flush(); } @@ -4275,17 +4273,37 @@ BTextView::HandleInputMethodChanged(BMessage *message) fInline->SetOffset(fSelStart); fInline->SetLength(stringLen); + fInline->ResetClauses(); + + // Get the clauses, and pass them to the _BInlineInput_ object + int32 clauseCount = 0; + int32 clauseStart; + int32 clauseEnd; + while (message->FindInt32("be:clause_start", clauseCount, &clauseStart) == B_OK && + message->FindInt32("be:clause_end", clauseCount, &clauseEnd) == B_OK) { + fInline->AddClause(clauseStart, clauseEnd); + clauseCount++; + } + + int32 selCount = 0; + int32 selection; + while (message->FindInt32("be:selection", selCount, &selection) == B_OK) { + // TODO: Do something with the selection + selCount++; + } + + if (clauseCount > 0) { + // Insert the new text + InsertText(string, stringLen, fSelStart, NULL); + fSelStart += stringLen; + fClickOffset = fSelEnd = fSelStart; + } - // Insert the new text - InsertText(string, stringLen, fSelStart, NULL); - fSelStart += stringLen; - fClickOffset = fSelEnd = fSelStart; - // If we find the "be:confirmed" boolean (and the boolean is true), // it means it's over for now, so the current _BInlineInput_ object // should become inactive bool confirmed = false; - if (message->FindBool("be:confirmed", &confirmed) != B_OK || !confirmed) + if (message->FindBool("be:confirmed", &confirmed) < B_OK || !confirmed) fInline->SetActive(true); else fInline->SetActive(false);