(purple) RequestAction dialogs

First progress in support for purple's Request dialogs
This commit is contained in:
Jaidyn Ann 2021-07-11 15:22:49 -05:00
parent 437154310b
commit c5521ad9a3
4 changed files with 303 additions and 4 deletions

View File

@ -23,7 +23,6 @@
#include <iostream> #include <iostream>
#include <glib.h> #include <glib.h>
#include <libpurple/purple.h>
#include <libpurple/status.h> #include <libpurple/status.h>
#include <Directory.h> #include <Directory.h>
@ -36,6 +35,7 @@
#include <Flags.h> #include <Flags.h>
#include "Purple.h" #include "Purple.h"
#include "PurpleDialog.h"
#include "PurpleMessages.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 void
init_ui_ops() init_ui_ops()
{ {
purple_eventloop_set_ui_ops(&_ui_op_eventloops); 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 bool
is_own_user(PurpleAccount* account, const char* name) is_own_user(PurpleAccount* account, const char* name)
{ {

View File

@ -153,6 +153,53 @@ private:
PurpleInputCondition condition, PurpleInputCondition condition,
PurpleInputFunction function, gpointer data); 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 // Util
bool is_own_user(PurpleAccount* account, const char* name); bool is_own_user(PurpleAccount* account, const char* name);

View File

@ -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);
}
}

View File

@ -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