Showing posts with label toolkits. Show all posts
Showing posts with label toolkits. Show all posts

Saturday, July 9, 2011

wxWidgets GTK font rendering

In my previous post, I managed to fix the bugs in wxDC::DrawPoint() by using my own custom drawing class. Unfortunately, a lot of the places I where I used DrawPoint were also places where I needed to draw text, and in order to draw text I needed a wxDC. No problem, I'll just draw the text using a temporary wxMemoryDC on the bitmap, and to make sure there's no clobbering problems I'll make sure that I don't intermingle direct drawing scope with the DC object scope.

This appeared to work, except for the scrolling/updating windows. For some reason, even though there was a Clear() call before the font rendering, the windows would never clear. If I destroyed and recreated the bitmap every time, it worked fine but was very slow. If I cleared after drawing the text, the clear worked. If I cleared before drawing the text, the clear did not work.

Eventually I figured out the reason:

Under wxGTK, wxDC drawing and rendering are done to a separate bitmap/bitmap layer that is permanently attached to the real bitmap. When font data is drawn using wxDC::DrawText(), the text is drawn to the hidden layer, then the hidden layer is blitted in its entirety on top of the real bitmap. The end result is that anything you do prior to constructing the DC and rendering text with that DC is overwritten/deleted when the DC destructs.

Just how the hell does this make any sense? Nevermind, forget I asked. On the plus side, this explains why full screen font rendering is so slow in wxGTK. I never could figure that part of it out.

For roughly a day, I was utterly at a loss when faced with this problem. Switch back to the old code and lose the MacOS X platform; stay with the new code and lose wxGTK (and possibly other platforms, I only ever tested it on GTK.) I couldn't even think of a way to work around it.

Eventually, a possible solution presented itself: add font rendering to my custom bitmap class. I wasn't real clear on how to do this at first, but the key breakthrough came when I realized I could just use a cheap glyph rendering scheme. Use wxDC to draw each of the letters I needed (ascii chars 32 through 126) into tiny, clean bitmaps, then use a modified alpha channel copy routine to draw them to my custom bitmaps.

I'm proud to say that I now have proper text rendering and graphical drawing primitives on all three platforms. And to think that all I needed to do was rewrite the entire wxDC rendering system to do it!

I should have just done it in the first place, as I recommended to myself in a past life. Sometimes our older selves are no wiser than we are in youth.

wxDC DrawPoint broken under wxMAC

To follow up on my previous post, I had written my own routines for handling alpha channel support under wxWidgets, and finally everything seemed to be working properly. Both Win32 and Linux/GTK builds seemed to work exactly as expected using my alpha channel bitmaps where I needed them. For most other places, I still used wxDC primitives, as wxDC direct drawing seemed to be a bit faster than going through a bitmap/blit interface, and I still needed to use wxDC to render fonts.

I figured porting to MacOS X would be a snap, and for the most part it wasn't too bad. There were some issues with Repaint() not working the same, but adding a few explicit paint calls in the right place fixed that up.

However, something was wrong with some of the graphics in the various windows. The sky bar, normally with lots of little stars in it, still had stars in it, but instead of one pixel there were two: one at offset (0, 0), and one at offset (1, 1). I also noticed 'fuzz' on the corners of various windows and buttons, and in a handful of other locations.

Long story short, wxDC::DrawPoint() draws two pixels under wxMAC. Not one, but two. I found a couple bug reports regarding this from a few years ago, where it was basically acknowledged as a "verified bug", and the ticket was never closed. Advice was "these routines are slow and shouldn't be used for high performance drawing". Thanks guys.

I have some mighty fine choice words to say to the developers regarding this, but I'll try to keep this post on topic.

If something as fundamental as DrawPoint() is malfunctioning on a major development platform, I figured it would probably be a good idea to transition away from the classes that implement it in favor of my own drawing routines. So, I started using my bitmap class, which just happens to have a DrawPixel() function that works properly.

As expected, this fixed the drawing problems on all three platforms. But alas, using my bitmap class exposed another set of very nasty wx bugs, which I'll discuss in the next post.

wxwidgets has no alpha channel

A few months after I ported the Alter Aeon client to the wxWidgets toolkit, I decided I wanted to add alpha overlay support to the automap and main window.

Encouragingly enough, this appeared to be trivially supported: wxColor included an alpha value, bitmaps could be defined as having an alpha channel, etc. Pretty much everything looked good to go, so I started experimenting with it.

Alas, it was not to be. It turns out that there are precisely three places where the alpha channel is used:

1) loading a PNG from PNG data that has an alpha channel,
2) drawing a bitmap containing alpha channel data using wxDC::DrawBitmap, and
3) wxDC::DrawText, which politely draws text on top of the underlying pixels.

For all other locations, there simply should have been this assert:

wxASSERT("Alpha channel is stubbed here and works on precisely zero platforms ever, ha ha, the joke is on you")

After upgrading to wx 2.9 and a pile of scouting around, I came across wx/rawbmp.h, which has some direct access functions that allow access to the alpha channel. With this, I managed to get alpha channel working - but there were other problems with 2.9, so I downgraded back to stable, 2.8.12.

The alpha channel code that worked under 2.9 works properly under wx 2.8.12 in wxMAC and wxGTK, but apparently isn't implemented under Win32, which happens to be my main development platform.

Rather than bash my skull repeatedly against the wall, I did what any sane developer would do: throw out the broken toolkit module, and write one that works. In the end, I ended up with a wxBitmap derived class that has drawing functions that actually work properly and support alpha channel drawing when I need them to.

However, there's a problem with this as well, which I'll detail in a later post.

Tuesday, November 10, 2009

Software Reuse

There is an old saying in the nootropic (mental-performance enhancing drug) community:

"The guys in the 60's had this truly brilliant idea of using drugs to expand conciousness and improve thinking. Unfortunately, all they had at the time was LSD." [Just to ensure proper context, this is said without sarcasm. It really was a good idea, however LSD turned out to be a complete flop in achieving this goal.]

I've recently been doing some work that involved C++ templates, so allow me to reword this for modern usage:

"The c++ guys in the 90's had this truly brilliant idea of direct language support for generic code and module reuse. Unfortunately, all they had at the time was c++ templates."

Saturday, August 29, 2009

Client update

I've been working on the DClient code for the last couple of days, and it's coming along nicely. I had intended to do another interim release on thursday; after discovering that the Windows build of fundamental display primitives is vastly different than the Linux version, I had to go back to the drawing board and come up with a rendering/display system to avoid those issues.

Conveniently, with the new rendering system, the original problem that forced me to write the rendering system has vanished. I could probably figure it out if necessary, but at this point, I just want to get my work done. I'm still keeping the rendering system though; every piece of WX I replace is one step farther away from needing to use it at all. At some point, all that will be left is the event loop, wxDC functions, and Win32 resource management.

The improvements in this version of the client are primarily a simpler user interface with a lot less clutter. We also have popup-style windows for things like score, equipment, inventory and the who list. I've also prettied up some of the buttons, and have enough infrastructure in place to possibly start doing some window decorations.

If everything goes stunningly well, I should be able to get a testing release out Sunday night. More likely however, it'll be monday or later.

Wednesday, August 12, 2009

wxWidgets sucks

This is becoming less of a mud development blog than a 'bitch about wxWidgets sucking' blog. I've run into yet another piece of wxWidgets wierdness: wxBitmapButtons don't work. The documentation claims bitmaps can be used instead of the default graphics; trying this results in a very small bitmap wedged inside a ten pixel thick border of default graphics. There appears to be no way to turn this behaviour off.

I'm sure that there's a perfectly good reason why it behaves this way. It might be intentional; it might be that my development platform (GNU/Linux) is more buggy than other platforms; it might be that I'm simply terrible at operating this toolkit. Regardless, its unacceptable, and it is only with great reluctance weighing my application requirements that I did not switch to something else this very night.

Screw this toolkit. I wrote a text window class for exactly this reason, and quite frankly if I'd have done it to start with I'd have saved myself a lot of time. I will not make that mistake again, and as of right now I'm creating an image button class. I might not know what I'm doing, but at least I'll know it works properly, on all the platforms I need it to.

I get the feeling that by the time I'm done with this, I'll have using only the event handling loop and the font selection dialog. It seems like those are the only widgets that actually function as documented.

Sunday, July 12, 2009

wxWidgets - focus problems using multiple top level windows or frames

[Updated Jul 14, 2009 - this turned out to be a code bug on my part, at least partially. Further details in the comment section.]

As I'm sure you all know, I've been putting together a graphical/GUI client for the MUD Alter Aeon for the last few years. About 9 months ago, I switched to using the wxWidgets toolkit instead of QT, for reasons of executable size and licensing.

This switch has cost me on the order of 3 full months of development time trying to work around bugs in the wxWidgets ports on various platforms. I hit another one of these porting bugs/issues today; fortunately it only cost me about four hours, and amazingly enough, I found a workaround/answer that didn't involve rewriting the component from scratch.

Long story short: if you have multiple wxFrames or top-level windows in an MSVC build, the default is that you can't focus on any but the first one. My exact scenario:

1) App creates main window frame.

2) Main window frame later on dynamically creates a handful of new popup-style frames.

3) All of these new frames are immediately defocused and placed behind the main window frame. Attempts to raise or focus them are completely and utterly ignored. The FLOAT_ON_PARENT window style does nothing.

Oddly enough, minimizing the main window sometimes allowed the children to gain focus or 'disconnect' from the main window so the focus worked properly. It wasn't reliable, and it was never clear to me exactly why or how, but it never did what I ultimately wanted anyway.

There's no documentation on why any of this should happen, at least nowhere I could find. It all worked fine in the Linux port! After multiple hours of screwing around with it and reading unrelated documentation, I finally tried something I found in an obscure post, and it worked.

The solution:

1) Don't bother to hook the focus event. It doesn't do shit anyway.

2) Hook the Activate event in your new frame. You've probably never seen this before. Neither had I. I still don't know what exactly it's supposed to do.

3) In your Activate event handler, SetFocus(), then Skip() and pass the event down. The SetFocus() brings your new frame to the top and allows it to take focus in the future.

That's it. It's all of like three lines of code; I hope it doesn't waste nearly as much of your time as it did of mine.

[Note - I understand that the wx guys are doing this basically for free, and that they're up against a nasty set of ports to get everything working properly. Still, it's cost me a lot of time, and if I had known better I would probably have just paid for a proper QT license and found some other way to reduce the file size.]

Tuesday, February 24, 2009

WxWidgets Review

Now that I've had a chance to settle down and not work on the client for a couple of weeks, I'm probably in the right frame of mind to write a proper review of wxWidgets.

First off, wxWidgets is a multi-platform GUI toolkit. It's been used to build a variety of applications, including the current version of the Alter Aeon Mud client. It works on a bunch of different platforms, including Linux, Windows, Mac, and a handful of less popular operating systems. I've used it to build the most recent versions of the Alter Aeon Mud Client, a standalone executable designed for the players of Alter Aeon. It has a graphical automap and basic colored-text console facilities.

In the case of standard dialogs and standard types of objects, it works quickly and well. Everything always looks 'as it should' for the platform it's on. Unfortunately, things work less well for even slightly more complicated objects.

Take for example the standard wxTextCtrl object. This uses what's known as a 'native' library - the guts of this object are based on the system libraries where it's built. On Windows it uses one of the standard text window DLLs, while under Linux it can use GTK or other libraries. Because of differences between these system libraries, the behavior of the wxTextCtrl on different platforms is vastly different.

Scrolling may or may not work depending on the platform; URLs, if enabled, may or may not display in Windows depending on the version and service pack level. Performance varies; disabling certain features may break window formatting, and Append may insert arbitrary line feeds after ever call. When editing text, attempts to move the cursor past the end of the text triggers a system beep at full volume. The list goes on, and not all of these are fixable without editing wxWidgets itself.

One recommended solution for these kinds of problems is to use the wxRichTextEdit class. This is a ground-up reimplementation of the text window, with an interface similar to the wxTextEdit class but far more comprehensive. This class actually works pretty well, and it's consistent across platforms as you'd expect.

The only problem is that it's slow. Dog slow. A dog with no legs slow. Using it as a text console display becomes almost useless beyond a few thousand lines of text. And that was pretty much the whole point of what I wanted to do.

Fortunately, there's another solution: the Scalia wxStyledTextEdit class, which is an add-on module from another open source project. This class is designed to do fairly complex text formatting and styling, including multiple styles simultaneously and syntax highlighting. I don't actually need most of that stuff, but I figured I'd give it a try as well.

The downside of this class is that the interface to make it work is quite complex. It's a heavyweight class, designed for very complicated types of things. It's got nearly everything you could possibly need - and some things you don't, including implementation bugs. Quite frankly, I never got to testing the performance of this class, simply because I could never figure out how to change the background color of the window. It's not like I didn't try.

As a last resort, the drawing primitives in wxWidgets are actually pretty good. In approximately one week, I was able to construct my own text window class with the features and performance that I required for this application. Remember that if you have a lot of trouble with one particular module, getting out a wxDC and building your own is always a viable option, and if it doesn't work it's no-one's fault but your own.

Compared with my experience with QT, there is absolutely no comparison: QT has better documentation, better cross platform support, fewer cross platform bugs, better performance, and a more consistent design. Unfortunately, QT is LGPL, requiring an installer for binary applications, and the QT libraries are upwards of 50 MB in most builds. So on that count, wxWidgets wins: it makes drastically smaller and easy to work with executables.

Score for wxWidgets: 5/10

It does most of what it's supposed to do, but don't use it for anything important.

Saturday, February 14, 2009

New client release

Finally, after a week of work, there is a new Official Alter Aeon Mudding Client for all to use! This version fixes a huge number of bugs in the previous code base, and has faster scrolling among other improvements. Beeping in the input window has been killed and control-c now works again.

It has been a long, hard five-day-slog to get to this point, but using a custom window class has made so many things better. Gone are all the hacks I had to put in to make the old libraries work; now they're back to the nice clean code they should have been. Scrolling works right, select works right, context switches work right - and best of all, it's fast as hell under Windows. I really wasn't expecting this level of performance.

The final hitch was getting the input window working reliably. Through some stroke of luck I found the event handler responsible for intercepting control C and the backspace events. With some really nasty state-handling code and about two hours of experimentation, I finally have an input window class that traps out all the beeps and handles selection copy without stupidity.

If I had known this to start, it would have saved me so much time and effort. Time lost that I could have spent elsewhere; such is life. But going forward, it's so liberating - no longer am I at the mercy of crap that can't be made to work the way I want it to.

If it fails, its my own fault. And I can live with that.

Wednesday, February 11, 2009

Sucking further wxWidgets

I've managed to fix and clean up more code in the last two days than in the last four months simply by throwing out these broken toolkit parts and writing my own display class. Bugs that I never could figure out are gone; workarounds for problems that should never have been there in the first place are no longer needed. It displays, it's solid, and it works. I've been mudding with it all day long.

So far, I have a fairly primitive display class with a scroll bar, display window, and border that changes color when it locks. The display window has primitive and buggy line wrapping, but it's usable. There is currently no URL clicky support or select/copy support. Performance is even pretty good.

Performance isn't as good as it should be though - when resizing narrow, it takes far too long to recalculate line numbers. I suspect most of the time doing this is spent in pointless object conversions between various objects. First thing tomorrow, I'm going to be switching over most of the wxString objects to regular const char *'s. There's an awful lot of string processing that needs to be done, and doing it in wxString land is problematic.

After that, I need to rework the way the line data is stored so I can handle select/copy and proper line wrap. This same code will also help with URL support, so it's possible that all three could be done pretty quickly. At this point, the display window is fully featured.

Next up, after the display window, is the typing bar/input window. This one is more troublesome; it's one of those things I'd really rather not re-implement, but I suppose if I have to I can. Either way, I have to do something with it:

1) The input bar beeps if you backspace too far. This is a show-stopper. Computers should NOT make noise unless actively requested to, especially for trivially ignored failure cases. It appears to be impossible to turn off this buggy behavior in the library.

2) It also appears to be impossible to reliably set and maintain the font and font color for this object. Backspacing until it's empty often has unpredictable results. No modifications to the class have been made, and it produces different results on different windows versions more and less frequently. This smacks of being a library/DLL bug.

Hopefully I can find some other input window class that is less problematic, and still have multi-line support. Multi-line paste is mandatory, as I paste a lot of notes and descriptions.

Tuesday, February 10, 2009

wxWidgets sucks...

... but even though it sucks, I can't really blame it. I think the problem is endemic when using pretty much any large toolkit, especially younger ones or ones that are built on top of other toolkits.

First, some background. wxWidgets is a windowing library to allow people to quickly and easily develop GUI applications. It's cross platform and in general built on top of other toolkits. This means that the layers of toolkits upon toolkits is often at least two levels deep, exponentially increasing the likelyhood that bugs in one layer will foul up things elsewhere.

These sorts of interactions are causing me huge difficulties with the display and input windows in the client. After much soul searching, I have what appears to be three choices going forward, each with various pros and cons, none of which are ideal. In short:

1) Use the native wxTextCtrl class. Pros - some minimal screen reader support, cut/paste works, already mostly working. Cons - scrolling doesn't work worth a shit, different performance on different windows versions, urls are unreadable for at least some people, no way to disable beeping on backspace, and easily a third of the style flags and other functions don't work or don't work correctly, often with no workaround. Further, the god damned thing intercepts certain keystrokes, specifically Control-C, before I can get at them, and there appears to be no workaround for this.

2) Use the scintilla derived display class. Pros - someone else maintains it. Cons - pain in the ass to get working, manual url and cut/paste handling, bigger, vastly more complicated than my application requires, and inability to configure simple, important things like the background color.

3) Write my own. Pros - it will do exactly what I want, when I want, with the interface that I want. Should be fast and small. Cons - I have to do all the work.

After all the crap I've been through in the last month trying to get the default text controls to do incredibly simple, obvious things, I'm heavily leaning toward option 3 at this point. In the time I've spent trying to get existing controls to work, I could have without question written my own custom primitive. Or rather, I now know enough to write my own. The road would have been rockier in the beginning.

I think this is a prime example of why I rail against toolkits in general. They are very risky; there's no guarantee that what you're using will work, or can be made to work the way you want it to. In this case, I have lost a huge amount of time trying to work around toolkit limitations.

Option 3, here I come.

Friday, January 9, 2009

xml xml xml

I really hate that hitting enter while in the title bar automatically posts, even if the post body is empty.

Today, I added support for XML dumping of player data via the web interface. This was at the request of the player Cu, whose XML data can now be seen at http://dentinmud.org:3004/xml/players/cu. The idea was to export various player statistics so that he could dump it into a database and do databasey things with it; in short, a third party app using AA data.

I really dislike XML, but I like this plan. I also hope to export other data, hopefully without compromising the game itself, so that more things can be done with it.

This reboot also brings in a handful of minor changes to newbie sends and the email command, but more importantly it brings in a major change to area checking. We now have code to check linkages between areas and figure out how far off in terms of relative position they are. This should help us line up the world and get things to be a little more grid-like.

This gridlike preparation is in anticipation of graphical maps in the dclient.

In other news, there's a bunch of presentation/toolkit bugs in the client, pointed out by various people. Some of them do not look easy to fix.

Tuesday, January 6, 2009

When will we have a real client?

Client work continued hard and heavy today, with two major additions going in: first, the hp/mana/movement status bar is functional. This is a bunch of progress bars, red for hp, blue for mana, and yellow for movement, that goes between the command-entry window and the main window. As you get beat up or heal, your stats update in real time, and the bars get redrawn to give a graphical representation of your current status.

A lot of this code was portable from the old client codebase, but between two different sets of library bugs on two different platforms, I ended up spending several more hours than is reasonable getting it all working. And in the end, I ended up doing a full client release with a trivially obvious bug in one of the display settings: the mana bar displays movement numbers if the client window is made wider than a certain amount.

The second thing I got working was to use the autoexit data to highlight/darken the various direction buttons. So if you're in a room with 3 exits showing, those three direction buttons will be lit. You can use the others if you want anyway (eg. to find doors by bumping into them), but if you're running from something or exploring, this should help.

The surprising thing about the autoexit buttons is how ugly they are. The display is just plain ugly, and I'm not real sure why. I'll have to poke around with it a bit more and see what else I can do with it.

I looked a little at the scrolling issue listed in the previous post, but it's entirely unclear to me how you would hook such an event with this library. I'm also pretty well stuck on the accessibility functions. Unfortunately, noone makes howtos for something this specific.

Tomorrow, other things permitting, I'm going to try to get new style automaps working. That should be fun, and probably overly ambitious: I have enough bug fixes and miscellaneous cleanup to probably consume the day already, and web page work is starting to fall behind.

For web pages, I have a large number of directions for the blind maps project, and an event report from christmas which needs to be put up.

This would be easier if I could fork copies of myself.

Monday, December 15, 2008

HTML logfiles

I managed to get the logfile save routines working in the AA client tonight. The text version is trivial, but the html version was harder; nevertheless, I have an initial (buggy) implementation done, and you can see the output of it here.

[Update - the various minor bugs have been fixed and the logfile updated. It's now HTML 4.01 transitional compliant.]

If you look closely at this, you'll notice a number of bugs of various kinds: it's not W3C compliant, uses tags that are probably obsolete or nearly so, and doesn't escape important characters like <>. These are all minor inconveniences compared to the inconvenience of using this toolkit; the file selection dialog has so far been the only thing about this port that has been relatively painless.

Next on the hit list is to fix these issues, then try it out on the windows laptop to see if the screen reader part of it works. I'm going to try to get a usable blind-friendly client out first, then work on the pretty graphics part later.

Thursday, December 11, 2008

This makes no sense

I finally got up enough incentive to put in time on the client, and as a result I got a fresh dose of why I avoid working on it: this toolkit makes no sense.

Or rather, it does make sense, it's just not documented. You pretty much have to figure out the internal state of the system from examples and experiments; this is very different from the QT tookit, which while a pain in the ass, at least was comprehensive.

So for my time tonight, I have a dialog box for logoff/disconnect/cancel that looks correct in the Linux build. I don't have any of the buttons hooked up, but that's a bit more straight forward. There's a handful of these dialogs that I need to build, so getting even one of them figured out and working properly is a huge step forward.

My current plan is to get the dialogs and history save working, then try to get it working with the screen reader on the laptop under windows. I hope I can get it working at least as well as other clients, so I can offer a preconfigured, functional client for the blind as well as one for sighted people.

One final note: I thought I had the dialogs and sizers figured out, and went to move the dialog out of the main window and into a subwindow. Shows what I know! Doing so broke the entire layout in weird ways I've never seen before. Clearly I don't understand what's going on yet.

Monday, November 10, 2008

Status update

I have been lax in my updates recently, but some small amount of work has been going on anyway. I spent a lot of time working on the client code, which has been a complete pain in the ass. wxWidgets is a portable gui toolkit, but it's also grossly inconsistent, poorly documented, and fundamentally broken in certain ways. That said, it has enough advantages over the QT toolkit to justify switching. It's just painful.

One of the nastier sets of issues I've run into is getting scrolling and font size changes to work properly in a wxTextEdit. In the case of the scrollbar, I manually determine the character position of each line and apply direction hysteresis to scroll up or down using the function keys. For font size changes, I basically clear the buffer and rerender the whole thing. Both of these are trivial operations under QT. Further, the QT documentation is much, much better.

That said, QT is bloated beyond belief, and the licensing is going to be problematic for what I want to do in the future. But primarily, it's the bloat factor that is the biggest problem. With the new toolkit, I can get executables that are around 20% as big as the QT client.

Right now, I'm trying to get dialog boxes working, and it's -really- unclear how these stupid sizer objects are supposed to function. I have it displaying a disconnect dialog right now, but I can't figure out how to place text in it, put the buttons in the right place, or hook anything in it up. I may have to go digging through sample code to get it to work right.

Thursday, November 6, 2008

Software Complexity and Human Limits

As you might have read from other posts here, I've been working on a gui client for Alter Aeon. Gui code is fundamentally different from what I'm used to working on, in that it has loads of function pointer handlers and 'virtual internal state' that is mostly held by which objects are instantiated and what they're presently doing. At its lowest level, this can of course be represented by a perfectly ordinary state machine, however these state machines are fairly large and the state it's currently in isn't always obvious.

[As a side note, I do work in FAX software in my off time, and this also has some pretty huge state machines. However, those state machines are really well defined in one central location, and it's much more obvious what's going on. Even saying that, I still have a hard time with those.]

While working on this client, I quickly lose track of what needs to be done and how the states work. The client itself is big enough that I can't remember everything that is in it; and after not working on it seriously for almost two years, I had a lot of trouble getting back up to speed.

A good part of this is that the code itself was basically built from the ground up, and then never cleaned up by a maintainer. Maintenance is more than just adding a button here or there and fixing minor bugs; maintenance of software means getting in there and saying "why the hell are these drawing functions intermingled with scroll locking?", then moving things around so it makes more sense. A good example of this is the button system, the entirety of which is contained in the main window implementation file. This serves only to clutter up the main window implementation, and further make the button code hard as hell to understand.

So I've been doing the proper thing and moving functions around, grouping them by functionality, and trying to make useful classes on the side where I can hide details. But even so, I can tell that my standard way of thinking about and writing code is showing signs of strain. Much like I'm having to retool my picking technique on guitar, I need to retool my brain to handle this kind of abstraction better.

I don't really need any advice or recommendations for books here; I know where to find that sort of thing if I need it, and I've done this enough to know when I'll need it. I even know conceptually how to approach this kind of problem; I think I'm just currently bad at it. Fortunately (or perhaps unfortunately), there's a lot of work left to do on this client, so I'll get lots of practice.

Gui client update

I've been working on the client, and as part of my foray into using a new gui toolkit I've learned the joys of incompatible toolkits. My latest problem arose with regard to the main display text window. There's two options for this:

1) use the standard system provided window type that has screen reader support and fewer features, or

2) use the custom window type that has way more features but doesn't read properly.

So, I've been trying to make the standard window type work, and it's been problematic. One thing in particular is that I can't easily go back and just change the one aspect of the style in the window; for example, I can't just change the font size without recoloring the whole damned thing. As a result of this, I spent most of the morning cleaning up and building a renderer that saves everything ever sent to the window and redraws it if necessary.

Another side effect of this is that I can't change the text background easily when window scrolling is locked. For now, I just have the window background changing, which is actually starting to grow on me - you can obviously tell that the window is locked, and the text keeps its high contrast. It does look a little blocky in certain areas though.

I don't have any of the intercession windows built (like the 'do you really want to disconnect without logging off the game' window), and I've been avoiding button handling like crazy. I'm getting down to where I'm going to have to start doing that in the next couple of days though.

On the schedule for this afternoon (if I don't get interrupted) is logfile saving, and the parts of the 'view' menu that make sense.

Thursday, October 23, 2008

More client stuff

The original version of the Alter Aeon client was a modified version of PuTTY, one that autoconnected to AA on startup. This was created by a player named Andres, several years ago. A lot of people don't like this client, for a lot of reasons.

So about three years ago, I set about creating a gui client. Using QT, I managed to put something together that isn't terrible, but isn't great either. On the down side, the QT license requires source distribution, and I'm not entirely keen on that, at least not for what I'm trying to do.

Not that I'm against open source, it's just not for everyone. I'm trying to build a player community, not a code community. Think Skype, as opposed to Apache. I definitely recognize that open source has a place.

I would probably have been fine with the source distribution of the QT version were it not for one minor issue: the old version of the executable is 8 meg. With new libraries, that size balloons even more. The download size really turns me off.

So I've been looking at and experimenting with a couple of other toolkits. So far, I have Foxlib and wxLib as candidates. Wyvren espouses Foxlib, but in my short time working with it I'm starting to think that it's probably just not what I'm looking for. wxLib is currently on the hit list, and I should know if it fits the bill in a few days.

One thing I have learned is that I'm really calcified and I hate learning new things. Or rather, I hate learning toolkits. I just want to get my work done; having to spend three hours looking up why a resize function doesn't work (then discovering entirely by accident that windows are created with resizing disabled by default) does not make me happy. One of the reasons I'm abandoning Foxlib is the lack of documentation.

I pawned off the room mapping stuff to Locane. Hopefully he'll have something interesting done by the time I need it; I want to hook up the room coordinates to a mapping system in the client so players can more easily figure out where they are and what they're doing.