Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
19 KB
Referenced Files
None
Subscribers
None
diff --git a/util/gui/lineedit.cpp b/util/gui/lineedit.cpp
index 14dcbdbd..1a722364 100644
--- a/util/gui/lineedit.cpp
+++ b/util/gui/lineedit.cpp
@@ -1,360 +1,362 @@
#include "util/bitmap.h"
#include "util/trans-bitmap.h"
#include "util/font.h"
#include "lineedit.h"
#include "keys.h"
#include "globals.h"
#include "util/debug.h"
#include <iostream>
using namespace Gui;
static std::ostream & 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(0),
textSizeH(0),
limit(0),
blinkRate(500),
blink(false),
focused(false),
changeCounter(0){
cursorTime.reset();
}
-LineEdit::~LineEdit()
-{
+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 (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);
} else {
if (hAlignMod==T_Left){
if (currentSetFont->textLength(input.getText().c_str())>location.getWidth()){
hAlignment = T_Right;
} else {
hAlignment = T_Left;
}
}
}
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;
}
//textY++;
//textX++;
stable();
}
}
// Draw
void LineEdit::render(const Graphics::Bitmap & work){
checkWorkArea();
// Check if we are using a rounded box
if (location.getRadius()>0) {
Graphics::Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
roundRectFill( *workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
workArea->translucent().draw(location.getX(),location.getY(),work);
workArea->fill(Graphics::makeColor(255,0,255));
Graphics::Bitmap::transBlender( 0, 0, 0, colors.borderAlpha );
roundRect( *workArea, (int)location.getRadius(), 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border );
workArea->translucent().draw(location.getX(),location.getY(),work);
} else {
Graphics::Bitmap::transBlender( 0, 0, 0, colors.bodyAlpha );
workArea->rectangleFill( 0, 0, location.getWidth()-1, location.getHeight()-1, colors.body );
workArea->translucent().draw(location.getX(),location.getY(),work);
workArea->fill(Graphics::makeColor(255,0,255));
Graphics::Bitmap::transBlender( 0, 0, 0, colors.borderAlpha );
workArea->rectangle( 0, 0, location.getWidth()-1, location.getHeight()-1, colors.border );
workArea->translucent().draw(location.getX(),location.getY(),work);
}
// work.drawingMode( Bitmap::MODE_SOLID );
workArea->fill(Graphics::makeColor(255,0,255));
if (currentSetFont){
currentSetFont->printf(textX,textY,textColor,*workArea, input.getText(), 0);
}
if (focused){
/*
if (cursorTime.msecs() <= blinkRate){
workArea->line(cursorX,cursorY,cursorX,cursorY+textSizeH-5,textColor);
}
*/
if (blink){
workArea->line(cursorX,cursorY,cursorX,cursorY+textSizeH-5,textColor);
}
}
workArea->draw(location.getX(), location.getY(), work);
}
#if 0
// Keypresses
sigslot::slot LineEdit::keyPress(const keys &k)
{
debug( 5 ) << "Received key press " << k.getValue() << std::endl;
if(focused)
{
if(k.isCharacter())
{
char keyValue = k.getValue();
bool addValue = false;
switch(inputTypeValue){
case inputNumerical:
if ( k.isNumber() ) addValue = !addValue;
break;
case inputNoCaps:
keyValue = tolower(keyValue);
addValue = !addValue;
break;
case inputAllCaps:
keyValue = toupper(keyValue);
addValue = !addValue;
break;
case inputGeneral:
default:
addValue = !addValue;
break;
}
if(addValue){
if(limit!=0)
{
if(currentSetText.length()<limit)
{
//currentSetText += k.getValue();
currentSetText.insert(cursorIndex, std::string(1,keyValue));
++cursorIndex;
changed();
}
}
else
{
//currentSetText += k.getValue();
currentSetText.insert(cursorIndex, std::string(1,keyValue));
++cursorIndex;
changed();
}
}
}
else
{
switch(k.getValue())
{
case keys::DEL:
if(cursorIndex<currentSetText.length())
{
currentSetText.erase(cursorIndex,1);
}
break;
case keys::BACKSPACE:
if(cursorIndex>0)
{
currentSetText.erase(cursorIndex - 1, 1);
--cursorIndex;
}
break;
case keys::RIGHT:
if(cursorIndex<currentSetText.length())++cursorIndex;
break;
case keys::LEFT:
if(cursorIndex>0)--cursorIndex;
break;
case keys::INSERT:
break;
}
changed();
}
}
}
#endif
// 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);
}
}
}
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();
}
//! 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();
}
//! Set the type of input default general
void LineEdit::setInputType(const inputType i){
inputTypeValue = i;
}
// Set textColor
void LineEdit::setTextColor(const int color){
textColor = color;
}
//! Set textColor
void LineEdit::setCursorColor(const int color){
textColor = color;
}
// Set font
void LineEdit::setFont(const Font *f){
currentSetFont = f;
if (currentSetFont) changed();
}
// Set autoResizeable
void LineEdit::setAutoResize(bool r){
autoResizable = r;
}
// Set the cursor blink rate in miliseconds (default 500)
void LineEdit::setCursorBlinkRate(unsigned int msecs){
blinkRate = msecs;
}
//! set Focus
void LineEdit::setFocused(bool focus){
focused = focus;
if (focus){
input.enable();
} else {
input.disable();
}
}
//! check Focus
bool LineEdit::isFocused(){
return focused;
}
diff --git a/util/thread.cpp b/util/thread.cpp
index 8416038c..b8ce6be1 100644
--- a/util/thread.cpp
+++ b/util/thread.cpp
@@ -1,183 +1,199 @@
#include "thread.h"
namespace Util{
namespace Thread{
+
+LockObject::LockObject(){
+ initializeLock(&lock);
+}
+
+void LockObject::acquire(){
+ acquireLock(&lock);
+}
+
+void LockObject::release(){
+ releaseLock(&lock);
+}
+
+LockObject::~LockObject(){
+ destroyLock(&lock);
+}
bool isUninitialized(Id thread){
return thread == uninitializedValue;
}
#ifdef USE_SDL
Id uninitializedValue = NULL;
void initializeLock(Lock * lock){
*lock = SDL_CreateMutex();
}
int acquireLock(Lock * lock){
return SDL_LockMutex(*lock);
}
int releaseLock(Lock * lock){
return SDL_UnlockMutex(*lock);
}
void destroyLock(Lock * lock){
SDL_DestroyMutex(*lock);
}
void initializeSemaphore(Semaphore * semaphore, unsigned int value){
*semaphore = SDL_CreateSemaphore(value);
}
void destroySemaphore(Semaphore * semaphore){
SDL_DestroySemaphore(*semaphore);
}
void semaphoreDecrease(Semaphore * semaphore){
SDL_SemWait(*semaphore);
}
void semaphoreIncrease(Semaphore * semaphore){
SDL_SemPost(*semaphore);
}
bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg){
*thread = SDL_CreateThread(function, arg);
return *thread != NULL;
}
void joinThread(Id thread){
SDL_WaitThread(thread, NULL);
}
void cancelThread(Id thread){
#ifndef PS3
SDL_KillThread(thread);
#endif
}
#else
Id uninitializedValue = 0;
void initializeLock(Lock * lock){
pthread_mutex_init(lock, NULL);
}
int acquireLock(Lock * lock){
return pthread_mutex_lock(lock);
}
int releaseLock(Lock * lock){
return pthread_mutex_unlock(lock);
}
void initializeSemaphore(Semaphore * semaphore, unsigned int value){
sem_init(semaphore, 0, value);
}
void destroySemaphore(Semaphore * semaphore){
/* nothing */
}
void semaphoreDecrease(Semaphore * semaphore){
sem_wait(semaphore);
}
void semaphoreIncrease(Semaphore * semaphore){
sem_post(semaphore);
}
bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg){
return pthread_create(thread, (pthread_attr_t*) attributes, function, arg) == 0;
}
void joinThread(Id thread){
pthread_join(thread, NULL);
}
void cancelThread(Id thread){
/* FIXME: cancel is not implemented for libogc, find another way.
* thread suspend/resume is there, though.
*/
#if !defined(WII)
pthread_cancel(thread);
#endif
}
void destroyLock(Lock * lock){
/* nothing */
}
#endif
}
WaitThread::WaitThread():
done(false){
Thread::initializeLock(&doneLock);
}
WaitThread::WaitThread(Thread::ThreadFunction thread, void * arg){
Thread::initializeLock(&doneLock);
start(thread, arg);
}
static void * do_thread(void * arg){
WaitThread * thread = (WaitThread *) arg;
thread->doRun();
return NULL;
}
void WaitThread::doRun(){
this->function(this->arg);
Thread::acquireLock(&doneLock);
this->done = true;
Thread::releaseLock(&doneLock);
}
void WaitThread::start(Thread::ThreadFunction thread, void * arg){
done = false;
this->arg = arg;
this->function = thread;
Thread::createThread(&this->thread, NULL, (Thread::ThreadFunction) do_thread, this);
}
bool WaitThread::isRunning(){
Thread::acquireLock(&doneLock);
bool what = done;
Thread::releaseLock(&doneLock);
return what;
}
void WaitThread::kill(){
Thread::cancelThread(thread);
Thread::joinThread(thread);
}
WaitThread::~WaitThread(){
/* FIXME: Should we join the thread? */
/* pthread_join(thread); */
}
ThreadBoolean::ThreadBoolean(volatile bool & what, Thread::Lock & lock):
what(what),
lock(lock){
}
bool ThreadBoolean::get(){
Thread::acquireLock(&lock);
bool b = what;
Thread::releaseLock(&lock);
return b;
}
void ThreadBoolean::set(bool value){
Thread::acquireLock(&lock);
what = value;
Thread::releaseLock(&lock);
}
}
diff --git a/util/thread.h b/util/thread.h
index 97a49a9e..19cbb0eb 100644
--- a/util/thread.h
+++ b/util/thread.h
@@ -1,189 +1,202 @@
#ifndef _paintown_thread_h
#define _paintown_thread_h
#ifdef USE_SDL
#include <SDL_thread.h>
#include <SDL_mutex.h>
#else
#include <pthread.h>
#include <semaphore.h>
#endif
#include "exceptions/exception.h"
#include "load_exception.h"
#include "token_exception.h"
#include "mugen/exception.h"
#include "debug.h"
namespace Util{
/* Either uses pthreads or SDL_thread */
namespace Thread{
#ifdef USE_SDL
typedef SDL_mutex* Lock;
typedef SDL_Thread* Id;
typedef int (*ThreadFunction)(void*);
typedef SDL_semaphore* Semaphore;
#else
typedef pthread_mutex_t Lock;
typedef pthread_t Id;
typedef sem_t Semaphore;
typedef void * (*ThreadFunction)(void*);
#endif
extern Id uninitializedValue;
bool isUninitialized(Id thread);
void initializeLock(Lock * lock);
void initializeSemaphore(Semaphore * semaphore, unsigned int value);
void destroySemaphore(Semaphore * semaphore);
void semaphoreDecrease(Semaphore * semaphore);
void semaphoreIncrease(Semaphore * semaphore);
int acquireLock(Lock * lock);
int releaseLock(Lock * lock);
void destroyLock(Lock * lock);
bool createThread(Id * thread, void * attributes, ThreadFunction function, void * arg);
void joinThread(Id thread);
void cancelThread(Id thread);
+
+ /* wraps a Lock in a c++ class */
+ class LockObject{
+ public:
+ LockObject();
+
+ void acquire();
+ void release();
+
+ virtual ~LockObject();
+
+ Lock lock;
+ };
}
class WaitThread{
public:
/* does not start a new thread yet */
WaitThread();
/* starts a thread */
WaitThread(Thread::ThreadFunction thread, void * arg);
/* starts a thread */
void start(Thread::ThreadFunction thread, void * arg);
bool isRunning();
void kill();
virtual ~WaitThread();
public:
/* actually runs the thread */
void doRun();
protected:
Thread::Lock doneLock;
Thread::Id thread;
volatile bool done;
void * arg;
Thread::ThreadFunction function;
};
/* wraps a boolean with lock/unlock while checking/setting it */
class ThreadBoolean{
public:
ThreadBoolean(volatile bool & what, Thread::Lock & lock);
bool get();
void set(bool value);
protected:
volatile bool & what;
Thread::Lock & lock;
};
/* Computes stuff in a separate thread and gives it back when you ask for it.
* As soon as the future is created a thread will start executing and compute
* whatever it is that the class is supposed to do. You can then call `get'
* on the future object to get the result. If the thread is still executing
* then `get' will block until the future completes. If the future has already
* completed then `get' will return immediately with the computed value.
* The use case is computing something that has to be used later:
* Future future; // might take a while to compute
* do_stuff_that_takes_a_while(); // future might finish sometime in here
* Object o = future.get(); // future is already done
*
* TODO: handle exceptions
*/
template<class X>
class Future{
protected:
/* WARNING: hack to find out the type of the exception */
/*
enum ExceptionType{
None,
Load,
Token,
Base,
Mugen
};
*/
public:
Future():
thing(0),
thread(Thread::uninitializedValue),
exception(NULL){
/* future will increase the count */
Thread::initializeSemaphore(&future, 0);
}
virtual ~Future(){
if (Thread::isUninitialized(thread)){
Thread::joinThread(thread);
}
Thread::destroySemaphore(&future);
delete exception;
}
virtual X get(){
X out;
Thread::semaphoreDecrease(&future);
if (exception != NULL){
exception->throwSelf();
}
out = thing;
Thread::semaphoreIncrease(&future);
return out;
}
virtual void start(){
if (!Thread::createThread(&thread, NULL, (Thread::ThreadFunction) runit, this)){
Global::debug(0) << "Could not create future thread. Blocking until its done" << std::endl;
runit(this);
// throw Exception::Base(__FILE__, __LINE__);
}
}
protected:
static void * runit(void * arg){
Future<X> * me = (Future<X>*) arg;
try{
me->compute();
} catch (const LoadException & load){
me->exception = new LoadException(load);
} catch (const TokenException & t){
me->exception = new TokenException(t);
} catch (const MugenException & m){
me->exception = new MugenException(m);
} catch (const Exception::Base & base){
me->exception = new Exception::Base(base);
}
Thread::semaphoreIncrease(&me->future);
return NULL;
}
virtual void set(X x){
this->thing = x;
}
virtual void compute() = 0;
X thing;
Thread::Id thread;
Thread::Semaphore future;
/* if any exceptions occur, throw them from `get' */
Exception::Base * exception;
};
}
#endif

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jun 11, 11:15 AM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
68687
Default Alt Text
(19 KB)

Event Timeline