Recieving of formatted messages (by font-face)
Now addons can format messages with new slots accepted by IM_MESSAGE_RECEIVED: "face_start," "face_length," and "face". The first two deal with the position of the face-change by character offset in the string, and the last being the face flag affected.
This commit is contained in:
parent
ad869c8972
commit
29a94bcf65
|
@ -75,8 +75,12 @@ enum im_what_code {
|
|||
printed in chat.
|
||||
If chat_id is ommitted, the message is sent to the protocol's system
|
||||
buffer, rather than a specific conversation.
|
||||
face_start and face_length specify the location of formatted text in
|
||||
the body, and "face" is the desired font face. Unsupported in bulk,
|
||||
i.e., IM_LOGS_RECEIVED.
|
||||
Requires: String "body"
|
||||
Allows: String "chat_id", String "user_id", String "user_name" */
|
||||
Allows: String "chat_id", String "user_id", String "user_name",
|
||||
int32s "face_start", int32s "face_length", uint16s "face" */
|
||||
IM_MESSAGE_RECEIVED = 22,
|
||||
|
||||
/*! Logs received →App
|
||||
|
|
|
@ -418,6 +418,12 @@ ConversationView::_AppendMessage(BMessage* msg)
|
|||
}
|
||||
|
||||
// … else we're jamming a message into this view no matter what it takes!
|
||||
if (msg->HasInt32("face_start") == true) {
|
||||
_AppendFormattedMessage(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
// For unformatted (normal or bulk) messages
|
||||
BStringList user_ids, user_names, bodies;
|
||||
if (msg->FindStrings("body", &bodies) != B_OK)
|
||||
return;
|
||||
|
@ -464,6 +470,115 @@ ConversationView::_AppendMessage(BMessage* msg)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_AppendFormattedMessage(BMessage* msg)
|
||||
{
|
||||
int64 timeInt;
|
||||
BString user_id;
|
||||
BString user_name;
|
||||
BString body;
|
||||
rgb_color userColor = ui_color(B_PANEL_TEXT_COLOR);
|
||||
|
||||
if (msg->FindString("body", &body) != B_OK)
|
||||
return;
|
||||
|
||||
if (msg->FindInt64("when", &timeInt) != B_OK)
|
||||
timeInt = (int64)time(NULL);
|
||||
|
||||
if (msg->FindString("user_id", &user_id) == B_OK)
|
||||
if (fConversation != NULL) {
|
||||
User* user = fConversation->UserById(user_id);
|
||||
if (user != NULL) {
|
||||
user_name = user->GetName();
|
||||
userColor = user->fItemColor;
|
||||
}
|
||||
else
|
||||
user_name = user_id;
|
||||
}
|
||||
else if (msg->FindString("user_name", &user_name) != B_OK) {
|
||||
fReceiveView->AppendGeneric(body);
|
||||
return;
|
||||
}
|
||||
|
||||
fReceiveView->AppendTimestamp(timeInt);
|
||||
fReceiveView->AppendUserstamp(user_name, userColor);
|
||||
|
||||
// And here we append the body…
|
||||
uint16 face = 0;
|
||||
UInt16IntMap face_indices;
|
||||
rgb_color color = ui_color(B_PANEL_TEXT_COLOR);
|
||||
|
||||
BFont font;
|
||||
for (int i = 0; i < body.CountChars(); i++) {
|
||||
_EnableStartingFaces(msg, i, &face, &face_indices);
|
||||
|
||||
if (face == B_REGULAR_FACE) {
|
||||
font = BFont();
|
||||
face = 0;
|
||||
}
|
||||
else if (face > 0) {
|
||||
font.SetFace(face);
|
||||
}
|
||||
|
||||
int32 bytes;
|
||||
const char* curChar = body.CharAt(i, &bytes);
|
||||
char append[bytes];
|
||||
|
||||
for (int i = 0; i < bytes; i++)
|
||||
append[i] = curChar[i];
|
||||
append[bytes] = '\0';
|
||||
fReceiveView->Append(append, color, &font);
|
||||
|
||||
_DisableEndingFaces(msg, &face, &face_indices);
|
||||
}
|
||||
fReceiveView->Append("\n");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_EnableStartingFaces(BMessage* msg, int32 index, uint16* face,
|
||||
UInt16IntMap* indices)
|
||||
{
|
||||
int32 face_start;
|
||||
int32 face_length;
|
||||
uint16 newFace;
|
||||
|
||||
int32 i = 0;
|
||||
while (msg->FindInt32("face_start", i, &face_start) == B_OK) {
|
||||
if (face_start == index) {
|
||||
if (msg->FindInt32("face_length", i, &face_length) != B_OK)
|
||||
continue;
|
||||
if (msg->FindUInt16("face", i, &newFace) != B_OK)
|
||||
continue;
|
||||
|
||||
*face |= newFace;
|
||||
indices->AddItem(newFace, face_length);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_DisableEndingFaces(BMessage* msg, uint16* face,
|
||||
UInt16IntMap* indices)
|
||||
{
|
||||
for (int32 i = 0; i < indices->CountItems(); i++) {
|
||||
uint16 key = indices->KeyAt(i);
|
||||
int32 value = indices->ValueAt(i) - 1;
|
||||
|
||||
indices->RemoveItemAt(i);
|
||||
if (value <= 0) {
|
||||
*face = *face & ~key;
|
||||
if (indices->CountItems() == 0)
|
||||
*face = B_REGULAR_FACE;
|
||||
}
|
||||
else
|
||||
indices->AddItem(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ConversationView::_UserMessage(const char* format, const char* bodyFormat,
|
||||
BMessage* msg)
|
||||
|
|
|
@ -26,6 +26,8 @@ class UserListView;
|
|||
|
||||
const uint32 kClearText = 'CVct';
|
||||
|
||||
typedef KeyMap<uint16, int32> UInt16IntMap;
|
||||
|
||||
|
||||
class ConversationView : public BGroupView, public Observer, public Notifier {
|
||||
public:
|
||||
|
@ -55,6 +57,13 @@ private:
|
|||
|
||||
bool _AppendOrEnqueueMessage(BMessage* msg);
|
||||
void _AppendMessage(BMessage* msg);
|
||||
void _AppendFormattedMessage(BMessage* msg);
|
||||
|
||||
// Helper functions for _AppendFormattedMessage()
|
||||
void _EnableStartingFaces(BMessage* msg, int32 index,
|
||||
uint16* face, UInt16IntMap* indices);
|
||||
void _DisableEndingFaces(BMessage* msg, uint16* face,
|
||||
UInt16IntMap* indices);
|
||||
|
||||
void _UserMessage(const char* format, const char* bodyFormat,
|
||||
BMessage* msg);
|
||||
|
|
|
@ -24,9 +24,7 @@ RenderView::AppendMessage(const char* nick, const char* message,
|
|||
if (BString(message).IsEmpty() == true) return;
|
||||
|
||||
AppendTimestamp(time);
|
||||
Append("<", nameColor);
|
||||
Append(nick);
|
||||
Append("> ", nameColor);
|
||||
AppendUserstamp(nick, nameColor);
|
||||
Append(message);
|
||||
|
||||
if (BString(message).EndsWith("\n") == false) Append("\n");
|
||||
|
@ -43,6 +41,15 @@ RenderView::AppendGeneric(const char* message)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
RenderView::AppendUserstamp(const char* nick, rgb_color nameColor)
|
||||
{
|
||||
Append("<", nameColor, B_BOLD_FACE);
|
||||
Append(nick, nameColor, B_BOLD_FACE);
|
||||
Append("> ", nameColor, B_BOLD_FACE);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RenderView::AppendTimestamp(time_t time)
|
||||
{
|
||||
|
@ -55,17 +62,18 @@ RenderView::AppendTimestamp(time_t time)
|
|||
BString stamp("――― %date% ―――\n");
|
||||
stamp.ReplaceAll("%date%", datestamp);
|
||||
|
||||
Append(stamp.String(), ui_color(B_PANEL_TEXT_COLOR), B_ITALIC_FACE);
|
||||
Append(stamp.String(), ui_color(B_PANEL_TEXT_COLOR),
|
||||
B_ITALIC_FACE | B_BOLD_FACE);
|
||||
|
||||
fLastDay = tm->tm_yday;
|
||||
fLastYear = tm->tm_year;
|
||||
}
|
||||
|
||||
if (time == 0) {
|
||||
Append("[xx:xx] ", ui_color(B_LINK_HOVER_COLOR));
|
||||
Append("[xx:xx] ", ui_color(B_LINK_HOVER_COLOR), B_BOLD_FACE);
|
||||
return;
|
||||
}
|
||||
char timestamp[9] = { '\0' };
|
||||
strftime(timestamp, 8, "[%H:%M] ", tm);
|
||||
Append(timestamp, ui_color(B_LINK_HOVER_COLOR));
|
||||
Append(timestamp, ui_color(B_LINK_HOVER_COLOR), B_BOLD_FACE);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ public:
|
|||
void AppendMessage(const char* nick, const char* message,
|
||||
rgb_color nameColor, time_t time = 0);
|
||||
void AppendGeneric(const char* message);
|
||||
void AppendUserstamp(const char* nick, rgb_color nameColor);
|
||||
void AppendTimestamp(time_t time = 0);
|
||||
|
||||
private:
|
||||
|
|
Ŝarĝante…
Reference in New Issue