Duplicate the lua Painter class in C++.

develop
Alexander Gavrilov 2012-11-19 18:11:26 +04:00
parent 902d2d5597
commit 767c1b9368
4 changed files with 170 additions and 0 deletions

@ -74,6 +74,28 @@ namespace DFHack
uint32_t xpNxtLvl;
};
typedef std::pair<df::coord2d, df::coord2d> rect2d;
inline rect2d intersect(rect2d a, rect2d b) {
df::coord2d g1 = a.first, g2 = a.second;
df::coord2d c1 = b.first, c2 = b.second;
df::coord2d rc1 = df::coord2d(std::max(g1.x, c1.x), std::max(g1.y, c1.y));
df::coord2d rc2 = df::coord2d(std::min(g2.x, c2.x), std::min(g2.y, c2.y));
return rect2d(rc1, rc2);
}
inline rect2d mkrect_xy(int x1, int y1, int x2, int y2) {
return rect2d(df::coord2d(x1, y1), df::coord2d(x2, y2));
}
inline rect2d mkrect_wh(int x, int y, int w, int h) {
return rect2d(df::coord2d(x, y), df::coord2d(x+w-1, y+h-1));
}
inline df::coord2d rect_size(const rect2d &rect) {
return rect.second - rect.first + df::coord2d(1,1);
}
DFHACK_EXPORT int getdir(std::string dir, std::vector<std::string> &files);
DFHACK_EXPORT bool hasEnding (std::string const &fullString, std::string const &ending);

@ -29,6 +29,8 @@ distribution.
#include "ColorText.h"
#include <string>
#include "Types.h"
#include "DataDefs.h"
#include "df/init.h"
#include "df/ui.h"
@ -116,6 +118,9 @@ namespace DFHack
int map_x1, map_x2, menu_x1, menu_x2, area_x1, area_x2;
int y1, y2;
bool menu_on, area_on, menu_forced;
rect2d map() { return mkrect_xy(map_x1, y1, map_x2, y2); }
rect2d menu() { return mkrect_xy(menu_x1, y1, menu_x2, y2); }
};
DFHACK_EXPORT DwarfmodeDims getDwarfmodeViewDims();

@ -27,6 +27,7 @@ distribution.
#include "Module.h"
#include "BitArray.h"
#include "ColorText.h"
#include "Types.h"
#include <string>
#include "DataDefs.h"
@ -94,11 +95,67 @@ namespace DFHack
: ch(ch), fg(fg), bg(bg), bold(bold),
tile(tile), tile_mode(TileColor), tile_fg(tile_fg), tile_bg(tile_bg)
{}
void adjust(int8_t nfg) { fg = nfg&7; bold = !!(nfg&8); }
void adjust(int8_t nfg, bool nbold) { fg = nfg; bold = nbold; }
void adjust(int8_t nfg, int8_t nbg) { adjust(nfg); bg = nbg; }
void adjust(int8_t nfg, bool nbold, int8_t nbg) { adjust(nfg, nbold); bg = nbg; }
Pen color(int8_t nfg) const { Pen cp(*this); cp.adjust(nfg); return cp; }
Pen color(int8_t nfg, bool nbold) const { Pen cp(*this); cp.adjust(nfg, nbold); return cp; }
Pen color(int8_t nfg, int8_t nbg) const { Pen cp(*this); cp.adjust(nfg, nbg); return cp; }
Pen color(int8_t nfg, bool nbold, int8_t nbg) const { Pen cp(*this); cp.adjust(nfg, nbold, nbg); return cp; }
Pen chtile(char ch) { Pen cp(*this); cp.ch = ch; return cp; }
Pen chtile(char ch, int tile) { Pen cp(*this); cp.ch = ch; cp.tile = tile; return cp; }
};
struct ViewRect {
rect2d view, clip;
ViewRect(rect2d area) : view(area), clip(area) {}
ViewRect(rect2d area, rect2d clip) : view(area), clip(clip) {}
bool isDefunct() const {
return clip.first.x > clip.second.x || clip.first.y > clip.second.y;
}
int width() const { return view.second.x-view.first.x+1; }
int height() const { return view.second.y-view.first.y+1; }
df::coord2d local(df::coord2d pos) const {
return df::coord2d(pos.x - view.first.x, pos.y - view.first.y);
}
df::coord2d global(df::coord2d pos) const {
return df::coord2d(pos.x + view.first.x, pos.y + view.first.y);
}
df::coord2d global(int x, int y) const {
return df::coord2d(x + view.first.x, y + view.first.y);
}
bool inClipGlobal(int x, int y) const {
return x >= clip.first.x && x <= clip.second.x &&
y >= clip.first.y && y <= clip.second.y;
}
bool inClipGlobal(df::coord2d pos) const {
return inClipGlobal(pos.x, pos.y);
}
bool inClipLocal(int x, int y) const {
return inClipGlobal(x + view.first.x, y + view.first.y);
}
bool inClipLocal(df::coord2d pos) const {
return inClipLocal(pos.x, pos.y);
}
ViewRect viewport(rect2d area) const {
rect2d nview(global(area.first), global(area.second));
return ViewRect(nview, intersect(nview, clip));
}
};
DFHACK_EXPORT df::coord2d getMousePos();
DFHACK_EXPORT df::coord2d getWindowSize();
inline rect2d getScreenRect() {
return rect2d(df::coord2d(0,0), getWindowSize()-df::coord2d(1,1));
}
/// Returns the state of [GRAPHICS:YES/NO]
DFHACK_EXPORT bool inGraphicsMode();
@ -133,6 +190,77 @@ namespace DFHack
/// Retrieve the string representation of the bound key.
DFHACK_EXPORT std::string getKeyDisplay(df::interface_key key);
/// A painter class that implements a clipping area and cursor/pen state
struct DFHACK_EXPORT Painter : ViewRect {
df::coord2d gcursor;
Pen cur_pen, cur_key_pen;
static const Pen default_pen;
static const Pen default_key_pen;
Painter(const ViewRect &area, const Pen &pen = default_pen, const Pen &kpen = default_key_pen)
: ViewRect(area), gcursor(area.view.first), cur_pen(pen), cur_key_pen(kpen)
{}
df::coord2d cursor() const { return local(gcursor); }
int cursorX() const { return gcursor.x - view.first.x; }
int cursorY() const { return gcursor.y - view.first.y; }
bool isValidPos() const { return inClipGlobal(gcursor); }
Painter viewport(rect2d area) const {
return Painter(ViewRect::viewport(area), cur_pen, cur_key_pen);
}
Painter &seek(df::coord2d pos) { gcursor = global(pos); return *this; }
Painter &seek(int x, int y) { gcursor = global(x,y); return *this; }
Painter &advance(int dx) { gcursor.x += dx; return *this; }
Painter &advance(int dx, int dy) { gcursor.x += dx; gcursor.y += dy; return *this; }
Painter &newline(int dx = 0) { gcursor.y++; gcursor.x = view.first.x + dx; return *this; }
const Pen &pen() const { return cur_pen; }
Painter &pen(const Pen &np) { cur_pen = np; return *this; }
Painter &pen(int8_t fg) { cur_pen.adjust(fg); return *this; }
const Pen &key_pen() const { return cur_key_pen; }
Painter &key_pen(const Pen &np) { cur_key_pen = np; return *this; }
Painter &key_pen(int8_t fg) { cur_key_pen.adjust(fg); return *this; }
Painter &clear() {
fillRect(Pen(' ',0,0,false), clip.first.x, clip.first.y, clip.second.x, clip.second.y);
return *this;
}
Painter &fill(const rect2d &area, const Pen &pen) {
rect2d irect = intersect(area, clip);
fillRect(pen, irect.first.x, irect.first.y, irect.second.x, irect.second.y);
return *this;
}
Painter &fill(const rect2d &area) { return fill(area, cur_pen); }
Painter &tile(const Pen &pen) {
if (isValidPos()) paintTile(pen, gcursor.x, gcursor.y);
return advance(1);
}
Painter &tile() { return tile(cur_pen); }
Painter &tile(char ch) { return tile(cur_pen.chtile(ch)); }
Painter &tile(char ch, int tileid) { return tile(cur_pen.chtile(ch, tileid)); }
Painter &string(const std::string &str, const Pen &pen) {
do_paint_string(str, pen); return advance(str.size());
}
Painter &string(const std::string &str) { return string(str, cur_pen); }
Painter &string(const std::string &str, int8_t fg) { return string(str, cur_pen.color(fg)); }
Painter &key(df::interface_key kc, const Pen &pen) {
return string(getKeyDisplay(kc), pen);
}
Painter &key(df::interface_key kc) { return key(kc, cur_key_pen); }
private:
void do_paint_string(const std::string &str, const Pen &pen);
};
}
class DFHACK_EXPORT dfhack_viewscreen : public df::viewscreen {

@ -234,6 +234,21 @@ bool Screen::invalidate()
return true;
}
const Pen Screen::Painter::default_pen(0,COLOR_GREY,0);
const Pen Screen::Painter::default_key_pen(0,COLOR_LIGHTGREEN,0);
void Screen::Painter::do_paint_string(const std::string &str, const Pen &pen)
{
if (gcursor.y < clip.first.y || gcursor.y > clip.second.y)
return;
int dx = std::max(0, int(clip.first.x - gcursor.x));
int len = std::min((int)str.size(), int(clip.second.x - gcursor.x + 1));
if (len > dx)
paintString(pen, gcursor.x + dx, gcursor.y, str.substr(dx, len-dx));
}
bool Screen::findGraphicsTile(const std::string &pagename, int x, int y, int *ptile, int *pgs)
{
if (!gps || !texture || x < 0 || y < 0) return false;