(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 <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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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