mirror of https://github.com/deavminet/gustav.git
Compare commits
45 Commits
Author | SHA1 | Date |
---|---|---|
Tristan B. Kildaire | 426a65cf96 | |
Tristan B. Kildaire | 66bb86e4cd | |
Tristan B. Kildaire | 3d6e01fb2a | |
Tristan B. Kildaire | a14d67e0fd | |
Tristan B. Kildaire | e0bd021db1 | |
Tristan B. Kildaire | f2120f5fd4 | |
Tristan B. Kildaire | ddee77a5b7 | |
Tristan B. Kildaire | 75ac2e16d4 | |
Tristan B. Kildaire | 5bac2157f8 | |
Tristan B. Kildaire | 302603a6f6 | |
Tristan B. Kildaire | 40342772c2 | |
Tristan B. Kildaire | 13d5176a89 | |
Tristan B. Kildaire | e6ef053f13 | |
Tristan B. Kildaire | 602d23e067 | |
Tristan B. Kildaire | 37c1afeaaa | |
Tristan B. Kildaire | 21f60747a6 | |
Tristan B. Kildaire | 4c687b06eb | |
Tristan B. Kildaire | e75aee2221 | |
Tristan B. Kildaire | 4ff60a02c9 | |
Tristan B. Kildaire | a3d70929e5 | |
Tristan B. Kildaire | 029cd5a3ee | |
Tristan B. Kildaire | be543d33fd | |
Tristan B. Kildaire | a9b3617b0d | |
Tristan B. Kildaire | 31611d6f94 | |
Tristan B. Kildaire | d4912089b1 | |
Tristan B. Kildaire | 638b1bfa9b | |
Tristan B. Kildaire | 58951da6b0 | |
Tristan B. Kildaire | 1420e8e86f | |
Tristan B. Kildaire | 27c42711e0 | |
Tristan B. Kildaire | f5791f2eae | |
Tristan B. Kildaire | 97295cf042 | |
Tristan B. Kildaire | ce9a675da0 | |
Tristan B. Kildaire | 62895ccaee | |
Tristan B. Kildaire | ecd23539ab | |
Tristan B. Kildaire | 5ea0a76a08 | |
Tristan B. Kildaire | e965b9a82c | |
Tristan B. Kildaire | 68ad0e5f38 | |
Tristan B. Kildaire | 01578ab03b | |
Tristan B. Kildaire | 95f36698f7 | |
Tristan B. Kildaire | d10c8f1c3c | |
Tristan B. Kildaire | 624d53d909 | |
Tristan B. Kildaire | 1da36e6936 | |
Tristan B. Kildaire | 015521082e | |
Tristan B. Kildaire | 27bc84da56 | |
Tristan B. Kildaire | 9bc6deb17d |
5
dub.json
5
dub.json
|
@ -4,8 +4,9 @@
|
||||||
],
|
],
|
||||||
"copyright": "Copyright © 2020, Tristan B. Kildaire",
|
"copyright": "Copyright © 2020, Tristan B. Kildaire",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"gtk-d": "~>3.9.0",
|
"gogga": "0.0.2",
|
||||||
"libdnet": "~>0.1.13"
|
"gtk-d": "3.9.0",
|
||||||
|
"libdnet": "0.2.3"
|
||||||
},
|
},
|
||||||
"description": "GTK graphical DNET client",
|
"description": "GTK graphical DNET client",
|
||||||
"license": "GPL v3",
|
"license": "GPL v3",
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
"fileVersion": 1,
|
"fileVersion": 1,
|
||||||
"versions": {
|
"versions": {
|
||||||
"bformat": "1.0.8",
|
"bformat": "1.0.8",
|
||||||
|
"gogga": "0.0.2",
|
||||||
"gtk-d": "3.9.0",
|
"gtk-d": "3.9.0",
|
||||||
"libdnet": "0.1.13",
|
"libdnet": "0.2.3",
|
||||||
"tristanable": "0.1.1"
|
"tristanable": "0.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,14 @@ import gui;
|
||||||
import gdk.Threads : te = threadsEnter, tl = threadsLeave;
|
import gdk.Threads : te = threadsEnter, tl = threadsLeave;
|
||||||
import gtk.Box;
|
import gtk.Box;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
import libdnet.dclient;
|
import libdnet.client;
|
||||||
import std.socket;
|
import std.socket;
|
||||||
import gtk.ListBox;
|
import gtk.ListBox;
|
||||||
import gtk.Label;
|
import gtk.Label;
|
||||||
|
|
||||||
import Channel;
|
import areas.Channel;
|
||||||
|
import areas.MessageArea;
|
||||||
|
import areas.User;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
|
||||||
import core.sync.mutex;
|
import core.sync.mutex;
|
||||||
|
@ -19,13 +21,15 @@ import gtk.Notebook;
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
|
import gogga;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public final class Connection : Thread
|
public final class Connection : Thread
|
||||||
{
|
{
|
||||||
private GUI gui;
|
private GUI gui;
|
||||||
private Box box;
|
private Box box;
|
||||||
private ListBox channels;
|
private ListBox channels;
|
||||||
private ListBox users;
|
|
||||||
private ListBox textArea;
|
|
||||||
|
|
||||||
private DClient client;
|
private DClient client;
|
||||||
private Address address;
|
private Address address;
|
||||||
|
@ -41,9 +45,9 @@ public final class Connection : Thread
|
||||||
* All joined Channel-s in this Connection
|
* All joined Channel-s in this Connection
|
||||||
*/
|
*/
|
||||||
private Notebook notebookSwitcher;
|
private Notebook notebookSwitcher;
|
||||||
private Channel[] chans; /*TODO: Technically locking by GTK would make this not needed */
|
private MessageArea[] areas; /*TODO: Technically locking by GTK would make this not needed */
|
||||||
private Mutex chansLock;
|
private Mutex chansLock;
|
||||||
private Channel focusedChan;
|
private MessageArea focusedArea;
|
||||||
|
|
||||||
|
|
||||||
// public void setPrescence(string pres)
|
// public void setPrescence(string pres)
|
||||||
|
@ -122,7 +126,8 @@ public final class Connection : Thread
|
||||||
{
|
{
|
||||||
/* Receive a notification */
|
/* Receive a notification */
|
||||||
byte[] notificationData = client.awaitNotification();
|
byte[] notificationData = client.awaitNotification();
|
||||||
writeln(notificationData);
|
gprintln("A new notification has arrived");
|
||||||
|
gprintln("Notification data: "~to!(string)(notificationData));
|
||||||
|
|
||||||
te();
|
te();
|
||||||
// import std.conv;
|
// import std.conv;
|
||||||
|
@ -151,45 +156,100 @@ public final class Connection : Thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes an incoming notification
|
* Processes an incoming notification
|
||||||
* accordingly
|
* accordingly
|
||||||
*/
|
*/
|
||||||
private void process(byte[] data)
|
private void process(byte[] data)
|
||||||
{
|
{
|
||||||
/* TODO: Implement me */
|
/* Get the notification type */
|
||||||
|
|
||||||
/* TODO: Check notification type */
|
|
||||||
ubyte notificationType = data[0];
|
ubyte notificationType = data[0];
|
||||||
|
gprintln("NotificationType: "~to!(string)(notificationType));
|
||||||
|
|
||||||
/* For normal message (to channel or user) */
|
/* For normal message (to channel or user) */
|
||||||
if(notificationType == 0)
|
if(notificationType == 0)
|
||||||
{
|
{
|
||||||
/* TODO: Decode using tristanable */
|
/* TODO: Handle private messages */
|
||||||
writeln("new message");
|
|
||||||
writeln(data);
|
|
||||||
|
|
||||||
/* Decode is a test for assuming channel message received */
|
/* Decode is a test for assuming channel message received */
|
||||||
data = data[1..data.length];
|
data = data[1..data.length];
|
||||||
|
gprintln("Channel/User Notification: "~to!(string)(data));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* If this is a new message channel notification */
|
||||||
|
if(data[0] == 0)
|
||||||
|
{
|
||||||
|
gprintln("New channel message received", DebugType.WARNING);
|
||||||
|
|
||||||
/* Decode the [usernameLength, username] */
|
/* Decode the [usernameLength, username] */
|
||||||
ubyte usernameLength = data[1];
|
ubyte usernameLength = data[1];
|
||||||
writeln(usernameLength);
|
gprintln("ChannelMessage: (Username length): "~to!(string)(usernameLength));
|
||||||
string username = cast(string)data[2..2+usernameLength];
|
string username = cast(string)data[2..2+usernameLength];
|
||||||
writeln(username);
|
gprintln("ChannelMessage: (Username): "~username);
|
||||||
|
|
||||||
/* Decode the [channelLength, channel] */
|
/* Decode the [channelLength, channel] */
|
||||||
ubyte channelLength = data[2+usernameLength];
|
ubyte channelLength = data[2+usernameLength];
|
||||||
writeln(channelLength);
|
gprintln("ChannelMessage: (Channel length): "~to!(string)(channelLength));
|
||||||
string channel = cast(string)data[2+usernameLength+1..2+usernameLength+1+channelLength];
|
string channel = cast(string)data[2+usernameLength+1..2+usernameLength+1+channelLength];
|
||||||
writeln(channel);
|
gprintln("ChannelMessage: (Channel): "~channel);
|
||||||
|
|
||||||
|
|
||||||
findChannel(channel).receiveMessage(username, cast(string)data[2+usernameLength+1+channelLength..data.length]);
|
findChannel(channel).receiveMessage(username, cast(string)data[2+usernameLength+1+channelLength..data.length]);
|
||||||
|
}
|
||||||
|
/* If this is a new direct message notification */
|
||||||
|
else if(data[0] == 1)
|
||||||
|
{
|
||||||
|
gprintln("New direct message received", DebugType.WARNING);
|
||||||
|
|
||||||
|
/* Decode the [usernameLength, username] (username here is recipient's) */
|
||||||
|
ubyte recipientLength = data[1];
|
||||||
|
gprintln("DirectMessage: (Recipient length): "~to!(string)(recipientLength));
|
||||||
|
string recipient = cast(string)data[2..2+recipientLength];
|
||||||
|
gprintln("DirectMessage: (Recipient): "~recipient);
|
||||||
|
|
||||||
|
/* Decode the [usernameLength, username] (username here is sender's) */
|
||||||
|
ubyte sendersLength = data[2+recipientLength];
|
||||||
|
gprintln("DirectMessage: (Sender length): "~to!(string)(sendersLength));
|
||||||
|
string sender = cast(string)data[2+recipientLength+1..2+recipientLength+1+sendersLength];
|
||||||
|
gprintln("DirectMessage: (Sender): "~sender);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The message is the remainder */
|
||||||
|
string message = cast(string)data[2+recipientLength+1+sendersLength..data.length];
|
||||||
|
gprintln("DirectMessage: (Message): "~message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: DIfferes from channels, channels we never get delivered those we have no tab for as we haven't joined them
|
||||||
|
* and because server side knows we haven't joined iot we don't receive the notifivcaiton, eher however, there is no
|
||||||
|
* user tab possibly yet, so we will need to add it our selves */
|
||||||
|
User userArea = findUser(sender);
|
||||||
|
|
||||||
|
if(userArea)
|
||||||
|
{
|
||||||
|
userArea.receiveMessage(sender, message);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Add a new UserArea which will generate a new tab for us */
|
||||||
|
addDirectMessage_unsafe(sender);
|
||||||
|
|
||||||
|
/* The above statement adds an entry for us, now let's find the added UserArea */
|
||||||
|
userArea = findUser(sender);
|
||||||
|
|
||||||
|
/* Now let's add the direct message */
|
||||||
|
userArea.receiveMessage(sender, message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO: Handle this */
|
||||||
|
gprintln("FOk");
|
||||||
|
}
|
||||||
|
|
||||||
writeln("hdsfhdk");
|
|
||||||
}
|
}
|
||||||
/* Channel notification (ntype=1) */
|
/* Channel notification (ntype=1) */
|
||||||
else if(notificationType == 1)
|
else if(notificationType == 1)
|
||||||
|
@ -240,6 +300,124 @@ public final class Connection : Thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void addUserDM(User newUser)
|
||||||
|
{
|
||||||
|
/* TODO: However this we need to mutex for the areas as we could recieve a new message by watcher which adds for us */
|
||||||
|
chansLock.lock();
|
||||||
|
areas ~= newUser;
|
||||||
|
chansLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a new tab for a new direct message
|
||||||
|
*
|
||||||
|
* (To be called by a handler, which auto-mutexes)
|
||||||
|
*
|
||||||
|
* 1. Will add a new area
|
||||||
|
* 2. Will add a new tab to the notebook switcher
|
||||||
|
* 3. Will switch the current tab to said tab
|
||||||
|
*/
|
||||||
|
public void addDirectMessage_unsafe(string username)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Get box over here etc. */
|
||||||
|
|
||||||
|
gprintln("Henlo begi");
|
||||||
|
|
||||||
|
/* Check if we have joined this user already */
|
||||||
|
User foundUser = findUser(username);
|
||||||
|
|
||||||
|
gprintln("Henlo");
|
||||||
|
|
||||||
|
/* If we have joined this user before */
|
||||||
|
if(foundUser)
|
||||||
|
{
|
||||||
|
/* TODO: Switch to */
|
||||||
|
writeln("nope time: "~username);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/* If we haven't joined this user before */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Create the new User area */
|
||||||
|
User newUser = new User(this, username);
|
||||||
|
|
||||||
|
/* Add the user */
|
||||||
|
addUserDM(newUser);
|
||||||
|
|
||||||
|
/* Set as the `foundChannel` */
|
||||||
|
foundUser = newUser;
|
||||||
|
|
||||||
|
/* Get the Widgets container for this channel and add a tab for it */
|
||||||
|
notebookSwitcher.add(newUser.getBox());
|
||||||
|
notebookSwitcher.setTabReorderable(newUser.getBox(), true);
|
||||||
|
notebookSwitcher.setTabLabelText(newUser.getBox(), newUser.getUsername());
|
||||||
|
|
||||||
|
writeln("hdsjghjsd");
|
||||||
|
|
||||||
|
writeln("first time: "~username);
|
||||||
|
|
||||||
|
// /* Get the user's list */
|
||||||
|
// newChannel.populateUsersList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Render recursively all children of the container and then the container itself */
|
||||||
|
box.showAll();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to find the User object you are looking for
|
||||||
|
*/
|
||||||
|
public User findUser(string username)
|
||||||
|
{
|
||||||
|
User result;
|
||||||
|
|
||||||
|
chansLock.lock();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop through each MessageArea and only inspect those
|
||||||
|
* whose type is `Channel`
|
||||||
|
*/
|
||||||
|
foreach(MessageArea area; areas)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Make sure the object is of type `Channel` */
|
||||||
|
if(typeid(area) == typeid(User))
|
||||||
|
{
|
||||||
|
/* Down-cast */
|
||||||
|
User user = cast(User)area;
|
||||||
|
|
||||||
|
/* Find the matching channel */
|
||||||
|
if(cmp(user.getUsername(), username) == 0)
|
||||||
|
{
|
||||||
|
result = user;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import std.stdio;
|
||||||
|
writeln("\""~username~"\"");
|
||||||
|
|
||||||
|
|
||||||
|
chansLock.unlock();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void joinChannel(string channelName)
|
public void joinChannel(string channelName)
|
||||||
{
|
{
|
||||||
/* Check if we have joined this channel already */
|
/* Check if we have joined this channel already */
|
||||||
|
@ -316,20 +494,36 @@ public final class Connection : Thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to find the Channel object you are looking for
|
||||||
|
*/
|
||||||
public Channel findChannel(string channelName)
|
public Channel findChannel(string channelName)
|
||||||
{
|
{
|
||||||
Channel result;
|
Channel result;
|
||||||
|
|
||||||
chansLock.lock();
|
chansLock.lock();
|
||||||
|
|
||||||
foreach(Channel channel; chans)
|
/**
|
||||||
|
* Loop through each MessageArea and only inspect those
|
||||||
|
* whose type is `Channel`
|
||||||
|
*/
|
||||||
|
foreach(MessageArea area; areas)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* Make sure the object is of type `Channel` */
|
||||||
|
if(typeid(area) == typeid(Channel))
|
||||||
|
{
|
||||||
|
/* Down-cast */
|
||||||
|
Channel channel = cast(Channel)area;
|
||||||
|
|
||||||
|
/* Find the matching channel */
|
||||||
if(cmp(channel.getName(), channelName) == 0)
|
if(cmp(channel.getName(), channelName) == 0)
|
||||||
{
|
{
|
||||||
result = channel;
|
result = channel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
writeln("\""~channelName~"\"");
|
writeln("\""~channelName~"\"");
|
||||||
|
@ -354,7 +548,7 @@ public final class Connection : Thread
|
||||||
{
|
{
|
||||||
/* Add the channel to the `chans` tracking list */
|
/* Add the channel to the `chans` tracking list */
|
||||||
chansLock.lock();
|
chansLock.lock();
|
||||||
chans ~= newChannel;
|
areas ~= newChannel;
|
||||||
chansLock.unlock();
|
chansLock.unlock();
|
||||||
|
|
||||||
/* Add the channel to the channels list (sidebar) */
|
/* Add the channel to the channels list (sidebar) */
|
||||||
|
|
|
@ -9,6 +9,7 @@ import gtk.Window;
|
||||||
import gtk.Label;
|
import gtk.Label;
|
||||||
import gtk.Image;
|
import gtk.Image;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
import gtk.Box;
|
||||||
|
|
||||||
public final class ProfileWindow
|
public final class ProfileWindow
|
||||||
{
|
{
|
||||||
|
@ -25,16 +26,41 @@ public final class ProfileWindow
|
||||||
|
|
||||||
private void showWindow()
|
private void showWindow()
|
||||||
{
|
{
|
||||||
|
/* Create the window with the username as the title */
|
||||||
Window profileWindow = new Window(username);
|
Window profileWindow = new Window(username);
|
||||||
|
|
||||||
|
/* Create a Box for contents */
|
||||||
|
Box profileBox = new Box(GtkOrientation.VERTICAL, 1);
|
||||||
|
|
||||||
|
|
||||||
Image profileImage = new Image("/home/deavmi/Downloads/5207740.jpg");
|
/* Create a Image for the profile picture */
|
||||||
//profileWindow.add(profileImage);
|
Image profileImage = new Image("/home/deavmi/Downloads/logo.png");
|
||||||
|
profileBox.add(profileImage);
|
||||||
|
// profileImage.
|
||||||
|
|
||||||
|
/* Create the username label */
|
||||||
|
Label usernameTitle = new Label("");
|
||||||
|
usernameTitle.setMarkup("<span size=\"20000\">"~username~"</span>");
|
||||||
|
profileBox.add(usernameTitle);
|
||||||
|
|
||||||
|
|
||||||
|
/* Display all props (keys) */
|
||||||
string[] props = connection.getClient().getProperties(username);
|
string[] props = connection.getClient().getProperties(username);
|
||||||
profileWindow.add(new Label(to!(string)(props)));
|
profileBox.add(new Label(to!(string)(props)));
|
||||||
|
|
||||||
|
/* Display all props (values) */
|
||||||
|
string[] propValues;
|
||||||
|
foreach(string property; props)
|
||||||
|
{
|
||||||
|
propValues ~= connection.getClient().getProperty(username, property);
|
||||||
|
}
|
||||||
|
profileBox.add(new Label(to!(string)(propValues)));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
profileWindow.add(profileBox);
|
||||||
profileWindow.showAll();
|
profileWindow.showAll();
|
||||||
|
// profileWindow.unmaximize();
|
||||||
|
// profileWindow.setAttachedTo()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
module UserNode;
|
module UserNode;
|
||||||
|
|
||||||
import Connection;
|
import Connection;
|
||||||
import libdnet.dclient;
|
import libdnet.client;
|
||||||
import gtk.Box;
|
import gtk.Box;
|
||||||
import gtk.Button;
|
import gtk.Button;
|
||||||
import gtk.Image;
|
import gtk.Image;
|
||||||
|
@ -9,6 +9,7 @@ import gtk.Label;
|
||||||
import gtk.Tooltip;
|
import gtk.Tooltip;
|
||||||
import gtk.Widget;
|
import gtk.Widget;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
import ProfileWIndow;
|
||||||
|
|
||||||
public final class UserNode
|
public final class UserNode
|
||||||
{
|
{
|
||||||
|
@ -25,15 +26,25 @@ public final class UserNode
|
||||||
initBox();
|
initBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void userButtonClick(Button)
|
||||||
|
{
|
||||||
|
/* Create a new ProfileWindow */
|
||||||
|
ProfileWindow profileWindow = new ProfileWindow(connection, username);
|
||||||
|
}
|
||||||
|
|
||||||
private void initBox()
|
private void initBox()
|
||||||
{
|
{
|
||||||
|
/* Create a new Box */
|
||||||
box = new Box(GtkOrientation.HORIZONTAL, 10);
|
box = new Box(GtkOrientation.HORIZONTAL, 10);
|
||||||
|
|
||||||
/* Layout [Button (Prescence Icon)] - Label <username> */
|
/* Layout [Button (Prescence Icon)] - Label <username> - [Button (Reply Icon)]*/
|
||||||
Button userButton = new Button();
|
Button userButton = new Button();
|
||||||
Image userButtonImg = new Image("user-available", GtkIconSize.BUTTON);
|
Image userButtonImg = new Image("user-available", GtkIconSize.BUTTON);
|
||||||
userButton.setImage(userButtonImg);
|
userButton.setImage(userButtonImg);
|
||||||
|
|
||||||
|
/* Set the handler for on click */
|
||||||
|
userButton.addOnClicked(&userButtonClick);
|
||||||
|
|
||||||
/* Create a label */
|
/* Create a label */
|
||||||
Label userLabel = new Label(username);
|
Label userLabel = new Label(username);
|
||||||
|
|
||||||
|
@ -48,8 +59,30 @@ public final class UserNode
|
||||||
/* Add both components */
|
/* Add both components */
|
||||||
box.add(userButton);
|
box.add(userButton);
|
||||||
box.add(userLabel);
|
box.add(userLabel);
|
||||||
|
|
||||||
|
|
||||||
|
/* Add the direct message button */
|
||||||
|
Button messageButton = new Button();
|
||||||
|
Image messageButtonImg = new Image("mail-forward", GtkIconSize.BUTTON);
|
||||||
|
messageButton.setImage(messageButtonImg);
|
||||||
|
|
||||||
|
/* Set the handler for on click */
|
||||||
|
messageButton.addOnClicked(&newDirectMessage);
|
||||||
|
|
||||||
|
box.add(messageButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the handler for when the "direct message" button is clicked
|
||||||
|
*
|
||||||
|
* It will call `addDirectMessage_unsafe` with the username specified
|
||||||
|
*/
|
||||||
|
private void newDirectMessage(Button)
|
||||||
|
{
|
||||||
|
connection.addDirectMessage_unsafe(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler to be run when you hover over a user's
|
* Event handler to be run when you hover over a user's
|
||||||
* username in the Users sidebar list which will show
|
* username in the Users sidebar list which will show
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
* along with the input box state
|
* along with the input box state
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
module areas.Channel;
|
||||||
|
|
||||||
import gtk.Box;
|
import gtk.Box;
|
||||||
import gtk.ListBox;
|
import gtk.ListBox;
|
||||||
import gtk.Label;
|
import gtk.Label;
|
||||||
import gtk.TextView;
|
import gtk.TextView;
|
||||||
import libdnet.dclient;
|
import libdnet.client;
|
||||||
import gtk.Label;
|
import gtk.Label;
|
||||||
import std.string;
|
import std.string;
|
||||||
import gtk.Button;
|
import gtk.Button;
|
||||||
|
@ -20,12 +22,16 @@ import gtk.Widget;
|
||||||
import gtk.ScrolledWindow;
|
import gtk.ScrolledWindow;
|
||||||
import gtk.Button;
|
import gtk.Button;
|
||||||
import gtk.Entry;
|
import gtk.Entry;
|
||||||
|
import UserNode;
|
||||||
|
|
||||||
import pango.PgAttributeList;
|
import pango.PgAttributeList;
|
||||||
import pango.PgAttribute;
|
import pango.PgAttribute;
|
||||||
import Connection;
|
import Connection;
|
||||||
|
|
||||||
public final class Channel
|
import gogga;
|
||||||
|
import areas.MessageArea;
|
||||||
|
|
||||||
|
public final class Channel : MessageArea
|
||||||
{
|
{
|
||||||
private DClient client;
|
private DClient client;
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
@ -35,11 +41,6 @@ public final class Channel
|
||||||
*/
|
*/
|
||||||
private string channelName;
|
private string channelName;
|
||||||
|
|
||||||
/**
|
|
||||||
* The container for this Channel
|
|
||||||
*/
|
|
||||||
private Box box;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UI components
|
* UI components
|
||||||
*
|
*
|
||||||
|
@ -94,10 +95,24 @@ public final class Channel
|
||||||
ScrolledWindow scrollTextChats = new ScrolledWindow(textArea);
|
ScrolledWindow scrollTextChats = new ScrolledWindow(textArea);
|
||||||
textBox.add(scrollTextChats);
|
textBox.add(scrollTextChats);
|
||||||
|
|
||||||
|
|
||||||
|
/* The Box for the whole |attach button| text field| send button| */
|
||||||
|
Box textInputBox = new Box(GtkOrientation.HORIZONTAL, 1);
|
||||||
|
|
||||||
|
import gtk.Image;
|
||||||
|
|
||||||
|
/* The attachment button */
|
||||||
|
Button attachFileButton = new Button("Upload");
|
||||||
|
Image attachFileButtonIcon = new Image("user-available", GtkIconSize.BUTTON); /* TODO: Fix icon now showing */
|
||||||
|
attachFileButton.setImage(attachFileButtonIcon);
|
||||||
|
attachFileButton.addOnClicked(&uploadFileDialog);
|
||||||
|
textInputBox.add(attachFileButton);
|
||||||
|
|
||||||
/* The text input */
|
/* The text input */
|
||||||
textInput = new Entry();
|
textInput = new Entry();
|
||||||
textInput.addOnActivate(&sendMessageEnter);
|
textInput.addOnActivate(&sendMessageEnter);
|
||||||
Box textInputBox = new Box(GtkOrientation.HORIZONTAL, 1);
|
textInput.addOnChanged(&textChangd);
|
||||||
|
|
||||||
textInputBox.packStart(textInput,1,1,0);
|
textInputBox.packStart(textInput,1,1,0);
|
||||||
|
|
||||||
|
|
||||||
|
@ -107,14 +122,6 @@ public final class Channel
|
||||||
textInputBox.add(sendButton);
|
textInputBox.add(sendButton);
|
||||||
textBox.add(textInputBox);
|
textBox.add(textInputBox);
|
||||||
|
|
||||||
|
|
||||||
// import gtk.TextView;
|
|
||||||
// TextView f = new TextView();
|
|
||||||
// textBox.add(f);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
box.add(textBox);
|
box.add(textBox);
|
||||||
box.packEnd(userBox,0,0,0);
|
box.packEnd(userBox,0,0,0);
|
||||||
|
|
||||||
|
@ -123,6 +130,23 @@ public final class Channel
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void uploadFileDialog(Button e)
|
||||||
|
{
|
||||||
|
import gtk.FileChooserDialog; /* TODO: Set parent */
|
||||||
|
FileChooserDialog fileChooser = new FileChooserDialog("Send file to "~channelName, null, FileChooserAction.OPEN);
|
||||||
|
fileChooser.run();
|
||||||
|
gprintln("Selected file: "~fileChooser.getFilename());
|
||||||
|
}
|
||||||
|
|
||||||
|
import gtk.EditableIF;
|
||||||
|
private void textChangd(EditableIF)
|
||||||
|
{
|
||||||
|
/* If the text box just became empty stop ssending typing notifications */
|
||||||
|
/* Send typing stats */
|
||||||
|
// client.sendIsTyping(channelName, true);
|
||||||
|
/* TODO: Client implement wiht different tag? */
|
||||||
|
}
|
||||||
|
|
||||||
private void sendMessageEnter(Entry)
|
private void sendMessageEnter(Entry)
|
||||||
{
|
{
|
||||||
/* Retrieve the message */
|
/* Retrieve the message */
|
||||||
|
@ -157,33 +181,12 @@ public final class Channel
|
||||||
box.showAll();
|
box.showAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Box getBox()
|
|
||||||
{
|
|
||||||
return box;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string getName()
|
public string getName()
|
||||||
{
|
{
|
||||||
return channelName;
|
return channelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a Label with the tooltip event such
|
|
||||||
* that it will run that handler on hover
|
|
||||||
*/
|
|
||||||
private Label getUserLabel(string username)
|
|
||||||
{
|
|
||||||
/* Create a label */
|
|
||||||
Label userLabel = new Label(username);
|
|
||||||
|
|
||||||
/* Enable the tooltip */
|
|
||||||
userLabel.setHasTooltip(true);
|
|
||||||
|
|
||||||
/* Set the handler to run on hover */
|
|
||||||
userLabel.addOnQueryTooltip(&userLabelHoverHandler);
|
|
||||||
|
|
||||||
return userLabel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Box getUserListItem(string username)
|
private Box getUserListItem(string username)
|
||||||
|
@ -209,49 +212,8 @@ public final class Channel
|
||||||
// return true;
|
// return true;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
|
||||||
* Event handler to be run when you hover over a user's
|
|
||||||
* username in the Users sidebar list which will show
|
|
||||||
* the status as text (and in an icon format), the user's
|
|
||||||
* username and also their status message
|
|
||||||
*/
|
|
||||||
private bool userLabelHoverHandler(int, int, bool, Tooltip tooltip, Widget userLabel)
|
|
||||||
{
|
|
||||||
/* The username hovered over */
|
|
||||||
string userHover = (cast(Label)userLabel).getText();
|
|
||||||
|
|
||||||
/* The final tooltip */
|
|
||||||
string toolTipText = "<b>"~userHover~"</b>";
|
|
||||||
|
|
||||||
/* Check if there is a `precensce` message */
|
|
||||||
if(client.isProperty(userHover, "pres"))
|
|
||||||
{
|
|
||||||
/* Fetch the precensce */
|
|
||||||
string prescence = client.getProperty(userHover, "pres");
|
|
||||||
|
|
||||||
/* Set the icon */
|
|
||||||
tooltip.setIconFromIconName(statusToGtkIcon(prescence), GtkIconSize.DIALOG);
|
|
||||||
|
|
||||||
/* Append the precesnee to the tooltip text */
|
|
||||||
toolTipText ~= "\n"~prescence;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if there is a `status` message */
|
|
||||||
if(client.isProperty(userHover, "status"))
|
|
||||||
{
|
|
||||||
/* Next is status message */
|
|
||||||
string status = client.getProperty(userHover, "status");
|
|
||||||
|
|
||||||
/* Append the status to the tooltip text */
|
|
||||||
toolTipText ~= "\n<i>"~status~"</i>";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the tooltip text */
|
|
||||||
tooltip.setMarkup(toolTipText);
|
|
||||||
|
|
||||||
/* TODO: Point of return value? */
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void populateUsersList()
|
public void populateUsersList()
|
||||||
{
|
{
|
||||||
|
@ -259,46 +221,18 @@ public final class Channel
|
||||||
|
|
||||||
foreach(string member; memberList)
|
foreach(string member; memberList)
|
||||||
{
|
{
|
||||||
Label bruh = getUserLabel(member);
|
/* Create the user entry in the list */
|
||||||
users.add(bruh);
|
UserNode userNode = new UserNode(connection, member);
|
||||||
|
users.add(userNode.getBox());
|
||||||
|
|
||||||
|
/* Add the user to the tracking list */
|
||||||
usersString~=member;
|
usersString~=member;
|
||||||
|
|
||||||
|
|
||||||
/* TODO: Testing code, remove */
|
|
||||||
import UserNode;
|
|
||||||
UserNode testNode = new UserNode(connection, member);
|
|
||||||
users.add(testNode.getBox());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static string statusToGtkIcon(string status)
|
|
||||||
{
|
|
||||||
/* The GTK icon */
|
|
||||||
string gtkIcon = "image-missing";
|
|
||||||
|
|
||||||
if(cmp(status, "available") == 0)
|
|
||||||
{
|
|
||||||
gtkIcon = "user-available";
|
|
||||||
}
|
|
||||||
else if(cmp(status, "away") == 0)
|
|
||||||
{
|
|
||||||
gtkIcon = "user-away";
|
|
||||||
}
|
|
||||||
else if(cmp(status, "busy") == 0)
|
|
||||||
{
|
|
||||||
gtkIcon = "user-busy";
|
|
||||||
}
|
|
||||||
/* TODO: This doesn't make sense */
|
|
||||||
else if(cmp(status, "offline") == 0)
|
|
||||||
{
|
|
||||||
gtkIcon = "user-offline";
|
|
||||||
}
|
|
||||||
|
|
||||||
return gtkIcon;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void channelJoin(string username)
|
public void channelJoin(string username)
|
||||||
{
|
{
|
||||||
|
@ -313,9 +247,11 @@ public final class Channel
|
||||||
/* Add join message to message log */
|
/* Add join message to message log */
|
||||||
textArea.add(joinLabel);
|
textArea.add(joinLabel);
|
||||||
|
|
||||||
/* Add user to user list */
|
/* Create the user entry in the list */
|
||||||
users.add(getUserLabel(username));
|
UserNode userNode = new UserNode(connection, username);
|
||||||
|
users.add(userNode.getBox());
|
||||||
|
|
||||||
|
/* Add the user to the tracking list */
|
||||||
usersString~=username;
|
usersString~=username;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,15 +288,10 @@ public final class Channel
|
||||||
|
|
||||||
foreach(string currentUser; usersString)
|
foreach(string currentUser; usersString)
|
||||||
{
|
{
|
||||||
users.add(getUserLabel(currentUser));
|
/* Create the user entry in the list */
|
||||||
|
UserNode userNode = new UserNode(connection, currentUser);
|
||||||
|
users.add(userNode.getBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove user from user list */
|
|
||||||
/* TODO: Do this better */
|
|
||||||
// foreach(Label label; users.get)
|
|
||||||
// users.add(new Label(username));
|
|
||||||
// users.showAll();
|
|
||||||
// box.showAll();+
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendMessage(string message)
|
public void sendMessage(string message)
|
|
@ -0,0 +1,25 @@
|
||||||
|
/**
|
||||||
|
* MessageArea
|
||||||
|
*
|
||||||
|
* Represents the binding of a text entry, send button, user list (sometimes)
|
||||||
|
* and message log - basically the place where you message a channel or someone
|
||||||
|
*
|
||||||
|
* The sub-classes are "Direct Message" and "Channel"
|
||||||
|
*/
|
||||||
|
|
||||||
|
module areas.MessageArea;
|
||||||
|
|
||||||
|
import gtk.Box;
|
||||||
|
|
||||||
|
public class MessageArea
|
||||||
|
{
|
||||||
|
/* TODO: Implement me */
|
||||||
|
|
||||||
|
/* The area's Box (where everything is contained) */
|
||||||
|
protected Box box;
|
||||||
|
|
||||||
|
public Box getBox()
|
||||||
|
{
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
module areas.User;
|
||||||
|
|
||||||
|
import areas.MessageArea;
|
||||||
|
|
||||||
|
import gtk.Box;
|
||||||
|
import gtk.ListBox;
|
||||||
|
import gtk.Label;
|
||||||
|
import gtk.TextView;
|
||||||
|
import libdnet.client;
|
||||||
|
import gtk.Label;
|
||||||
|
import std.string;
|
||||||
|
import gtk.Button;
|
||||||
|
import gtk.Tooltip;
|
||||||
|
import gtk.Widget;
|
||||||
|
import gtk.ScrolledWindow;
|
||||||
|
import gtk.Button;
|
||||||
|
import gtk.Entry;
|
||||||
|
import UserNode;
|
||||||
|
|
||||||
|
import pango.PgAttributeList;
|
||||||
|
import pango.PgAttribute;
|
||||||
|
import Connection;
|
||||||
|
|
||||||
|
import gogga;
|
||||||
|
|
||||||
|
public final class User : MessageArea
|
||||||
|
{
|
||||||
|
private DClient client;
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Username
|
||||||
|
*/
|
||||||
|
private string username;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UI components
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
// private ListBox users;
|
||||||
|
private ListBox textArea;
|
||||||
|
private Entry textInput;
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: No mutexes should be needed (same precaution) as the GTK lock provides safety */
|
||||||
|
// private string[] usersString;
|
||||||
|
|
||||||
|
this(Connection connection, string username)
|
||||||
|
{
|
||||||
|
this.client = connection.getClient();
|
||||||
|
this.connection = connection;
|
||||||
|
this.username = username;
|
||||||
|
|
||||||
|
initializeBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string getUsername()
|
||||||
|
{
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeBox()
|
||||||
|
{
|
||||||
|
box = new Box(GtkOrientation.HORIZONTAL, 1);
|
||||||
|
|
||||||
|
// box.add(new Label("poes"));
|
||||||
|
/* The text box */
|
||||||
|
Box textBox = new Box(GtkOrientation.VERTICAL, 1);
|
||||||
|
|
||||||
|
/* Channel title */
|
||||||
|
Label channelTitleLabel = new Label(username);
|
||||||
|
channelTitleLabel.setMarkup("<span size=\"large\"><b>"~username~"</b></span>");
|
||||||
|
textBox.add(channelTitleLabel);
|
||||||
|
|
||||||
|
/* The messages box */
|
||||||
|
textArea = new ListBox();
|
||||||
|
ScrolledWindow scrollTextChats = new ScrolledWindow(textArea);
|
||||||
|
textBox.add(scrollTextChats);
|
||||||
|
|
||||||
|
|
||||||
|
/* The Box for the whole |attach button| text field| send button| */
|
||||||
|
Box textInputBox = new Box(GtkOrientation.HORIZONTAL, 1);
|
||||||
|
|
||||||
|
import gtk.Image;
|
||||||
|
|
||||||
|
/* The attachment button */
|
||||||
|
Button attachFileButton = new Button("Upload");
|
||||||
|
Image attachFileButtonIcon = new Image("user-available", GtkIconSize.BUTTON); /* TODO: Fix icon now showing */
|
||||||
|
attachFileButton.setImage(attachFileButtonIcon);
|
||||||
|
attachFileButton.addOnClicked(&uploadFileDialog);
|
||||||
|
textInputBox.add(attachFileButton);
|
||||||
|
|
||||||
|
/* The text input */
|
||||||
|
textInput = new Entry();
|
||||||
|
textInput.addOnActivate(&sendMessageEnter);
|
||||||
|
textInput.addOnChanged(&textChangd);
|
||||||
|
|
||||||
|
textInputBox.packStart(textInput,1,1,0);
|
||||||
|
|
||||||
|
|
||||||
|
/* The send button */
|
||||||
|
Button sendButton = new Button("Send");
|
||||||
|
sendButton.addOnClicked(&sendMessageBtn);
|
||||||
|
textInputBox.add(sendButton);
|
||||||
|
textBox.add(textInputBox);
|
||||||
|
|
||||||
|
box.add(textBox);
|
||||||
|
// box.packEnd(userBox,0,0,0);
|
||||||
|
|
||||||
|
textBox.setChildPacking(scrollTextChats, true, true, 0, GtkPackType.START);
|
||||||
|
box.setChildPacking(textBox, true, true, 0, GtkPackType.START);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
import gtk.EditableIF;
|
||||||
|
private void textChangd(EditableIF)
|
||||||
|
{
|
||||||
|
/* If the text box just became empty stop ssending typing notifications */
|
||||||
|
/* Send typing stats */
|
||||||
|
// client.sendIsTyping(channelName, true);
|
||||||
|
/* TODO: Client implement wiht different tag? */
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessageEnter(Entry)
|
||||||
|
{
|
||||||
|
/* Retrieve the message */
|
||||||
|
string message = textInput.getBuffer().getText();
|
||||||
|
|
||||||
|
/* TODO: Add the message to our log (as it won't be delivered to us) */
|
||||||
|
sendMessage(message);
|
||||||
|
|
||||||
|
/* Send the message */
|
||||||
|
client.sendMessage(1, username, message);
|
||||||
|
|
||||||
|
/* Clear the text box */
|
||||||
|
textInput.getBuffer().setText("",0);
|
||||||
|
|
||||||
|
box.showAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessageBtn(Button)
|
||||||
|
{
|
||||||
|
/* Retrieve the message */
|
||||||
|
string message = textInput.getBuffer().getText();
|
||||||
|
|
||||||
|
/* TODO: Add the message to our log (as it won't be delivered to us) */
|
||||||
|
sendMessage(message);
|
||||||
|
|
||||||
|
/* Send the message */
|
||||||
|
client.sendMessage(1, username, message);
|
||||||
|
|
||||||
|
/* Clear the text box */
|
||||||
|
textInput.getBuffer().setText("",0);
|
||||||
|
|
||||||
|
box.showAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(string message)
|
||||||
|
{
|
||||||
|
/* TOOD: Pass in connection perhaps */
|
||||||
|
string username = "Yourself";
|
||||||
|
|
||||||
|
/* Create the MessageBox */
|
||||||
|
Box messageBox = new Box(GtkOrientation.VERTICAL, 1);
|
||||||
|
|
||||||
|
/* Create and add the username */
|
||||||
|
Label usernameLabel = new Label("");
|
||||||
|
usernameLabel.setMarkup("<b>"~username~"</b>");
|
||||||
|
usernameLabel.setHalign(GtkAlign.END);
|
||||||
|
messageBox.add(usernameLabel);
|
||||||
|
|
||||||
|
/* Create and add the message */
|
||||||
|
Label messageLabel = new Label(message);
|
||||||
|
messageLabel.setHalign(GtkAlign.END);
|
||||||
|
messageLabel.setSelectable(true);
|
||||||
|
messageBox.add(messageLabel);
|
||||||
|
|
||||||
|
/* Add the message to the log */
|
||||||
|
textArea.add(messageBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void receiveMessage(string username, string message)
|
||||||
|
{
|
||||||
|
/* Create the MessageBox */
|
||||||
|
Box messageBox = new Box(GtkOrientation.VERTICAL, 1);
|
||||||
|
|
||||||
|
/* Create and add the username */
|
||||||
|
Label usernameLabel = new Label("");
|
||||||
|
usernameLabel.setMarkup("<b>"~username~"</b>");
|
||||||
|
usernameLabel.setHalign(GtkAlign.START);
|
||||||
|
messageBox.add(usernameLabel);
|
||||||
|
|
||||||
|
/* Create and add the message */
|
||||||
|
Label messageLabel = new Label(message);
|
||||||
|
messageLabel.setHalign(GtkAlign.START);
|
||||||
|
messageLabel.setSelectable(true);
|
||||||
|
messageBox.add(messageLabel);
|
||||||
|
|
||||||
|
// import gtk.Image;
|
||||||
|
// Image d = new Image("/home/deavmi/Downloads/5207740.jpg");
|
||||||
|
// messageBox.add(d);
|
||||||
|
|
||||||
|
/* Add the message to the log */
|
||||||
|
textArea.add(messageBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uploadFileDialog(Button e)
|
||||||
|
{
|
||||||
|
import gtk.FileChooserDialog; /* TODO: Set parent */
|
||||||
|
FileChooserDialog fileChooser = new FileChooserDialog("Send file to "~username, null, FileChooserAction.OPEN);
|
||||||
|
fileChooser.run();
|
||||||
|
gprintln("Selected file: "~fileChooser.getFilename());
|
||||||
|
}
|
||||||
|
}
|
81
source/gui.d
81
source/gui.d
|
@ -21,7 +21,7 @@ import gtk.SearchEntry;
|
||||||
import gtk.Image;
|
import gtk.Image;
|
||||||
|
|
||||||
import Connection;
|
import Connection;
|
||||||
import Channel;
|
import areas.Channel;
|
||||||
import std.socket;
|
import std.socket;
|
||||||
|
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
@ -253,6 +253,16 @@ public class GUI : Thread
|
||||||
channelListButton.addOnClicked(&listChannels);
|
channelListButton.addOnClicked(&listChannels);
|
||||||
toolbar.add(channelListButton);
|
toolbar.add(channelListButton);
|
||||||
|
|
||||||
|
/* TODO: Join channel button */
|
||||||
|
ToolButton joinChannelButton = new ToolButton("");
|
||||||
|
joinChannelButton.setIconName("document-new");
|
||||||
|
joinChannelButton.setTooltipText("Join channel");
|
||||||
|
toolbar.add(joinChannelButton);
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Leave channel button */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -278,6 +288,18 @@ public class GUI : Thread
|
||||||
import std.string;
|
import std.string;
|
||||||
private void setStatusMessage(Entry f)
|
private void setStatusMessage(Entry f)
|
||||||
{
|
{
|
||||||
|
/* If there are no connections */
|
||||||
|
if(!connections.length)
|
||||||
|
{
|
||||||
|
import gtk.MessageDialog;
|
||||||
|
MessageDialog errorDialog = new MessageDialog(mainWindow, GtkDialogFlags.MODAL, GtkMessageType.ERROR, GtkButtonsType.CLOSE, false, "Cannot set status\n\nYou are not connected to a server");
|
||||||
|
errorDialog.setIconName("user-available");
|
||||||
|
// errorDialog.set
|
||||||
|
errorDialog.run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the current connection */
|
/* Get the current connection */
|
||||||
Connection currentConnection = connections[notebook.getCurrentPage()];
|
Connection currentConnection = connections[notebook.getCurrentPage()];
|
||||||
|
|
||||||
|
@ -398,6 +420,34 @@ public class GUI : Thread
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class JoinButtonCustom : Button
|
||||||
|
{
|
||||||
|
private Entry channelInputBox;
|
||||||
|
|
||||||
|
this(Entry channelInputBox)
|
||||||
|
{
|
||||||
|
/* Set the button's text to "Join" */
|
||||||
|
super("Join");
|
||||||
|
|
||||||
|
/* Set the handler for the button */
|
||||||
|
addOnClicked(&handler);
|
||||||
|
|
||||||
|
this.channelInputBox = channelInputBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handler(Button)
|
||||||
|
{
|
||||||
|
/* Get the current connection */
|
||||||
|
Connection currentConnection = connections[notebook.getCurrentPage()];
|
||||||
|
|
||||||
|
/* Get the name of the channel selected */
|
||||||
|
string channelSelected = channelInputBox.getText();
|
||||||
|
|
||||||
|
/* Join the channel on this connection */
|
||||||
|
currentConnection.joinChannel(channelSelected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List channels
|
* List channels
|
||||||
*
|
*
|
||||||
|
@ -414,6 +464,29 @@ public class GUI : Thread
|
||||||
ListBox channelsList = new ListBox();
|
ListBox channelsList = new ListBox();
|
||||||
win.add(new ScrolledWindow(channelsList));
|
win.add(new ScrolledWindow(channelsList));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: Temporary, REMOVE AFTWR TESTING (ADDED ON 27th of JAN 2021) */
|
||||||
|
Box box = new Box(GtkOrientation.HORIZONTAL, 1);
|
||||||
|
Entry customChannelEntry = new Entry();
|
||||||
|
box.packStart(customChannelEntry, 1, 1, 1);
|
||||||
|
box.add(new JoinButtonCustom(customChannelEntry));
|
||||||
|
channelsList.add(box);
|
||||||
|
|
||||||
|
/* If there are no available connections */
|
||||||
|
if(!connections.length)
|
||||||
|
{
|
||||||
|
import gtk.MessageDialog;
|
||||||
|
MessageDialog errorDialog = new MessageDialog(mainWindow, GtkDialogFlags.MODAL, GtkMessageType.ERROR, GtkButtonsType.CLOSE, false, "Cannot list channels\n\nYou are not connected to a server");
|
||||||
|
errorDialog.setIconName("user-available");
|
||||||
|
// errorDialog.set
|
||||||
|
errorDialog.run();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get the current connection */
|
/* Get the current connection */
|
||||||
Connection currentConnection = connections[notebook.getCurrentPage()];
|
Connection currentConnection = connections[notebook.getCurrentPage()];
|
||||||
|
|
||||||
|
@ -455,6 +528,10 @@ public class GUI : Thread
|
||||||
win.showAll();
|
win.showAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run when you select the 'Join' button next tio an already existing
|
||||||
|
* channel in the channels list
|
||||||
|
*/
|
||||||
private void selectChannel(Button s)
|
private void selectChannel(Button s)
|
||||||
{
|
{
|
||||||
/* Get the current connection */
|
/* Get the current connection */
|
||||||
|
@ -489,7 +566,7 @@ public class GUI : Thread
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
import gtk.MessageDialog;
|
import gtk.MessageDialog;
|
||||||
MessageDialog errorDialog = new MessageDialog(mainWindow, GtkDialogFlags.MODAL, GtkMessageType.ERROR, GtkButtonsType.CLOSE, false, "Cannot list channels\n\nYou are not connected to a server");
|
MessageDialog errorDialog = new MessageDialog(mainWindow, GtkDialogFlags.MODAL, GtkMessageType.ERROR, GtkButtonsType.CLOSE, false, "Cannot set prescence\n\nYou are not connected to a server");
|
||||||
errorDialog.setIconName("user-available");
|
errorDialog.setIconName("user-available");
|
||||||
// errorDialog.set
|
// errorDialog.set
|
||||||
errorDialog.run();
|
errorDialog.run();
|
||||||
|
|
Loading…
Reference in New Issue