summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-05-17 15:48:23 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-05-17 15:48:23 +0200
commit2872eb224e9f3ec6947542f2d7ac0ad288574cf1 (patch)
tree718c571b7930afce9e909920366d0a052ddbf698
parente7e6a79f8bf2855b5d1d432613151e48d2d685da (diff)
Added a console-like window which doesn't do anything interesting yet.
-rw-r--r--GUI/layouts/console.layout15
-rw-r--r--SConstruct2
-rw-r--r--gui.cpp101
-rw-r--r--gui.h32
-rw-r--r--main.cpp1
-rw-r--r--scene.cpp90
-rw-r--r--scene.h1
-rw-r--r--tool.cpp13
-rw-r--r--tool.h7
-rw-r--r--widgets/FormattedListboxTextItem.cpp165
-rw-r--r--widgets/FormattedListboxTextItem.h54
-rw-r--r--widgets/README1
12 files changed, 444 insertions, 38 deletions
diff --git a/GUI/layouts/console.layout b/GUI/layouts/console.layout
new file mode 100644
index 0000000..e6ef61b
--- /dev/null
+++ b/GUI/layouts/console.layout
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<GUILayout>
+ <Window Type="Vanilla/FrameWindow" Name="ConsoleWindow">
+ <Property Name="UnifiedPosition" Value="{{0, 0}, {0, 0}}" />
+ <Property Name="UnifiedSize" Value="{{1, 0}, {.3, 0}}" />
+ <Window Type="Vanilla/Listbox" Name="console_listbox">
+ <Property Name="UnifiedPosition" Value="{{0, 0}, {0, 0}}" />
+ <Property Name="UnifiedSize" Value="{{1, 0}, {1, -20}}" />
+ </Window>
+ <Window Type="Vanilla/Editbox" Name="console_editbox">
+ <Property Name="UnifiedPosition" Value="{{0, 0}, {1, -20}}" />
+ <Property Name="UnifiedSize" Value="{{1, 0}, {0, 20}}" />
+ </Window>
+ </Window>
+</GUILayout>
diff --git a/SConstruct b/SConstruct
index bec2ba8..c4e9247 100644
--- a/SConstruct
+++ b/SConstruct
@@ -24,6 +24,6 @@ if GetOption('profiling'):
Export('env')
-env.Program('foo', Glob('*.cpp') + ['noiseutils/noiseutils.cpp'])
+env.Program('foo', Glob('*.cpp') + ['noiseutils/noiseutils.cpp'] + Glob('widgets/*.cpp'))
# vim: syn=python
diff --git a/gui.cpp b/gui.cpp
index 72275c8..f29ee82 100644
--- a/gui.cpp
+++ b/gui.cpp
@@ -1,7 +1,10 @@
#include "gui.h"
#include "video.h"
+#include "widgets/FormattedListboxTextItem.h"
+
#include <boost/format.hpp>
+#include <boost/algorithm/string/trim.hpp>
#include <RendererModules/OpenGL/CEGUIOpenGLRenderer.h>
using namespace CEGUI;
@@ -38,6 +41,10 @@ void GUI::init() {
System::getSingleton().setGUISheet(root);
}
+void GUI::pre_render() {
+ MouseCursor::getSingleton().hide();
+}
+
void GUI::render() {
/* Disable depth testing to avoid cursor bugginess. */
glDisable(GL_DEPTH_TEST);
@@ -45,6 +52,92 @@ void GUI::render() {
glEnable(GL_DEPTH_TEST);
}
+void GUI::show() {
+ wnd->show();
+ _showing = true;
+}
+
+void GUI::hide() {
+ wnd->hide();
+ _showing = false;
+}
+
+bool GUI::showing() {
+ return _showing;
+}
+
+/* ConsoleWindow */
+
+ConsoleWindow::ConsoleWindow() {
+ WindowManager& wmgr(WindowManager::getSingleton());
+
+ wnd = wmgr.loadWindowLayout("console.layout");
+ root->addChildWindow(wnd);
+
+ editbox = wmgr.getWindow("console_editbox");
+ editbox->subscribeEvent(Editbox::EventMouseClick, Event::Subscriber(&ConsoleWindow::clicked, this));
+ editbox->subscribeEvent(Editbox::EventKeyDown, Event::Subscriber(&ConsoleWindow::keydown, this));
+
+ listbox = static_cast<Listbox*>(wmgr.getWindow("console_listbox"));
+}
+
+ConsoleWindow::~ConsoleWindow() {
+ WindowManager& wmgr(WindowManager::getSingleton());
+ wmgr.destroyWindow(wnd);
+ wmgr.cleanDeadPool();
+}
+
+bool ConsoleWindow::clicked(const EventArgs& e) {
+ handle_input();
+
+ return true;
+}
+
+void ConsoleWindow::erase_editbox_text() {
+ String s(editbox->getText());
+
+ if(s.size() == 0)
+ return;
+
+ s.erase(s.size()-1);
+ editbox->setText(s);
+}
+
+bool ConsoleWindow::keydown(const EventArgs& e) {
+ const KeyEventArgs& ke = static_cast<const KeyEventArgs&>(e);
+ switch(ke.scancode) {
+ // enter
+ case 36:
+ handle_input();
+ break;
+ // backspace
+ case 22:
+ erase_editbox_text();
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+void ConsoleWindow::handle_input() {
+ std::string s = editbox->getText().c_str();
+ editbox->setText("");
+ boost::trim(s);
+ if(!s.size())
+ return;
+
+ FormattedListboxTextItem *item = new FormattedListboxTextItem(s, HTF_WORDWRAP_LEFT_ALIGNED);
+ listbox->addItem(item);
+ listbox->ensureItemIsVisible(item);
+}
+
+void ConsoleWindow::update() {
+ MouseCursor::getSingleton().show();
+ WindowManager::getSingleton().getWindow("console_editbox")->activate();
+}
+
/* RaiseWindow */
/* default values */
@@ -55,7 +148,7 @@ float RaiseWindow::strength = .3;
RaiseWindow::RaiseWindow() {
WindowManager& wmgr(WindowManager::getSingleton());
- wnd = static_cast<FrameWindow*>(wmgr.loadWindowLayout("raisewnd.layout"));
+ wnd = wmgr.loadWindowLayout("raisewnd.layout");
root->addChildWindow(wnd);
radius_sb = static_cast<Scrollbar*>(wmgr.getWindow("radius_sb"));
@@ -82,12 +175,12 @@ RaiseWindow::~RaiseWindow() {
wmgr.cleanDeadPool();
}
-void RaiseWindow::render() {
+void RaiseWindow::update() {
+ MouseCursor::getSingleton().show();
+
radius_sb_lbl->setText((boost::format("%.2f") % radius_sb->getScrollPosition()).str().c_str());
focus_sb_lbl->setText((boost::format("%.2f") % focus_sb->getScrollPosition()).str().c_str());
strength_sb_lbl->setText((boost::format("%.2f") % strength_sb->getScrollPosition()).str().c_str());
-
- GUI::render();
}
float RaiseWindow::get_radius() {
diff --git a/gui.h b/gui.h
index fe3bb3e..9e769f5 100644
--- a/gui.h
+++ b/gui.h
@@ -6,18 +6,44 @@
#include <CEGUI.h>
class GUI {
+ protected:
+ CEGUI::Window *wnd;
+ bool _showing;
+
public:
static CEGUI::Window *root;
virtual ~GUI() {};
static void init();
- virtual void render();
+ static void pre_render();
+ static void render();
+ virtual void update() = 0;
+ virtual void show();
+ virtual void hide();
+ bool showing();
+};
+
+class ConsoleWindow : public GUI {
+ private:
+ CEGUI::Window *editbox;
+ CEGUI::Listbox *listbox;
+
+ bool clicked(const CEGUI::EventArgs& e);
+ bool keydown(const CEGUI::EventArgs& e);
+
+ void erase_editbox_text();
+ void handle_input();
+
+ public:
+ ConsoleWindow();
+ virtual ~ConsoleWindow();
+
+ virtual void update();
};
class RaiseWindow : public GUI {
private:
- CEGUI::FrameWindow *wnd;
CEGUI::PushButton *btn;
CEGUI::Scrollbar *radius_sb;
@@ -35,7 +61,7 @@ class RaiseWindow : public GUI {
RaiseWindow();
virtual ~RaiseWindow();
- virtual void render();
+ virtual void update();
float get_radius();
float get_focus();
float get_strength();
diff --git a/main.cpp b/main.cpp
index 4d050fc..be24747 100644
--- a/main.cpp
+++ b/main.cpp
@@ -29,6 +29,7 @@ int main(int argc, char **argv) {
Scene *scene = new Scene();
SDL_ShowCursor(SDL_DISABLE);
+ SDL_EnableUNICODE(1);
SDL_WarpMouse(video::width/2, video::height/2);
scene->last_time = SDL_GetTicks();
diff --git a/scene.cpp b/scene.cpp
index f7db5c4..e179a3b 100644
--- a/scene.cpp
+++ b/scene.cpp
@@ -56,6 +56,9 @@ Scene::Scene() {
font->FaceSize(10);
GUI::init();
+
+ console = new ConsoleWindow();
+ console->hide();
}
Scene::~Scene() {
@@ -64,6 +67,7 @@ Scene::~Scene() {
if(terrain)
delete terrain;
delete font;
+ delete console;
}
void Scene::lookat() {
@@ -143,11 +147,18 @@ void Scene::events() {
running = false;
break;
case SDL_KEYDOWN:
+ if(console->showing() && event.key.keysym.sym != 124) {
+ CEGUI::System::getSingleton().injectKeyDown(event.key.keysym.scancode);
+ if(CEGUI::System::getSingleton().injectChar(event.key.keysym.unicode))
+ break;
+ }
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
if(tool) {
delete tool;
tool = NULL;
+ } else if(console->showing()) {
+ console->hide();
} else
running = false;
break;
@@ -171,15 +182,35 @@ void Scene::events() {
break;
case SDLK_TAB:
dialog = !dialog && tool;
+ if(tool) {
+ if(dialog)
+ tool->gui_show();
+ else
+ tool->gui_hide();
+ }
break;
case SDLK_1:
if(tool) delete tool;
tool = new RaiseTool(terrain);
break;
+ case 124:
+ if(console->showing()) {
+ console->hide();
+ dialog = false;
+ } else {
+ console->show();
+ dialog = true;
+ }
+ break;
default:
break;
}
break;
+ case SDL_KEYUP:
+ if(console->showing() && event.key.keysym.sym != 124) {
+ CEGUI::System::getSingleton().injectKeyUp(event.key.keysym.scancode);
+ }
+ break;
case SDL_MOUSEBUTTONDOWN:
switch(event.button.button) {
case SDL_BUTTON_LEFT:
@@ -259,28 +290,30 @@ void Scene::render() {
float forward = 0;
float right = 0;
bool moved = false;
- if(keystate[SDLK_w]) {
- moved = true;
- forward++;
- }
- if(keystate[SDLK_s]) {
- moved = true;
- forward--;
- }
- if(keystate[SDLK_a]) {
- moved = true;
- right--;
- }
- if(keystate[SDLK_d]) {
- moved = true;
- right++;
- }
- if(keystate[SDLK_q])
- pos.y -= 0.002*steps*(keystate[SDLK_LSHIFT]?10:1);
- if(keystate[SDLK_e])
- pos.y += 0.002*steps*(keystate[SDLK_LSHIFT]?10:1);
- if(moved && (forward || right)) {
- move(forward, right, steps*(keystate[SDLK_LSHIFT]?10:1));
+ if(!dialog) {
+ if(keystate[SDLK_w]) {
+ moved = true;
+ forward++;
+ }
+ if(keystate[SDLK_s]) {
+ moved = true;
+ forward--;
+ }
+ if(keystate[SDLK_a]) {
+ moved = true;
+ right--;
+ }
+ if(keystate[SDLK_d]) {
+ moved = true;
+ right++;
+ }
+ if(keystate[SDLK_q])
+ pos.y -= 0.002*steps*(keystate[SDLK_LSHIFT]?10:1);
+ if(keystate[SDLK_e])
+ pos.y += 0.002*steps*(keystate[SDLK_LSHIFT]?10:1);
+ if(moved && (forward || right)) {
+ move(forward, right, steps*(keystate[SDLK_LSHIFT]?10:1));
+ }
}
std::string move_str;
@@ -464,8 +497,17 @@ void Scene::render() {
font->Render(selected->str().c_str());
}*/
- if(dialog && tool)
- tool->render_gui();
+ GUI::pre_render();
+
+ if(tool && dialog) {
+ tool->gui_update();
+ }
+
+ if(console->showing()) {
+ console->update();
+ }
+
+ GUI::render();
SDL_GL_SwapBuffers();
}
diff --git a/scene.h b/scene.h
index 72bf506..89a5ec0 100644
--- a/scene.h
+++ b/scene.h
@@ -19,6 +19,7 @@ class Scene {
FTFont *font;
GUI *gui;
Tool *tool;
+ ConsoleWindow *console;
bool running;
bool grid;
diff --git a/tool.cpp b/tool.cpp
index d96a45f..d652b16 100644
--- a/tool.cpp
+++ b/tool.cpp
@@ -5,13 +5,22 @@ Tool::Tool(Terrain *terrain) {
this->terrain = terrain;
}
-void Tool::render_gui() {
- gui->render();
+void Tool::gui_show() {
+ gui->show();
+}
+
+void Tool::gui_hide() {
+ gui->hide();
+}
+
+void Tool::gui_update() {
+ gui->update();
}
/* RaiseTool */
RaiseTool::RaiseTool(Terrain *terrain) : Tool(terrain) {
gui = new RaiseWindow();
+ gui_hide();
}
RaiseTool::~RaiseTool() {
diff --git a/tool.h b/tool.h
index 5ccda41..e08ecef 100644
--- a/tool.h
+++ b/tool.h
@@ -17,14 +17,13 @@ class Tool {
virtual ~Tool() {};
virtual bool handle_event(SDL_Event& event, Vector3& selected) = 0;
- virtual void render_gui();
+ virtual void gui_show();
+ virtual void gui_hide();
+ virtual void gui_update();
virtual const char* get_name() = 0;
};
class RaiseTool : public Tool {
- protected:
- static std::string name;
-
public:
RaiseTool(Terrain *terrain);
virtual ~RaiseTool();
diff --git a/widgets/FormattedListboxTextItem.cpp b/widgets/FormattedListboxTextItem.cpp
new file mode 100644
index 0000000..b9362cc
--- /dev/null
+++ b/widgets/FormattedListboxTextItem.cpp
@@ -0,0 +1,165 @@
+#include "FormattedListboxTextItem.h"
+
+namespace CEGUI
+{
+//----------------------------------------------------------------------------//
+FormattedListboxTextItem::FormattedListboxTextItem(const String& text,
+ const HorizontalTextFormatting format,
+ const uint item_id,
+ void* const item_data,
+ const bool disabled,
+ const bool auto_delete) :
+ // initialise base class
+ ListboxTextItem(text, item_id, item_data, disabled, auto_delete),
+ // initialise subclass fields
+ d_formatting(format),
+ d_formattedRenderedString(0)
+{
+}
+
+//----------------------------------------------------------------------------//
+FormattedListboxTextItem::~FormattedListboxTextItem()
+{
+ delete d_formattedRenderedString;
+}
+
+//----------------------------------------------------------------------------//
+HorizontalTextFormatting FormattedListboxTextItem::getFormatting() const
+{
+ return d_formatting;
+}
+
+//----------------------------------------------------------------------------//
+void FormattedListboxTextItem::setFormatting(const HorizontalTextFormatting fmt)
+{
+ if (fmt == d_formatting)
+ return;
+
+ d_formatting = fmt;
+ delete d_formattedRenderedString;
+ d_formattedRenderedString = 0;
+ d_formattingAreaSize = Size(0, 0);
+}
+
+//----------------------------------------------------------------------------//
+Size FormattedListboxTextItem::getPixelSize(void) const
+{
+ if (!d_owner)
+ return Size(0, 0);
+
+ // reparse text if we need to.
+ if (!d_renderedStringValid)
+ parseTextString();
+
+ // create formatter if needed
+ if (!d_formattedRenderedString)
+ setupStringFormatter();
+
+ // get size of render area from target window, to see if we need to reformat
+ const Size area_sz(static_cast<const Listbox*>(d_owner)->
+ getListRenderArea().getSize());
+ if (area_sz != d_formattingAreaSize)
+ {
+ d_formattedRenderedString->format(area_sz);
+ d_formattingAreaSize = area_sz;
+ }
+
+ return Size(d_formattedRenderedString->getHorizontalExtent(),
+ d_formattedRenderedString->getVerticalExtent());
+}
+
+//----------------------------------------------------------------------------//
+void FormattedListboxTextItem::draw(GeometryBuffer& buffer,
+ const Rect& targetRect,
+ float alpha, const Rect* clipper) const
+{
+ // reparse text if we need to.
+ if (!d_renderedStringValid)
+ parseTextString();
+
+ // create formatter if needed
+ if (!d_formattedRenderedString)
+ setupStringFormatter();
+
+ // get size of render area from target window, to see if we need to reformat
+ // NB: We do not use targetRect, since it may not represent the same area.
+ const Size area_sz(static_cast<const Listbox*>(d_owner)->
+ getListRenderArea().getSize());
+ if (area_sz != d_formattingAreaSize)
+ {
+ d_formattedRenderedString->format(area_sz);
+ d_formattingAreaSize = area_sz;
+ }
+
+ // draw selection imagery
+ if (d_selected && d_selectBrush != 0)
+ d_selectBrush->draw(buffer, targetRect, clipper,
+ getModulateAlphaColourRect(d_selectCols, alpha));
+
+ // factor the window alpha into our colours.
+ const ColourRect final_colours(
+ getModulateAlphaColourRect(ColourRect(0xFFFFFFFF), alpha));
+
+ // draw the formatted text
+ d_formattedRenderedString->draw(buffer, targetRect.getPosition(),
+ &final_colours, clipper);
+}
+
+//----------------------------------------------------------------------------//
+void FormattedListboxTextItem::setupStringFormatter() const
+{
+ // delete any existing formatter
+ delete d_formattedRenderedString;
+ d_formattedRenderedString = 0;
+
+ // create new formatter of whichever type...
+ switch(d_formatting)
+ {
+ case HTF_LEFT_ALIGNED:
+ d_formattedRenderedString =
+ new LeftAlignedRenderedString(d_renderedString);
+ break;
+
+ case HTF_RIGHT_ALIGNED:
+ d_formattedRenderedString =
+ new RightAlignedRenderedString(d_renderedString);
+ break;
+
+ case HTF_CENTRE_ALIGNED:
+ d_formattedRenderedString =
+ new CentredRenderedString(d_renderedString);
+ break;
+
+ case HTF_JUSTIFIED:
+ d_formattedRenderedString =
+ new JustifiedRenderedString(d_renderedString);
+ break;
+
+ case HTF_WORDWRAP_LEFT_ALIGNED:
+ d_formattedRenderedString =
+ new RenderedStringWordWrapper
+ <LeftAlignedRenderedString>(d_renderedString);
+ break;
+
+ case HTF_WORDWRAP_RIGHT_ALIGNED:
+ d_formattedRenderedString =
+ new RenderedStringWordWrapper
+ <RightAlignedRenderedString>(d_renderedString);
+ break;
+
+ case HTF_WORDWRAP_CENTRE_ALIGNED:
+ d_formattedRenderedString =
+ new RenderedStringWordWrapper
+ <CentredRenderedString>(d_renderedString);
+ break;
+
+ case HTF_WORDWRAP_JUSTIFIED:
+ d_formattedRenderedString =
+ new RenderedStringWordWrapper
+ <JustifiedRenderedString>(d_renderedString);
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------//
+}
diff --git a/widgets/FormattedListboxTextItem.h b/widgets/FormattedListboxTextItem.h
new file mode 100644
index 0000000..efe5ff2
--- /dev/null
+++ b/widgets/FormattedListboxTextItem.h
@@ -0,0 +1,54 @@
+#ifndef FORMATTEDLISTBOXTEXTITEM_H
+#define FORMATTEDLISTBOXTEXTITEM_H
+
+// TODO: Remove temporary workaround for CEGUI + GCC 4.6
+#include <cstddef>
+
+#include "CEGUI.h"
+
+namespace CEGUI
+{
+//! A ListboxItem based class that can do horizontal text formatiing.
+class FormattedListboxTextItem : public ListboxTextItem
+{
+public:
+ //! Constructor
+ FormattedListboxTextItem(const String& text,
+ const HorizontalTextFormatting format = HTF_LEFT_ALIGNED,
+ const uint item_id = 0,
+ void* const item_data = 0,
+ const bool disabled = false,
+ const bool auto_delete = true);
+
+ //! Destructor.
+ ~FormattedListboxTextItem();
+
+ //! Return the current formatting set.
+ HorizontalTextFormatting getFormatting() const;
+ /*!
+ Set the formatting. You should call Listbox::handleUpdatedItemData
+ after setting the formatting in order to update the listbox. We do not
+ do it automatically since you may wish to batch changes to multiple
+ items and multiple calls to handleUpdatedItemData is wasteful.
+ */
+ void setFormatting(const HorizontalTextFormatting fmt);
+
+ // overriden functions.
+ Size getPixelSize(void) const;
+ void draw(GeometryBuffer& buffer, const Rect& targetRect,
+ float alpha, const Rect* clipper) const;
+
+protected:
+ //! Helper to create a FormattedRenderedString of an appropriate type.
+ void setupStringFormatter() const;
+ //! Current formatting set
+ HorizontalTextFormatting d_formatting;
+ //! Class that renders RenderedString with some formatting.
+ mutable FormattedRenderedString* d_formattedRenderedString;
+ //! Tracks target area for rendering so we can reformat when needed
+ mutable Size d_formattingAreaSize;
+};
+
+}
+
+#endif
diff --git a/widgets/README b/widgets/README
new file mode 100644
index 0000000..3682ee3
--- /dev/null
+++ b/widgets/README
@@ -0,0 +1 @@
+FormattedListboxTextItem source: http://www.cegui.org.uk/phpBB2/viewtopic.php?f=10&t=4322