Inline input method handling for BTextView (still lacks the blue/red highlighting). Thanks to Andrew and Koki for the hints.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8431 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2004-07-19 14:38:35 +00:00
parent 3b3b8f4460
commit 6adf049cfa
6 changed files with 229 additions and 26 deletions
@@ -0,0 +1,69 @@
#include "InlineInput.h"
#include <cstdlib>
_BInlineInput_::_BInlineInput_(BMessenger messenger)
:
fMessenger(messenger),
fActive(false),
fOffset(0),
fLength(0)
{
}
_BInlineInput_::~_BInlineInput_()
{
}
/*! \brief Returns a pointer to the Input Server Method BMessenger
which requested the transaction.
*/
const BMessenger *
_BInlineInput_::Method() const
{
return &fMessenger;
}
bool
_BInlineInput_::IsActive() const
{
return fActive;
}
void
_BInlineInput_::SetActive(bool active)
{
fActive = active;
}
int32
_BInlineInput_::Length() const
{
return fLength;
}
void
_BInlineInput_::SetLength(int32 len)
{
fLength = len;
}
int32
_BInlineInput_::Offset() const
{
return fOffset;
}
void
_BInlineInput_::SetOffset(int32 offset)
{
fOffset = offset;
}
@@ -0,0 +1,31 @@
#ifndef __INLINEINPUT_H
#define __INLINEINPUT_H
#include <Messenger.h>
class _BInlineInput_ {
public:
_BInlineInput_(BMessenger);
~_BInlineInput_();
const BMessenger *Method() const;
bool IsActive() const;
void SetActive(bool active);
int32 Length() const;
void SetLength(int32 length);
int32 Offset() const;
void SetOffset(int32 offset);
private:
const BMessenger fMessenger;
bool fActive;
int32 fOffset;
int32 fLength;
};
#endif //__INLINEINPUT_H
+1
View File
@@ -3,6 +3,7 @@ SubDir OBOS_TOP src kits interface BTextView ;
UsePrivateHeaders interface ; UsePrivateHeaders interface ;
StaticLibrary haiku : StaticLibrary haiku :
InlineInput.cpp
LineBuffer.cpp LineBuffer.cpp
StyleBuffer.cpp StyleBuffer.cpp
TextGapBuffer.cpp TextGapBuffer.cpp
+2 -1
View File
@@ -27,6 +27,7 @@
// Standard Includes ----------------------------------------------------------- // Standard Includes -----------------------------------------------------------
// System Includes ------------------------------------------------------------- // System Includes -------------------------------------------------------------
#include "InlineInput.h"
#include "StyleBuffer.h" #include "StyleBuffer.h"
// Project Includes ------------------------------------------------------------ // Project Includes ------------------------------------------------------------
@@ -479,7 +480,7 @@ _BStyleBuffer_::RemoveStyles(int32 index, int32 count)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int32 int32
_BStyleBuffer_::Iterate(int32 fromOffset, int32 length, /*_BInlineInput_ *,*/ _BStyleBuffer_::Iterate(int32 fromOffset, int32 length, _BInlineInput_ *input,
const BFont **outFont, const rgb_color **outColor, const BFont **outFont, const rgb_color **outColor,
float *outAscent, float *outDescent, uint32 *) const float *outAscent, float *outDescent, uint32 *) const
{ {
+2 -1
View File
@@ -122,6 +122,7 @@ STEStyleRecordPtr _BStyleRecordBuffer_::operator[](int32 index) const
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class _BInlineInput_;
// _BStyleBuffer_ class -------------------------------------------------------- // _BStyleBuffer_ class --------------------------------------------------------
class _BStyleBuffer_ { class _BStyleBuffer_ {
@@ -150,7 +151,7 @@ public:
void RemoveStyleRange(int32 fromOffset, int32 toOffset); void RemoveStyleRange(int32 fromOffset, int32 toOffset);
void RemoveStyles(int32 index, int32 count = 1); void RemoveStyles(int32 index, int32 count = 1);
int32 Iterate(int32 fromOffset, int32 length, /*_BInlineInput_ *,*/ int32 Iterate(int32 fromOffset, int32 length, _BInlineInput_ *,
const BFont **outFont = NULL, const BFont **outFont = NULL,
const rgb_color **outColor = NULL, const rgb_color **outColor = NULL,
float *outAscent = NULL, float *outAscent = NULL,
+122 -22
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2004, Haiku // Copyright (c) 2001-2004, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@@ -28,9 +28,9 @@
// TODO: // TODO:
// - Finish documenting this class // - Finish documenting this class
// - Consider using _PointerList_/BObjectList instead of BList // - Consider using BObjectList instead of BList
// for disallowed charachters (it would remove a lot of reinterpret_casts) // for disallowed charachters (it would remove a lot of reinterpret_casts)
// - Asynchronous mouse tracking
// Standard Includes ----------------------------------------------------------- // Standard Includes -----------------------------------------------------------
#include <cstdlib> #include <cstdlib>
@@ -41,6 +41,7 @@
#include <Beep.h> #include <Beep.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <Clipboard.h> #include <Clipboard.h>
#include <Debug.h>
#include <Errors.h> #include <Errors.h>
#include <Input.h> #include <Input.h>
#include <Message.h> #include <Message.h>
@@ -51,6 +52,7 @@
#include <Window.h> #include <Window.h>
// Local Includes -------------------------------------------------------------- // Local Includes --------------------------------------------------------------
#include "InlineInput.h"
#include "LineBuffer.h" #include "LineBuffer.h"
#include "StyleBuffer.h" #include "StyleBuffer.h"
#include "TextGapBuffer.h" #include "TextGapBuffer.h"
@@ -431,6 +433,8 @@ BTextView::MouseDown(BPoint where)
if (!fEditable && !fSelectable) if (!fEditable && !fSelectable)
return; return;
CancelInputMethod();
if (!IsFocus()) if (!IsFocus())
MakeFocus(); MakeFocus();
@@ -819,23 +823,27 @@ BTextView::MessageReceived(BMessage *message)
switch (opcode) { switch (opcode) {
case B_INPUT_METHOD_STARTED: case B_INPUT_METHOD_STARTED:
{ {
printf("B_INPUT_METHOD_STARTED\n"); BMessenger messenger;
if (message->FindMessenger("be:reply_to", &messenger) == B_OK) {
ASSERT(fInline == NULL);
fInline = new _BInlineInput_(messenger);
}
break; break;
} }
case B_INPUT_METHOD_STOPPED: case B_INPUT_METHOD_STOPPED:
{ {
printf("B_INPUT_METHOD_STOPPED\n"); delete fInline;
fInline = NULL;
break; break;
} }
case B_INPUT_METHOD_CHANGED: case B_INPUT_METHOD_CHANGED:
printf("B_INPUT_METHOD_CHANGED\n");
HandleInputMethodChanged(message); HandleInputMethodChanged(message);
break; break;
case B_INPUT_METHOD_LOCATION_REQUEST: case B_INPUT_METHOD_LOCATION_REQUEST:
printf("B_INPUT_METHOD_LOCATION_REQUEST\n");
HandleInputMethodLocationRequest(); HandleInputMethodLocationRequest();
break; break;
@@ -969,6 +977,9 @@ void
BTextView::SetText(const char *inText, const text_run_array *inRuns) BTextView::SetText(const char *inText, const text_run_array *inRuns)
{ {
CALLED(); CALLED();
CancelInputMethod();
// hide the caret/unhilite the selection // hide the caret/unhilite the selection
if (fActive) { if (fActive) {
if (fSelStart != fSelEnd) if (fSelStart != fSelEnd)
@@ -1005,6 +1016,9 @@ BTextView::SetText(const char *inText, int32 inLength,
const text_run_array *inRuns) const text_run_array *inRuns)
{ {
CALLED(); CALLED();
CancelInputMethod();
// hide the caret/unhilite the selection // hide the caret/unhilite the selection
if (fActive) { if (fActive) {
if (fSelStart != fSelEnd) if (fSelStart != fSelEnd)
@@ -1039,7 +1053,11 @@ BTextView::SetText(BFile *inFile, int32 inOffset, int32 inLength,
const text_run_array *inRuns) const text_run_array *inRuns)
{ {
CALLED(); CALLED();
// TODO: Should probably call _DoDeleteText() here
CancelInputMethod();
// TODO: Should probably call _DoDeleteText() here, as the bebook
// says this function doesn't dall DeleteText()
if (fText->Length() > 0) if (fText->Length() > 0)
DeleteText(0, fText->Length()); DeleteText(0, fText->Length());
@@ -1093,6 +1111,9 @@ BTextView::Insert(int32 startOffset, const char *inText, int32 inLength,
const text_run_array *inRuns) const text_run_array *inRuns)
{ {
CALLED(); CALLED();
CancelInputMethod();
// do we really need to do anything? // do we really need to do anything?
if (inLength < 1) if (inLength < 1)
return; return;
@@ -1139,6 +1160,9 @@ void
BTextView::Delete() BTextView::Delete()
{ {
CALLED(); CALLED();
CancelInputMethod();
// anything to delete? // anything to delete?
if (fSelStart == fSelEnd) if (fSelStart == fSelEnd)
return; return;
@@ -1230,8 +1254,7 @@ BTextView::TextLength() const
CALLED(); CALLED();
return fText->Length(); return fText->Length();
} }
//------------------------------------------------------------------------------
void void
BTextView::GetText(int32 offset, int32 length, char *buffer) const BTextView::GetText(int32 offset, int32 length, char *buffer) const
{ {
@@ -1280,6 +1303,7 @@ void
BTextView::GoToLine(int32 index) BTextView::GoToLine(int32 index)
{ {
CALLED(); CALLED();
CancelInputMethod();
fSelStart = fSelEnd = OffsetAt(index); fSelStart = fSelEnd = OffsetAt(index);
} }
@@ -1291,6 +1315,7 @@ void
BTextView::Cut(BClipboard *clipboard) BTextView::Cut(BClipboard *clipboard)
{ {
CALLED(); CALLED();
CancelInputMethod();
if (fUndo) { if (fUndo) {
delete fUndo; delete fUndo;
fUndo = new _BCutUndoBuffer_(this); fUndo = new _BCutUndoBuffer_(this);
@@ -1307,6 +1332,9 @@ void
BTextView::Copy(BClipboard *clipboard) BTextView::Copy(BClipboard *clipboard)
{ {
CALLED(); CALLED();
CancelInputMethod();
BMessage *clip = NULL; BMessage *clip = NULL;
if (clipboard->Lock()) { if (clipboard->Lock()) {
@@ -1337,6 +1365,8 @@ void
BTextView::Paste(BClipboard *clipboard) BTextView::Paste(BClipboard *clipboard)
{ {
CALLED(); CALLED();
CancelInputMethod();
BMessage *clip = NULL; BMessage *clip = NULL;
if (clipboard->Lock()) { if (clipboard->Lock()) {
@@ -1513,6 +1543,8 @@ BTextView::SetFontAndColor(const BFont *inFont, uint32 inMode,
const rgb_color *inColor) const rgb_color *inColor)
{ {
CALLED(); CALLED();
CancelInputMethod();
// hide the caret/unhilite the selection // hide the caret/unhilite the selection
if (fActive) { if (fActive) {
if (fSelStart != fSelEnd) if (fSelStart != fSelEnd)
@@ -1619,6 +1651,9 @@ BTextView::SetRunArray(int32 startOffset, int32 endOffset,
const text_run_array *inRuns) const text_run_array *inRuns)
{ {
CALLED(); CALLED();
CancelInputMethod();
// pin offsets at reasonable values // pin offsets at reasonable values
startOffset = (startOffset < 0) ? 0 : startOffset; startOffset = (startOffset < 0) ? 0 : startOffset;
endOffset = (endOffset < 0) ? 0 : endOffset; endOffset = (endOffset < 0) ? 0 : endOffset;
@@ -2187,10 +2222,11 @@ BTextView::MakeEditable(bool editable)
fEditable = editable; fEditable = editable;
if (Window() != NULL) { if (Window() != NULL && fActive) {
if (fActive) { if (!fEditable) {
if (!fEditable && fCaretVisible) if (fCaretVisible)
InvertCaret(); InvertCaret();
CancelInputMethod();
} }
} }
} }
@@ -3101,7 +3137,7 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
if (fromOffset >= limit) { if (fromOffset >= limit) {
// try to return valid height info anyway // try to return valid height info anyway
if (fStyles->NumRuns() > 0) if (fStyles->NumRuns() > 0)
fStyles->Iterate(fromOffset, 1, NULL, NULL, outAscent, outDescent); fStyles->Iterate(fromOffset, 1, fInline, NULL, NULL, outAscent, outDescent);
else { else {
if (fStyles->IsValidNullStyle()) { if (fStyles->IsValidNullStyle()) {
const BFont *font = NULL; const BFont *font = NULL;
@@ -3137,7 +3173,7 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
int32 length = offset; int32 length = offset;
int32 startOffset = fromOffset; int32 startOffset = fromOffset;
int32 numChars; int32 numChars;
while ((numChars = fStyles->Iterate(startOffset, length, NULL, NULL, &ascent, &descent)) != 0) { while ((numChars = fStyles->Iterate(startOffset, length, fInline, NULL, NULL, &ascent, &descent)) != 0) {
*outAscent = max_c(ascent, *outAscent); *outAscent = max_c(ascent, *outAscent);
*outDescent = max_c(descent, *outDescent); *outDescent = max_c(descent, *outDescent);
@@ -3290,7 +3326,7 @@ BTextView::StyledWidth(int32 fromOffset, int32 length, float *outAscent,
// iterate through the style runs // iterate through the style runs
const BFont *font = NULL; const BFont *font = NULL;
int32 numChars; int32 numChars;
while ((numChars = fStyles->Iterate(fromOffset, length, &font, NULL, &ascent, &descent)) != 0) { while ((numChars = fStyles->Iterate(fromOffset, length, fInline, &font, NULL, &ascent, &descent)) != 0) {
maxAscent = max_c(ascent, maxAscent); maxAscent = max_c(ascent, maxAscent);
maxDescent = max_c(descent, maxDescent); maxDescent = max_c(descent, maxDescent);
@@ -3408,7 +3444,7 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
const BFont *font = NULL; const BFont *font = NULL;
const rgb_color *color = NULL; const rgb_color *color = NULL;
int32 numChars; int32 numChars;
while ((numChars = fStyles->Iterate(offset, length, &font, &color)) != 0) { while ((numChars = fStyles->Iterate(offset, length, fInline, &font, &color)) != 0) {
SetFont(font); SetFont(font);
SetHighColor(*color); SetHighColor(*color);
@@ -3795,6 +3831,8 @@ BTextView::Deactivate()
CALLED(); CALLED();
fActive = false; fActive = false;
CancelInputMethod();
if (fSelStart != fSelEnd) { if (fSelStart != fSelEnd) {
if (fSelectable) if (fSelectable)
Highlight(fSelStart, fSelEnd); Highlight(fSelStart, fSelEnd);
@@ -3837,7 +3875,7 @@ uint32
BTextView::CharClassification(int32 offset) const BTextView::CharClassification(int32 offset) const
{ {
CALLED(); CALLED();
// Should check against a list of character containing also // Should check against a list of characters containing also
// japanese word breakers // japanese word breakers
switch (fText->RealCharAt(offset)) { switch (fText->RealCharAt(offset)) {
case B_SPACE: case B_SPACE:
@@ -4003,11 +4041,43 @@ void
BTextView::HandleInputMethodChanged(BMessage *message) BTextView::HandleInputMethodChanged(BMessage *message)
{ {
CALLED(); CALLED();
// TODO: Implement me
if (!fInline) if (!fInline)
return; return;
message->PrintToStream(); // TODO: Highlight in blue/red the various clauses
const char *string = NULL;
if (message->FindString("be:string", &string) != B_OK || string == NULL)
return;
be_app->ObscureCursor();
// Delete the previously inserted text (if any)
if (fInline->IsActive()) {
int32 oldOffset = fInline->Offset();
DeleteText(oldOffset, oldOffset + fInline->Length());
Select(oldOffset, oldOffset);
}
int32 stringLen = strlen(string);
fInline->SetOffset(fSelStart);
fInline->SetLength(stringLen);
// Insert the new text
InsertText(string, stringLen, fSelStart, NULL);
Select(fSelStart + stringLen, fSelStart + stringLen);
Refresh(0, fLines->NumLines(), true, false);
// 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)
fInline->SetActive(true);
else
fInline->SetActive(false);
} }
@@ -4019,15 +4089,45 @@ BTextView::HandleInputMethodLocationRequest()
CALLED(); CALLED();
if (!fInline) if (!fInline)
return; return;
// TODO: Implement me
int32 offset = fInline->Offset();
int32 limit = offset + fInline->Length();
BMessage message(B_INPUT_METHOD_EVENT);
message.AddInt32("be:opcode", B_INPUT_METHOD_LOCATION_REQUEST);
// Add the location of the UTF8 charachters
float height = 0;
BPoint where;
while (offset < limit) {
where = PointAt(offset, &height);
ConvertToScreen(&where);
message.AddPoint("be:location_reply", where);
message.AddFloat("be:height_reply", height);
offset = NextInitialByte(offset);
}
fInline->Method()->SendMessage(&message);
} }
/*! \brief Tells the input server method addon to stop the current transaction.
*/
void void
BTextView::CancelInputMethod() BTextView::CancelInputMethod()
{ {
// TODO: Implement me
CALLED(); CALLED();
if (!fInline)
return;
BMessage message(B_INPUT_METHOD_EVENT);
message.AddInt32("be:opcode", B_INPUT_METHOD_STOPPED);
fInline->Method()->SendMessage(&message);
delete fInline;
fInline = NULL;
} }