(purple) RequestAction dialogs
First progress in support for purple's Request dialogs
This commit is contained in:
parent
437154310b
commit
c5521ad9a3
|
@ -23,7 +23,6 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <glib.h>
|
||||
#include <libpurple/purple.h>
|
||||
#include <libpurple/status.h>
|
||||
|
||||
#include <Directory.h>
|
||||
|
@ -36,6 +35,7 @@
|
|||
#include <Flags.h>
|
||||
|
||||
#include "Purple.h"
|
||||
#include "PurpleDialog.h"
|
||||
#include "PurpleMessages.h"
|
||||
|
||||
|
||||
|
@ -900,10 +900,27 @@ static PurpleEventLoopUiOps _ui_op_eventloops =
|
|||
};
|
||||
|
||||
|
||||
static PurpleRequestUiOps _ui_op_request =
|
||||
{
|
||||
ui_op_request_input,
|
||||
ui_op_request_choice,
|
||||
ui_op_request_action,
|
||||
ui_op_request_fields,
|
||||
ui_op_request_file,
|
||||
NULL,
|
||||
ui_op_request_folder,
|
||||
ui_op_request_action_with_icon,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
init_ui_ops()
|
||||
{
|
||||
purple_eventloop_set_ui_ops(&_ui_op_eventloops);
|
||||
purple_request_set_ui_ops(&_ui_op_request);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1176,6 +1193,88 @@ ui_op_input_add(gint fd, PurpleInputCondition condition,
|
|||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_input(const char* title, const char* primary,
|
||||
const char* secondary, const char* default_value, gboolean multiline,
|
||||
gboolean masked, gchar* hint, const char* ok_text, GCallback ok_cb,
|
||||
const char* cancel_text, GCallback cancel_cb, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv, void* user_data)
|
||||
{
|
||||
std::cerr << "request input: " << title << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_choice(const char* title, const char* primary,
|
||||
const char* secondary, int default_value, const char* ok_text,
|
||||
GCallback ok_cb, const char* cancel_text, GCallback cancel_cb,
|
||||
PurpleAccount* account, const char* who, PurpleConversation* conv,
|
||||
void* user_data, va_list choices)
|
||||
{
|
||||
std::cerr << "request choice: " << title << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_action(const char* title, const char* primary,
|
||||
const char* secondary, int default_action, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv, void* user_data,
|
||||
size_t action_count, va_list actions)
|
||||
{
|
||||
PurpleDialog* win =
|
||||
new PurpleDialog(title, primary, secondary, account, actions,
|
||||
action_count, user_data);
|
||||
win->Show();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_fields(const char* title, const char* primary,
|
||||
const char* secondary, PurpleRequestFields* fields, const char* ok_text,
|
||||
GCallback ok_cb, const char* cancel_text, GCallback cancel_cb,
|
||||
PurpleAccount* account, const char* who, PurpleConversation* conv,
|
||||
void* user_data)
|
||||
{
|
||||
std::cerr << "request fields from " << purple_account_get_username(account)
|
||||
<< ": " << primary << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_file(const char* title, const char* filename, gboolean savedialog,
|
||||
GCallback ok_cb, GCallback cancel_cb, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv, void* user_data)
|
||||
{
|
||||
std::cerr << "request file: " << title << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_folder(const char* title, const char* dirname, GCallback ok_cb,
|
||||
GCallback cancel_cb, PurpleAccount* account, const char* who,
|
||||
PurpleConversation* conv, void* user_data)
|
||||
{
|
||||
std::cerr << "request folder: " << title << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void*
|
||||
ui_op_request_action_with_icon(const char* title, const char* primary,
|
||||
const char* secondary, int default_action, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv, gconstpointer icon_data,
|
||||
gsize icon_size, void* user_data, size_t action_count, va_list actions)
|
||||
{
|
||||
std::cerr << "request action with icon: " << title << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_own_user(PurpleAccount* account, const char* name)
|
||||
{
|
||||
|
|
|
@ -141,18 +141,65 @@ private:
|
|||
static void signal_chat_buddy_joined(PurpleConversation* conv,
|
||||
const char* name, PurpleConvChatBuddyFlags flags,
|
||||
gboolean new_arrival);
|
||||
static void signal_chat_invited(PurpleAccount* account,
|
||||
static void signal_chat_invited(PurpleAccount* account,
|
||||
const char* inviter, const char* chat,
|
||||
const char* message, const GHashTable* components);
|
||||
static void signal_chat_buddy_flags(PurpleConversation* conv,
|
||||
static void signal_chat_buddy_flags(PurpleConversation* conv,
|
||||
const char* name, PurpleConvChatBuddyFlags oldflags,
|
||||
PurpleConvChatBuddyFlags newflags);
|
||||
|
||||
// EventLoop ui ops
|
||||
static guint ui_op_input_add(gint fd,
|
||||
static guint ui_op_input_add(gint fd,
|
||||
PurpleInputCondition condition,
|
||||
PurpleInputFunction function, gpointer data);
|
||||
|
||||
// Request ui ops
|
||||
static void* ui_op_request_input(const char* title,
|
||||
const char* primary, const char* secondary,
|
||||
const char* default_value, gboolean multiline,
|
||||
gboolean masked, gchar* hint, const char* ok_text,
|
||||
GCallback ok_cb, const char* cancel_text,
|
||||
GCallback cancel_cb, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv,
|
||||
void* user_data);
|
||||
static void* ui_op_request_choice(const char* title,
|
||||
const char* primary, const char* secondary,
|
||||
int default_value, const char* ok_text,
|
||||
GCallback ok_cb, const char* cancel_text,
|
||||
GCallback cancel_cb, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv,
|
||||
void* user_data, va_list choices);
|
||||
static void* ui_op_request_action(const char* title,
|
||||
const char* primary, const char* secondary,
|
||||
int default_action, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv,
|
||||
void* user_data, size_t action_count,
|
||||
va_list actions);
|
||||
static void* ui_op_request_fields(const char* title,
|
||||
const char* primary, const char* secondary,
|
||||
PurpleRequestFields* fields, const char* ok_text,
|
||||
GCallback ok_cb, const char* cancel_text,
|
||||
GCallback cancel_cb, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv,
|
||||
void* user_data);
|
||||
static void* ui_op_request_file(const char* title,
|
||||
const char* filename, gboolean savedialog,
|
||||
GCallback ok_cb, GCallback cancel_cb,
|
||||
PurpleAccount* account, const char* who,
|
||||
PurpleConversation* conv, void* user_data);
|
||||
static void* ui_op_request_folder(const char* title,
|
||||
const char* dirname, GCallback ok_cb,
|
||||
GCallback cancel_cb, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv,
|
||||
void* user_data);
|
||||
static void* ui_op_request_action_with_icon(const char* title,
|
||||
const char* primary, const char* secondary,
|
||||
int default_action, PurpleAccount* account,
|
||||
const char* who, PurpleConversation* conv,
|
||||
gconstpointer icon_data, gsize icon_size,
|
||||
void* user_data, size_t action_count,
|
||||
va_list actions);
|
||||
|
||||
// Util
|
||||
bool is_own_user(PurpleAccount* account, const char* name);
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
|
||||
#include "PurpleDialog.h"
|
||||
|
||||
#include <libpurple/purple.h>
|
||||
|
||||
#include <Button.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <StringView.h>
|
||||
#include <TextView.h>
|
||||
|
||||
|
||||
PurpleDialog::PurpleDialog(const char* title, const char* primary,
|
||||
const char* secondary, PurpleAccount* account, va_list actions,
|
||||
size_t action_count, void* user_data)
|
||||
:
|
||||
BWindow(BRect(BPoint(-1000, -1000), BSize(300, 250)),title,
|
||||
B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
|
||||
B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fUserData(user_data)
|
||||
{
|
||||
CenterOnScreen();
|
||||
_ParseActions(actions, action_count, PURPLE_REQUEST_ACTION);
|
||||
_InitActionInterface(primary, secondary);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PurpleDialog::MessageReceived(BMessage* msg)
|
||||
{
|
||||
switch (msg->what)
|
||||
{
|
||||
case ACTION_BUTTON:
|
||||
{
|
||||
int32 id;
|
||||
if (msg->FindInt32("index", &id) != B_OK) break;
|
||||
|
||||
PurpleRequestActionCb cb = fActions.ItemAt(0)->callback.action;
|
||||
cb(fUserData, fActions.ItemAt(0)->index);
|
||||
Quit();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PurpleDialog::_InitActionInterface(const char* label, const char* desc)
|
||||
{
|
||||
BStringView* primaryLabel = new BStringView("primaryText", label);
|
||||
primaryLabel->SetExplicitAlignment(
|
||||
BAlignment(B_ALIGN_CENTER, B_ALIGN_TOP));
|
||||
|
||||
BTextView* secondaryLabel = new BTextView("secondaryText");
|
||||
secondaryLabel->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
secondaryLabel->MakeEditable(false);
|
||||
secondaryLabel->SetWordWrap(true);
|
||||
secondaryLabel->SetText(desc);
|
||||
|
||||
// Init buttons view
|
||||
BView* buttonsView = new BView("actionButtons", 0);
|
||||
BLayoutBuilder::Group<>(buttonsView, B_HORIZONTAL);
|
||||
for (int i = 0; i < fActions.CountItems(); i++) {
|
||||
RequestAction* action = fActions.ItemAt(i);
|
||||
BMessage* msg = new BMessage(ACTION_BUTTON);
|
||||
msg->AddInt32("index", action->index);
|
||||
|
||||
BButton* button = new BButton(action->name.String(), msg);
|
||||
buttonsView->AddChild(button);
|
||||
}
|
||||
|
||||
// Main layout
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL)
|
||||
.SetInsets(B_USE_DEFAULT_SPACING)
|
||||
.Add(primaryLabel)
|
||||
.Add(secondaryLabel)
|
||||
.Add(buttonsView)
|
||||
.AddGlue()
|
||||
.End();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PurpleDialog::_ParseActions(va_list actions, int32 count,
|
||||
PurpleRequestType type)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
RequestAction* action = new RequestAction;
|
||||
action->name = va_arg(actions, const char*);
|
||||
action->index = i;
|
||||
action->type = type;
|
||||
|
||||
switch (type) {
|
||||
case PURPLE_REQUEST_ACTION:
|
||||
action->callback.action = va_arg(actions, PurpleRequestActionCb);
|
||||
break;
|
||||
}
|
||||
fActions.AddItem(action);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 2021, Jaidyn Levesque <jadedctrl@teknik.io>
|
||||
* All rights reserved. Distributed under the terms of the MIT license.
|
||||
*/
|
||||
#ifndef _PURPLE_DIALOG_H
|
||||
#define _PURPLE_DIALOG_H
|
||||
|
||||
#include <libpurple/purple.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
const uint32 ACTION_BUTTON = 'PDab';
|
||||
|
||||
|
||||
struct RequestAction
|
||||
{
|
||||
BString name;
|
||||
PurpleRequestType type;
|
||||
int32 index;
|
||||
|
||||
union {
|
||||
PurpleRequestActionCb action;
|
||||
} callback;
|
||||
};
|
||||
|
||||
|
||||
class PurpleDialog : public BWindow {
|
||||
public:
|
||||
// PURPLE_REQUEST_ACTION
|
||||
PurpleDialog(const char* title, const char* primary,
|
||||
const char* secondary, PurpleAccount* account,
|
||||
va_list actions, size_t action_count, void* user_data);
|
||||
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
|
||||
private:
|
||||
void _InitActionInterface(const char* label, const char* desc);
|
||||
void _ParseActions(va_list actions, int32 count,
|
||||
PurpleRequestType type);
|
||||
|
||||
BObjectList<RequestAction> fActions;
|
||||
void* fUserData;
|
||||
};
|
||||
|
||||
#endif // _PURPLE_DIALOG_H
|
Ŝarĝante…
Reference in New Issue