Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
45 KB
Referenced Files
None
Subscribers
None
diff --git a/util/gui/lineedit.cpp b/util/gui/lineedit.cpp
index abbc28b8..31c8f8bc 100644
--- a/util/gui/lineedit.cpp
+++ b/util/gui/lineedit.cpp
@@ -1,258 +1,129 @@
#include "util/graphics/bitmap.h"
#include "util/font.h"
#include "lineedit.h"
#include "util/debug.h"
#include <iostream>
using namespace Gui;
static Global::stream_type & debug(int level){
Global::debug(level) << "[line edit] ";
return Global::debug(level);
}
-LineEdit::LineEdit() :
-currentSetFont(0),
-hAlignment(T_Middle),
-hAlignMod(T_Middle),
-vAlignment(T_Middle),
-inputTypeValue(inputGeneral),
-changed_(0),
-autoResizable(0),
-textX(0),
-textY(0),
-cursorX(0),
-cursorY(0),
-cursorIndex(0),
-textColor(Graphics::makeColor(0, 0, 0)),
-textSizeH(0),
-limit(0),
-blinkRate(500),
-blink(false),
-focused(false),
-changeCounter(0){
- cursorTime.reset();
-}
-
-LineEdit::~LineEdit(){
- if (focused){
- input.disable();
- }
-}
-
-void LineEdit::hookKey(int key, void (*callback)(void *), void * arg){
- input.addBlockingHandle(key, callback, arg);
-}
-
-bool LineEdit::didChanged(unsigned long long & counter){
- bool did = counter < changeCounter;
- counter = changeCounter;
- return did;
-}
-
-// If the font size changes
-void LineEdit::fontChange(){
- changed();
-}
-
-// Update
-void LineEdit::act(const Font & font){
- if (currentSetFont == NULL){
- currentSetFont = &font;
- }
- if (cursorTime.msecs() >= blinkRate){
- cursorTime.reset();
- blink = !blink;
- changed();
- }
- /*
- if ((blinkRate * 2) <= cursorTime.msecs()){
- cursorTime.reset();
- changed();
- }
- */
-
- if (input.doInput()){
- changed();
- cursorIndex = input.getText().size();
- }
-
- if (changed_){
- textSizeH = currentSetFont->getHeight();
- if (autoResizable) {
- location.setDimensions(textSizeH+2, currentSetFont->textLength(input.getText().c_str()) + 4);
+void drawBox(int radius, int x, int y, int width, int height, const Gui::ColorInfo & colors, const Graphics::Bitmap & where){
+ if (radius > 0){
+ if (colors.bodyAlpha < 255){
+ Graphics::Bitmap::transBlender(0,0,0,colors.bodyAlpha);
+ where.translucent().roundRectFill(radius, x, y, x+width, y+height, colors.body);
} else {
- if (hAlignMod==T_Left){
- if (currentSetFont->textLength(input.getText().c_str())>location.getWidth()){
- hAlignment = T_Right;
- } else {
- hAlignment = T_Left;
- }
- }
+ where.roundRectFill(radius, x, y, x+width, y+height, colors.body);
}
-
- switch (hAlignment) {
- case T_Left:
- textX = 2;
- cursorX = textX + currentSetFont->textLength(input.getText().substr(0,cursorIndex).c_str()) + 1;
- break;
- case T_Middle:
- textX = (location.getWidth()/2) - (currentSetFont->textLength(input.getText().c_str())/2);
- cursorX = (textX) + currentSetFont->textLength(input.getText().substr(0,cursorIndex).c_str()) + 1;
- break;
- case T_Right:
- textX = location.getWidth() - currentSetFont->textLength(input.getText().c_str());//(position.width - 1)-2;
- cursorX = location.getWidth() - currentSetFont->textLength(input.getText().substr(0, input.getText().length()-cursorIndex).c_str());
- break;
- case T_Bottom:
- case T_Top:
- break;
- }
-
- switch (vAlignment) {
- case T_Top:
- textY = 1;
- cursorY = 1;
- break;
- case T_Middle:
- textY = cursorY = (location.getHeight() - textSizeH-(5))/2;
- break;
- case T_Bottom:
- textY = (location.getHeight() - 1) - textSizeH - 1;
- cursorY = textY - textSizeH;
- break;
- case T_Right:
- case T_Left:
- break;
+
+ if (colors.borderAlpha < 255){
+ Graphics::Bitmap::transBlender(0,0,0,colors.borderAlpha);
+ where.translucent().roundRect(radius, x, y, x+width, y+height, colors.border);
+ } else {
+ where.roundRect(radius, x, y, x+width, y+height, colors.border);
}
-
- //textY++;
- //textX++;
- stable();
- }
-}
-
-// Draw
-void LineEdit::render(const Graphics::Bitmap & work){
-
- //Util::ReferenceCount<Graphics::Bitmap> workArea = checkWorkArea(work);
- Graphics::Bitmap workArea = Graphics::Bitmap(workArea, location.getX(), location.getY(), location.getWidth(), location.getHeight());
-
- /* Check if we are using a rounded box */
- if (transforms.getRadius() > 0){
- workArea.translucent(0, 0, 0, colors.bodyAlpha).roundRectFill((int)transforms.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
- workArea.translucent(0, 0, 0, colors.borderAlpha).roundRect((int)transforms.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
} else {
- workArea.translucent(0, 0, 0, colors.bodyAlpha).rectangleFill(0, 0, location.getWidth()-1, location.getHeight()-1, colors.body);
- workArea.translucent(0, 0, 0, colors.borderAlpha).rectangle(0, 0, location.getWidth()-1, location.getHeight()-1, colors.border);
- }
-
- if (currentSetFont){
- currentSetFont->printf(textX, textY, textColor, workArea, input.getText(), 0);
- }
-
- if (focused){
- if (blink){
- workArea.line(cursorX, cursorY, cursorX, cursorY+textSizeH-5, textColor);
+ if (colors.bodyAlpha < 255){
+ Graphics::Bitmap::transBlender(0,0,0,colors.bodyAlpha);
+ where.translucent().rectangleFill(x, y, x+width, y+height, colors.body);
+ } else {
+ where.rectangleFill(x, y, x+width, y+height, colors.body);
}
- }
-}
-
-// Set text
-void LineEdit::setText(const std::string & text){
- input.setText(text);
- if (limit!=0) {
- if (input.getText().length() > limit) {
- while (input.getText().length() > limit){
- // currentSetText.erase(currentSetText.begin()+currentSetText.length()-1);
- }
+ if (colors.borderAlpha < 255){
+ Graphics::Bitmap::transBlender(0,0,0,colors.borderAlpha);
+ where.translucent().rectangle(x, y, x+width, y+height, colors.border);
+ } else {
+ where.rectangle(x, y, x+width, y+height, colors.border);
}
}
- cursorIndex = input.getText().length();
- changed();
}
-
-//! Get text
-const std::string LineEdit::getText(){
- return input.getText();
-}
-
-//! Clear text
-void LineEdit::clearText(){
- input.clearInput();
- cursorIndex=0;
- changed();
+LineEdit::LineEdit():
+blinkRate(60),
+cursorTime(0),
+changed(false){
+ colors.body = Graphics::makeColor(0,0,60);
+ colors.border = Graphics::makeColor(0,0,20);
+ colors.bodyAlpha = colors.borderAlpha = 150;
+ textColor = Graphics::makeColor(255,255,255);
+ cursorColor = Graphics::makeColor(128,128,128);
+ transforms.setRadius(10);
+ input.enable();
}
-//! Set text limit
-void LineEdit::setLimit(unsigned int l){
- limit = l;
- if (limit!=0){
- if (input.getText().length()>limit){
- while (input.getText().length()>limit){
- // currentSetText.erase(currentSetText.begin()+currentSetText.length()-1);
- }
- }
- }
- cursorIndex = input.getText().length();
- changed();
-}
-
-// Set Horizontal Alignment
-void LineEdit::setHorizontalAlign(const textAlign & a){
- hAlignment = hAlignMod = a;
- changed();
-}
-
-// Set Vertical Alignment
-void LineEdit::setVerticalAlign(const textAlign & a){
- vAlignment = a;
- changed();
+LineEdit::~LineEdit(){
}
-//! Set the type of input default general
-void LineEdit::setInputType(const inputType i){
- inputTypeValue = i;
-}
-
-// Set textColor
void LineEdit::setTextColor(const Graphics::Color color){
textColor = color;
}
-//! Set textColor
void LineEdit::setCursorColor(const Graphics::Color color){
- textColor = color;
+ cursorColor = color;
}
-// Set font
-void LineEdit::setFont(const Font *f){
- currentSetFont = f;
- if (currentSetFont) changed();
+void LineEdit::act(const Font &){
+ if (input.doInput()){
+ changed = true;
+ } else {
+ changed = false;
+ }
+ cursorTime++;
+ if (cursorTime > blinkRate*2){
+ cursorTime = 0;
+ }
}
-// Set autoResizeable
-void LineEdit::setAutoResize(bool r){
- autoResizable = r;
+void LineEdit::draw(const Font & font, const Graphics::Bitmap & work){
+
+ Graphics::Bitmap temp = Graphics::Bitmap(work, location.getX(), location.getY(), location.getWidth(), location.getHeight());
+
+ drawBox(10, 0, 0, location.getWidth(), location.getHeight(), colors, temp);
+
+ Graphics::Bitmap textTemp = Graphics::Bitmap(temp, 10, 0, temp.getWidth()-10, temp.getHeight());
+ int fontLength = font.textLength(input.getText().c_str());
+ if (fontLength >= textTemp.getWidth()){
+ font.printf(textTemp.getWidth()-10 - fontLength, 0, textColor, textTemp, input.getText(), 0);
+ renderCursor(textTemp.getWidth()-11, 0, font, textTemp);
+ } else {
+ font.printf(0, 0, textColor, textTemp, input.getText(), 0);
+ renderCursor(fontLength+1, 0, font, textTemp);
+ }
}
-// Set the cursor blink rate in miliseconds (default 500)
-void LineEdit::setCursorBlinkRate(unsigned int msecs){
- blinkRate = msecs;
+void LineEdit::render(const Graphics::Bitmap &){
}
-//! set Focus
-void LineEdit::setFocused(bool focus){
- focused = focus;
- if (focus){
- input.enable();
+void LineEdit::toggleEnabled(){
+ if (input.isEnabled()){
+ input.disable();
} else {
+ input.enable();
+ }
+}
+
+void LineEdit::setFocused(bool enabled){
+ if (enabled){
input.disable();
+ } else {
+ input.enable();
}
}
-//! check Focus
-bool LineEdit::isFocused(){
- return focused;
+void LineEdit::addHook(int key, void (*callback)(void *), void * arg){
+ input.addBlockingHandle(key, callback, arg);
+}
+
+bool LineEdit::didChanged(unsigned long long &){
+ return changed;
+}
+
+void LineEdit::renderCursor(int x, int y, const Font & font, const Graphics::Bitmap & work){
+ if (cursorTime <= blinkRate){
+ font.printf(x, y, cursorColor, work, "|", 0);
+ }
}
diff --git a/util/gui/lineedit.h b/util/gui/lineedit.h
index 1d5443a5..98a2f395 100644
--- a/util/gui/lineedit.h
+++ b/util/gui/lineedit.h
@@ -1,174 +1,78 @@
#ifndef paintown_gui_lineedit_h
#define paintown_gui_lineedit_h
#include <iostream>
#include <vector>
#include "widget.h"
#include "timer.h"
#include "util/input/text-input.h"
class Font;
class keys;
namespace Gui{
class LineEdit: public Widget{
public:
- //! enumerator housing alignment positions
- enum textAlign {
- T_Left = 0,
- T_Middle,
- T_Right,
- T_Top,
- T_Bottom
- };
-
- //! enumerator housing alignment positions
- enum inputType {
- inputGeneral = 0,
- inputAllCaps,
- inputNoCaps,
- inputNumerical
- };
-
//! Constructor
LineEdit();
//! Destructor
virtual ~LineEdit();
- //! Set text
- void setText(const std::string & text);
-
- //! Get text
- const std::string getText();
-
- //! Clear text
- void clearText();
-
- //! Set text limit (default 0, no limit)
- void setLimit(unsigned int l);
-
- void hookKey(int key, void (*callback)(void *), void * arg);
-
- //! Set Horizontal Alignment
- void setHorizontalAlign(const textAlign & a);
-
- //! Set Vertical Alignment
- void setVerticalAlign(const textAlign & a);
-
- //! Set the type of input default general
- void setInputType(const inputType i = inputGeneral);
-
//! Set textColor
void setTextColor(const Graphics::Color color);
//! Set textColor
void setCursorColor(const Graphics::Color color);
- //! Set font
- void setFont(const Font *f);
-
- //! Set autoResizeable
- void setAutoResize(bool r);
-
- //! Set the cursor blink rate in miliseconds (default 500)
- void setCursorBlinkRate(unsigned int msecs);
-
//! Update
void act(const Font &);
//! Draw
- using Widget::render;
+ void draw(const Font &, const Graphics::Bitmap &);
+
+ //! Render
+ using Gui::Widget::render;
void render(const Graphics::Bitmap &);
- //! set Focus
- void setFocused(bool focus);
-
- //! check Focus
- bool isFocused();
-
- bool didChanged( unsigned long long & counter );
-
+ virtual void toggleEnabled();
+
+ virtual void setFocused(bool enabled);
+
+ virtual void addHook(int key, void (*callback)(void *), void * arg);
+
+ virtual bool didChanged(unsigned long long &);
+
+ virtual inline const std::string getText() const {
+ return this->input.getText();
+ }
+
+ virtual inline void setText(const std::string & text){
+ this->input.setText(text);
+ }
+
+ virtual inline void clear(){
+ this->input.clearInput();
+ }
+
+ virtual inline void setBlinkRate(int rate){
+ this->blinkRate = rate;
+ }
+
protected:
- //! Current font the label is currently using (uses systemFont by default)
- const Font *currentSetFont;
-
- //! Current set text
- // std::string currentSetText;
-
- //! Horizontal Alignment (RIGHT, MIDDLE, LEFT)
- textAlign hAlignment;
-
- //! Additional checker for Horizontal alignment for easy adjustment
- textAlign hAlignMod;
-
- //! Vertical Alignment (TOP, MIDDLE, BOTTOM)
- textAlign vAlignment;
-
- //! Input type
- inputType inputTypeValue;
-
- //! Has changed?
- bool changed_;
-
- //! Auto resize
- bool autoResizable;
-
- //! Text horizontal position
- int textX;
-
- //! Text vertical position
- int textY;
-
- //! Cursor horizontal position
- int cursorX;
-
- //! Cursor vertical position
- int cursorY;
-
- //! Cursor index relative to the string
- unsigned int cursorIndex;
-
- //! Text color
+ void renderCursor(int x, int y, const Font &, const Graphics::Bitmap &);
Graphics::Color textColor;
-
- //! Text size Height check in case it changes
- int textSizeH;
-
- //! Text limit
- unsigned int limit;
-
- //! Cursor timer
- guiTimer cursorTime;
-
- //! Cursor blink rate
- unsigned int blinkRate;
- bool blink;
-
- //! Focused?
- bool focused;
-
+ Graphics::Color cursorColor;
TextInput input;
-
- // keeps track of changes
- unsigned long long changeCounter;
-
- //! If the font size changes
- void fontChange();
-
- inline void changed(){
- changed_ = true;
- changeCounter += 1;
- }
-
- inline void stable(){
- changed_ = false;
- }
+ int blinkRate;
+ int cursorTime;
+
+ bool changed;
};
}
#endif
diff --git a/util/network/irc.cpp b/util/network/irc.cpp
index 2041ad8a..a64b8a15 100644
--- a/util/network/irc.cpp
+++ b/util/network/irc.cpp
@@ -1,635 +1,642 @@
#include "irc.h"
#include "util/font.h"
#include "util/regex.h"
#include "util/graphics/bitmap.h"
#include "util/configuration.h"
#include <stdexcept>
namespace Network{
namespace IRC{
static Command::Type convertCommand(const std::string & cmd){
Command::Type command = Command::Unknown;
if (cmd == "PASS"){
command = Command::Pass;
} else if (cmd == "NICK"){
command = Command::Nick;
} else if (cmd == "USER"){
command = Command::User;
} else if (cmd == "SERVER"){
command = Command::Server;
} else if (cmd == "OPER"){
command = Command::Oper;
} else if (cmd == "QUIT"){
command = Command::Quit;
} else if (cmd == "SQUIT"){
command = Command::Squit;
} else if (cmd == "JOIN"){
command = Command::Join;
} else if (cmd == "PART"){
command = Command::Part;
} else if (cmd == "MODE"){
command = Command::Mode;
} else if (cmd == "TOPIC"){
command = Command::Topic;
} else if (cmd == "NAMES"){
command = Command::Names;
} else if (cmd == "LIST"){
command = Command::List;
} else if (cmd == "INVITE"){
command = Command::Invite;
} else if (cmd == "KICK"){
command = Command::Kick;
} else if (cmd == "VERSION"){
command = Command::Version;
} else if (cmd == "STATS"){
command = Command::Stats;
} else if (cmd == "LINKS"){
command = Command::Links;
} else if (cmd == "TIME"){
command = Command::Time;
} else if (cmd == "CONNECT"){
command = Command::Connect;
} else if (cmd == "TRACE"){
command = Command::Trace;
} else if (cmd == "ADMIN"){
command = Command::Admin;
} else if (cmd == "INFO"){
command = Command::Info;
} else if (cmd == "PRIVMSG"){
command = Command::PrivateMessage;
} else if (cmd == "NOTICE"){
command = Command::Notice;
} else if (cmd == "WHO"){
command = Command::Who;
} else if (cmd == "WHOIS"){
command = Command::Whois;
} else if (cmd == "WHOWAS"){
command = Command::Whowas;
} else if (cmd == "KILL"){
command = Command::Kill;
} else if (cmd == "PING"){
command = Command::Ping;
} else if (cmd == "PONG"){
command = Command::Pong;
} else if (cmd == "ERROR"){
command = Command::Error;
} else if (cmd == "433"){
command = Command::ErrorNickInUse;
} else if (cmd == "401"){
command = Command::ErrorNoSuchNick;
} else if (cmd == "403"){
command = Command::ErrorNoSuchChannel;
} else if (cmd == "461"){
command = Command::ErrorNeedMoreParams;
} else if (cmd == "473"){
command = Command::ErrorInviteOnlyChannel;
} else if (cmd == "474"){
command = Command::ErrorBannedFromChannel;
} else if (cmd == "475"){
command = Command::ErrorBadChannelKey;
} else if (cmd == "471"){
command = Command::ErrorChannelIsFull;
} else if (cmd == "331"){
command = Command::ReplyNoTopic;
} else if (cmd == "332"){
command = Command::ReplyTopic;
} else if (cmd == "333"){
command = Command::ReplyTopicAuthor;
} else if (cmd == "353"){
command = Command::ReplyNames;
} else if (cmd == "366"){
command = Command::ReplyNamesEndOf;
} else if (cmd == "372"){
command = Command::ReplyMOTD;
} else if (cmd == "375"){
command = Command::ReplyMOTDStart;
} else if (cmd == "376"){
command = Command::ReplyMOTDEndOf;
}
return command;
}
static std::string convertCommand(const Command::Type & cmd){
switch (cmd){
case Command::Pass: return "PASS";
case Command::Nick: return "NICK";
case Command::User: return "USER";
case Command::Server: return "SERVER";
case Command::Oper: return "OPER";
case Command::Quit: return "QUIT";
case Command::Squit: return "SQUIT";
case Command::Join: return "JOIN";
case Command::Part: return "PART";
case Command::Mode: return "MODE";
case Command::Topic: return "TOPIC";
case Command::Names: return "NAMES";
case Command::List: return "LIST";
case Command::Invite: return "INVITE";
case Command::Kick: return "KICK";
case Command::Version: return "VERSION";
case Command::Stats: return "STATS";
case Command::Links: return "LINKS";
case Command::Time: return "TIME";
case Command::Connect: return "CONNECT";
case Command::Trace: return "TRACE";
case Command::Admin: return "ADMIN";
case Command::Info: return "INFO";
case Command::PrivateMessage: return "PRIVMSG";
case Command::Notice: return "NOTICE";
case Command::Who: return "WHO";
case Command::Whois: return "WHOIS";
case Command::Whowas: return "WHOAS";
case Command::Kill: return "KILL";
case Command::Ping: return "PING";
case Command::Pong: return "PONG";
case Command::Error: return "ERROR";
case Command::Unknown:
default:
break;
}
return "";
}
static std::vector<std::string> split(std::string str, char splitter){
std::vector<std::string> strings;
size_t next = str.find(splitter);
while (next != std::string::npos){
strings.push_back(str.substr(0, next));
str = str.substr(next+1);
next = str.find(splitter);
}
if (str != ""){
strings.push_back(str);
}
return strings;
}
Command::Command(const std::string & message){
std::vector< std::string > messageSplit = split(message, ' ');
std::vector< std::string >::iterator current = messageSplit.begin();
if (Util::matchRegex(*current, Util::Regex("^:.*"))){
// Found owner (":") indicates the user, otherwise it's going to be the command
// Grab just the username, ignore everything else
try{
owner = split(*current, '!').at(0).substr(1);
} catch (const std::out_of_range & ex){
}
current++;
}
// Next is the actual command
type = convertCommand(*current);
if (type == Unknown){
Global::debug(0) << "Got unhandled response: " << message << std::endl;
}
current++;
// Parameters
bool foundCtcp = false;
bool concactenate = false;
std::string concactenated;
for (std::vector< std::string >::iterator i = current; i != messageSplit.end(); ++i){
const std::string & parameter = *i;
// If there is a colon in the parameter the rest of split string is the whole parameter rejoin
if (Util::matchRegex(parameter, Util::Regex("^:\001.*")) && !foundCtcp){
foundCtcp = true;
// Drop the ':\001'
ctcp.push_back(parameter.substr(2));
continue;
} else if (Util::matchRegex(parameter, Util::Regex(".*\001")) && foundCtcp){
foundCtcp = false;
// Drop the '\001'
ctcp.push_back(parameter.substr(0, parameter.size()-1));
continue;
} else if (Util::matchRegex(parameter, Util::Regex("^:.*")) && !concactenate){
concactenate = true;
// Drop the ':'
concactenated += parameter.substr(1) + " ";
continue;
} else if (Util::matchRegex(parameter, Util::Regex("=")) ||
Util::matchRegex(parameter, Util::Regex("@"))){
// Ignore
continue;
}
if (concactenate){
concactenated += parameter + " ";
} else {
if (!foundCtcp){
parameters.push_back(parameter);
} else {
ctcp.push_back(parameter);
}
}
}
if (concactenate){
parameters.push_back(concactenated);
}
}
Command::Command(const std::string & owner, const Type & type):
owner(owner),
type(type){
}
Command::Command(const Command & copy):
owner(copy.owner),
type(copy.type),
parameters(copy.parameters),
ctcp(copy.ctcp){
}
Command::~Command(){
}
const Command & Command::operator=(const Command & copy){
owner = copy.owner;
type = copy.type;
parameters = copy.parameters;
ctcp = copy.ctcp;
return *this;
}
std::string Command::getSendable() const {
std::string sendable;
// Name
if (!owner.empty()){
sendable += ":" + owner + " ";
}
// Command
sendable += convertCommand(type) + " ";
// Params
/*for (std::vector<std::string>::const_iterator i = parameters.begin(); i != parameters.end(); ++i){
sendable+= *i + " ";
}*/
for (unsigned int i = 0; i < parameters.size(); ++i){
sendable += parameters[i] + (i < parameters.size()-1 ? " " : "");
}
// End
sendable += "\r\n";
return sendable;
}
Channel::Channel(){
}
Channel::Channel(const std::string & name):
name(name){
}
Channel::Channel(const Channel & copy):
name(copy.name),
topic(copy.topic),
topicAuthor(copy.topicAuthor),
topicDate(copy.topicDate),
users(copy.users){
}
Channel::~Channel(){
}
const Channel & Channel::operator=(const Channel & copy){
name = copy.name;
topic = copy.topic;
topicAuthor = copy.topicAuthor;
topicDate = copy.topicDate;
users = copy.users;
return *this;
}
void Channel::addUser(const std::string & user){
// Can't add same user twice
for (std::vector<std::string>::iterator i = users.begin(); i != users.end(); ++i){
const std::string & name = *i;
if (name == user){
return;
}
}
users.push_back(user);
}
void Channel::removeUser(const std::string & user){
for (std::vector<std::string>::iterator i = users.begin(); i != users.end(); ++i){
const std::string & name = *i;
if (name == user){
users.erase(i);
break;
}
}
}
void Channel::addUsers(const std::vector<std::string> & list){
for (std::vector<std::string>::const_iterator i = list.begin(); i != list.end(); ++i){
const std::string & name = *i;
addUser(name);
}
}
Client::Client(const std::string & hostname, int port):
previousUsername("AUTH"),
username("AUTH"),
previousActiveChannel(0),
currentChannel(0),
hostname(hostname),
port(port),
end(false){
}
Client::~Client(){
}
void Client::connect(){
if (username.empty()){
throw NetworkException("Set username first.");
}
Global::debug(0) << "Connecting to " << hostname << " on port " << port << std::endl;
socket = Network::connectReliable(hostname, port);
start();
setName("paintown-test");
Command user("AUTH", Command::User);
user.setParameters(username, "*", "0", ":auth");
sendCommand(user);
// ^^^^^^^^ Should get a response from this crap!
joinChannel("#paintown");
Global::debug(0) << "Connected" << std::endl;
}
bool Client::hasCommands() const{
::Util::Thread::ScopedLock scope(lock);
return !commands.empty();
}
Command Client::nextCommand() const {
::Util::Thread::ScopedLock scope(lock);
Command command = commands.front();
commands.pop();
return command;
}
void Client::sendCommand(const Command & command){
const std::string & sendable = command.getSendable();
Network::sendBytes(socket, (uint8_t *) sendable.c_str(), sendable.size());
}
void Client::sendCommand(const Command::Type & type){
Command command(username, type);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1){
Command command(username, type);
command.setParameters(param1);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1, const std::string & param2){
Command command(username, type);
command.setParameters(param1, param2);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1, const std::string & param2, const std::string & param3){
Command command(username, type);
command.setParameters(param1, param2, param3);
sendCommand(command);
}
void Client::sendCommand(const Command::Type & type, const std::string & param1, const std::string & param2, const std::string & param3, const std::string & param4){
Command command(username, type);
command.setParameters(param1, param2, param3, param4);
sendCommand(command);
}
void Client::setName(const std::string & name){
previousUsername = username;
// Update channel list
//channel.removeUser(username);
//channel.addUser(name);
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
activeChannel->removeUser(username);
activeChannel->addUser(name);
}
username = name;
sendCommand(Command::Nick, name);
}
void Client::joinChannel(const std::string & chan){
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
if (activeChannel->getName() == chan){
// Already belonging to this channel
return;
}
}
previousActiveChannel = currentChannel;
ChannelPointer newChannel = ChannelPointer(new Channel(chan));
/*if (!currentChannel.getName().empty()){
sendCommand(Command::Part, currentChannel.getName());
}*/
activeChannels.push_back(newChannel);
currentChannel = activeChannels.size()-1;
sendCommand(Command::Join, getChannel()->getName());
}
std::string Client::channelListAsString(){
std::string list;
for (std::vector<ChannelPointer>::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
list += activeChannel->getName() + ", ";
}
return list.substr(0, list.size()-2);
}
unsigned int Client::getChannelIndex(const std::string & channel){
for (unsigned int i = 0; i < activeChannels.size(); ++i){
if (activeChannels[i]->getName() == channel){
return i;
}
}
return 0;
}
bool Client::isCurrentChannel(const std::string & channel){
return (activeChannels[currentChannel]->getName() == channel);
}
void Client::setChannel(unsigned int channel){
if (channel >= activeChannels.size()){
return;
}
currentChannel = channel;
}
void Client::nextChannel(){
currentChannel = (currentChannel + 1) % activeChannels.size();
}
void Client::previousChannel(){
if (currentChannel == 0){
currentChannel = activeChannels.size()-1;
} else {
currentChannel--;
}
}
void Client::removeChannel(const std::string & name){
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
if (activeChannel->getName() == name){
activeChannels.erase(i);
return;
}
}
}
ChannelPointer Client::findChannel(const std::string & name){
for (std::vector< ChannelPointer >::iterator i = activeChannels.begin(); i != activeChannels.end(); ++i){
ChannelPointer activeChannel = *i;
if (activeChannel->getName() == name){
return activeChannel;
}
}
return ChannelPointer(NULL);
}
void Client::sendMessage(const std::string & msg){
sendCommand(Command::PrivateMessage, getChannel()->getName(), ":" + msg);
}
void Client::sendPong(const Command & ping){
Command pong(username, Command::Pong);
pong.setParameters(ping.getParameters());
sendCommand(pong);
}
std::string Client::readMessage(){
std::string received;
bool foundReturn = false;
while (true){
try {
char nextCharacter = Network::read8(socket);
/* NOTE the latest RFC says that either \r or \n is the end of the message
* http://www.irchelp.org/irchelp/rfc/chapter8.html
*/
if (nextCharacter == '\r'){
// Found return
foundReturn = true;
continue;
} else if ((nextCharacter == '\n') && foundReturn){
// Should be the end of the message assuming \r is before it
break;
}
received += nextCharacter;
} catch (const Network::MessageEnd & ex){
// end of message get out
throw ex;
}
}
//Global::debug(0) << "Read next string: " << received << std::endl;
return received;
}
void Client::checkResponseAndHandle(const Command & command){
// Checks for username or channel errors
if (command.getType() == Command::ErrorNickInUse){
::Util::Thread::ScopedLock scope(lock);
// Change the username back to what it was
getChannel()->removeUser(username);
username = previousUsername;
getChannel()->addUser(username);
} else if (command.getType() == Command::ErrorBannedFromChannel ||
command.getType() == Command::ErrorInviteOnlyChannel ||
command.getType() == Command::ErrorBadChannelKey ||
command.getType() == Command::ErrorChannelIsFull ||
command.getType() == Command::ErrorNoSuchChannel){
::Util::Thread::ScopedLock scope(lock);
// Revert old channel
removeChannel(getChannel()->getName());
currentChannel = previousActiveChannel;
} else if (command.getType() == Command::ReplyTopic){
::Util::Thread::ScopedLock scope(lock);
// Set topic
getChannel()->setTopic(command.getParameters().at(2));
} else if (command.getType() == Command::ReplyTopicAuthor){
::Util::Thread::ScopedLock scope(lock);
// Set topic and author
const std::vector<std::string> & params = command.getParameters();
getChannel()->setTopicAuthor(split(params.at(1), '!').at(0), atoi(params.at(2).c_str()));
} else if (command.getType() == Command::ReplyNames){
// Add names
const std::vector<std::string> & params = command.getParameters();
//if (params.at(1) == currentChannel->getName()){
const std::vector<std::string> & names = split(params.at(2), ' ');
::Util::Thread::ScopedLock scope(lock);
//currentChannel->addUsers(names);
ChannelPointer update = findChannel(params.at(1));
if (update != NULL){
update->addUsers(names);
}
//}
}
}
void Client::run(){
while (!end){
try {
const std::string & message = readMessage();
// Check if the message is empty it might be because of (\n)
if (!message.empty()){
Command command(message);
::Util::Thread::ScopedLock scope(lock);
checkResponseAndHandle(command);
commands.push(command);
} else {
}
} catch (const Network::MessageEnd & ex){
end = true;
}
}
}
-ChatInterface::ChatInterface(const std::string & host, int port){
+ChatInterface::ChatInterface(const std::string & host, int port):
+widthRatio(.8),
+heightRatio(.92){
//client = Util::ReferenceCount< Client >(new Client(host, port));
//client->connect();
// Setup window size and chat list
- int width = Configuration::getScreenWidth();
- int height = Configuration::getScreenHeight();
+ const int width = Configuration::getScreenWidth();
+ const int height = Configuration::getScreenHeight();
- Global::debug(0) << "Current Height: " << height * .8 << " Current Width: " << width *.09 << std::endl;
-
- // chat panel 80% width 90% height
- chatBox.location.set(0, 0, 0, 0);
- chatBox.location.setDimensions(width * .8, height * .9);
- // edit box
- inputBox.location.set(0, height * .91, 0, 0);
- inputBox.location.setDimensions(width * .8, height * .09);
- // Set the location of user list width * .8 and height
+ // chat panel widthRatio% heightRatio%
+ chatBox.location.setPosition(Gui::AbsolutePoint(0, 0));
+ chatBox.location.setDimensions(width * widthRatio, height * heightRatio);
+ // edit box widthRatio% remaining (heightRatio + .01)%
+ const double inputStart = heightRatio + .01;
+ inputBox.location.setPosition(Gui::AbsolutePoint(0, height * inputStart));
+ inputBox.location.setDimensions(width * widthRatio, height * (1 - inputStart));
+ // Set the location of user list width * widthRatio and height
}
ChatInterface::~ChatInterface(){
}
void ChatInterface::act(){
- chatBox.act(Font::getDefaultFont());
- inputBox.act(Font::getDefaultFont());
+ // Default size of fonts
+ const int size = Configuration::getScreenHeight() * (1 - (heightRatio + .01));
+ // Size is important
+ const Font & font = Font::getDefaultFont(size, size);
+ chatBox.act(font);
+ inputBox.act(font);
}
void ChatInterface::draw(const Graphics::Bitmap & work){
+ const int size = Configuration::getScreenHeight() * (1 - (heightRatio + .01));
+ const Font & font = Font::getDefaultFont(size, size);
chatBox.render(work);
- inputBox.render(work);
+ inputBox.draw(font, work);
}
Util::ReferenceCount<Client> ChatInterface::getClient(){
return client;
}
}
}
diff --git a/util/network/irc.h b/util/network/irc.h
index 4212a957..5d4d3557 100644
--- a/util/network/irc.h
+++ b/util/network/irc.h
@@ -1,274 +1,284 @@
#ifndef _util_network_irc_h
#define _util_network_irc_h
#include "network.h"
#include "chat.h"
#include "util/pointer.h"
#include "util/thread.h"
#include "util/gui/tabbed-box.h"
#include "util/gui/lineedit.h"
#include <string>
#include <vector>
#include <queue>
namespace Network{
namespace IRC{
class Command{
public:
enum Type{
Unknown,
Pass,
Nick,
User,
Server,
Oper,
Quit,
Squit,
Join,
Part,
Mode,
Topic,
Names,
List,
Invite,
Kick,
Version,
Stats,
Links,
Time,
Connect,
Trace,
Admin,
Info,
PrivateMessage,
Notice,
Who,
Whois,
Whowas,
Kill,
Ping,
Pong,
Error,
ErrorNickInUse,
ErrorNoSuchNick,
ErrorNoSuchChannel,
ErrorNeedMoreParams,
ErrorBannedFromChannel,
ErrorInviteOnlyChannel,
ErrorBadChannelKey,
ErrorChannelIsFull,
ReplyNames,
ReplyNamesEndOf,
ReplyNoTopic,
ReplyTopic,
ReplyTopicAuthor,
ReplyMOTD,
ReplyMOTDStart,
ReplyMOTDEndOf,
};
// Initializes it from an incoming message off of socket
Command(const std::string &);
// Create a message with owner and type
Command(const std::string &, const Type &);
Command(const Command &);
virtual ~Command();
virtual const Command & operator=(const Command &);
virtual std::string getSendable() const;
virtual inline const std::string & getOwner() const {
return this->owner;
}
virtual inline const Type & getType() const {
return this->type;
}
virtual inline void setParameters(const std::string & param1){
this->parameters.clear();
this->parameters.push_back(param1);
}
virtual inline void setParameters(const std::string & param1, const std::string & param2){
this->parameters.clear();
this->parameters.push_back(param1);
this->parameters.push_back(param2);
}
virtual inline void setParameters(const std::string & param1, const std::string & param2, const std::string & param3){
this->parameters.clear();
this->parameters.push_back(param1);
this->parameters.push_back(param2);
this->parameters.push_back(param3);
}
virtual inline void setParameters(const std::string & param1, const std::string & param2, const std::string & param3, const std::string & param4){
this->parameters.clear();
this->parameters.push_back(param1);
this->parameters.push_back(param2);
this->parameters.push_back(param3);
this->parameters.push_back(param4);
}
virtual inline void setParameters(const std::vector< std::string > & params){
this->parameters = params;
}
virtual inline const std::vector< std::string > & getParameters() const {
return this->parameters;
}
virtual inline bool hasCtcp() {
return !this->ctcp.empty();
}
virtual inline const std::vector< std::string > & getCtcp() const {
return this->ctcp;
}
protected:
std::string owner;
Type type;
std::vector< std::string > parameters;
std::vector< std::string > ctcp;
};
class Channel{
public:
Channel();
Channel(const std::string &);
Channel(const Channel &);
~Channel();
const Channel & operator=(const Channel &);
void addUser(const std::string &);
void removeUser(const std::string &);
void addUsers(const std::vector<std::string> &);
inline const std::vector<std::string> & getUsers() const{
return this->users;
}
inline const std::string & getName() const {
return this->name;
}
inline void setTopic(const std::string & topic){
this->topic = topic;
}
inline void setTopicAuthor(const std::string & topicAuthor, uint64_t topicDate){
this->topicAuthor = topicAuthor;
this->topicDate = topicDate;
}
protected:
std::string name;
std::string topic;
std::string topicAuthor;
uint64_t topicDate;
std::vector<std::string> users;
};
// Channel ReferenceCount
typedef Util::ReferenceCount<Channel> ChannelPointer;
class Client : public Chat::Threadable{
public:
Client(const std::string &, int port);
virtual ~Client();
virtual void connect();
virtual void run();
virtual bool hasCommands() const;
virtual Command nextCommand() const;
virtual void sendCommand(const Command &);
virtual void sendCommand(const Command::Type &);
virtual void sendCommand(const Command::Type &, const std::string &);
virtual void sendCommand(const Command::Type &, const std::string &, const std::string &);
virtual void sendCommand(const Command::Type &, const std::string &, const std::string &, const std::string &);
virtual void sendCommand(const Command::Type &, const std::string &, const std::string &, const std::string &, const std::string &);
virtual void setName(const std::string &);
virtual inline const std::string & getName() const {
return this->username;
}
virtual void joinChannel(const std::string &);
virtual inline ChannelPointer getChannel() const {
return this->activeChannels[this->currentChannel];
}
virtual inline std::vector< ChannelPointer > & channelList(){
return this->activeChannels;
}
virtual std::string channelListAsString();
virtual unsigned int getChannelIndex(const std::string &);
virtual bool isCurrentChannel(const std::string &);
virtual void setChannel(unsigned int channel);
virtual void nextChannel();
virtual void previousChannel();
virtual void sendMessage(const std::string &);
virtual void sendPong(const Command &);
protected:
void removeChannel(const std::string &);
ChannelPointer findChannel(const std::string &);
std::string readMessage();
//! Doesn't do anything to the command just handle some internal changes like username and channel stuff
void checkResponseAndHandle(const Command &);
Network::Socket socket;
std::string previousUsername;
std::string username;
unsigned int previousActiveChannel;
unsigned int currentChannel;
std::vector< ChannelPointer > activeChannels;
std::string hostname;
int port;
bool end;
mutable std::queue< Command > commands;
};
// Create a tabbed chatter to implement in games
class ChatInterface{
public:
ChatInterface(const std::string &, int port);
virtual ~ChatInterface();
void act();
void draw(const Graphics::Bitmap &);
Util::ReferenceCount<Client> getClient();
+
+ inline void setWidthRatio(double ratio){
+ this->widthRatio = ratio;
+ }
+ inline void setHeightRatio(double ratio){
+ this->heightRatio = ratio;
+ }
+
protected:
Util::ReferenceCount<Client> client;
Gui::TabbedBox chatBox;
Gui::LineEdit inputBox;
+ double widthRatio;
+ double heightRatio;
};
}// end irc
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 16, 12:29 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71310
Default Alt Text
(45 KB)

Event Timeline