git-svn-id: svn://db.shs.com.ru/pip@530 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2017-07-19 16:05:27 +00:00
parent 44cbdc1f4a
commit e6b1ef3fb1
13 changed files with 272 additions and 24 deletions

View File

@@ -3,9 +3,19 @@
int main(int argc, char *argv[]) {
PIKbdListener kbd;
/*PIKbdListener kbd;
kbd.enableExitCapture();
kbd.start();
kbd.start();*/
/*PIScreen s(false);
PIScreenTile t;
t.minimumHeight = t.minimumWidth = t.maximumHeight = t.maximumWidth = 1;
t.back_format.color_back = PIScreenTypes::Green;
s.rootTile()->addTile(&t);
s.rootTile()->addTile(new PIScreenTile());
s.enableExitCapture();
s.start();
piMSleep(100);
piCout << t.x() << t.y() << t.width() << t.height();*/
WAIT_FOR_EXIT
return 0;
}

View File

@@ -155,6 +155,7 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * _d, bool startNow): PIThread()
is_active = true;
ret_func = slot;
kbddata_ = _d;
dbl_interval = 400;
PIKbdListener::exiting = exit_enabled = false;
if (startNow) start();
}
@@ -270,30 +271,43 @@ void PIKbdListener::readKeyboard() {
me.modifiers = getModifiers(mer.dwControlKeyState);
MouseButtons mb = getButtons(mer.dwButtonState);
//me.action = getButtons(mer.dwButtonState);
me.x = mer.dwMousePosition.X;
me.y = mer.dwMousePosition.Y - PRIVATE->sbi.srWindow.Top;
if (mer.dwEventFlags & MOUSE_WHEELED) {
memcpy(&we, &me, sizeof(me));
we.action = MouseWheel;
we.direction = short((mer.dwButtonState >> 8) & 0xFFFF) > 0;
piCout << "wheel" << we.direction;
//piCout << "wheel" << we.direction;
wheelEvent(we, kbddata_);
break;
} else {
me.x = mer.dwMousePosition.X;
me.y = mer.dwMousePosition.Y - PRIVATE->sbi.srWindow.Top;
bool move = mer.dwEventFlags & MOUSE_MOVED;
if (move && (me.action == MouseButtonRelease)) {
if (move) {
if (me.action == MouseButtonRelease) {
me.action = MouseMove;
return;
}
if (!move) {
if (mb > me.buttons) me.action = MouseButtonPress;
if (me.buttons == 0) return;
me.action = MouseMove;
} else {
if (mb > me.buttons) {
if (tm_dbl.elapsed_m() <= dbl_interval && prev_p_me.x == me.x && prev_p_me.y == me.y)
me.action = MouseButtonDblClick;
else {
me.action = MouseButtonPress;
prev_p_me = me;
}
tm_dbl.reset();
}
else if (mb < me.buttons) me.action = MouseButtonRelease;
else {piCoutObj << "WTF"; break;}
} else
me.action = MouseMove;
}
me.buttons = mb;
PIString _s[] = {"press", "release", "move"};
piCoutObj << _s[me.action] << me.buttons << ":" << me.x << me.y;
if (piCompareBinary(&prev_me, &me, sizeof(me)))
break;
memcpy(&prev_me, &me, sizeof(me));
//PIString _s[] = {"press", "release", "dbl click", "move"};
//piCoutObj << _s[me.action] << me.buttons << ":" << me.x << me.y;
mouseEvent(me, kbddata_);
break;
}
@@ -359,10 +373,21 @@ void PIKbdListener::readKeyboard() {
case 0: me.buttons = MouseLeft; break;
case 1: me.buttons = MouseMiddle; break;
case 2: me.buttons = MouseRight; break;
default: break;
}
if (a == 0x20) {
if (b == 3) me.action = MouseButtonRelease;
else me.action = MouseButtonPress;
if (b == 3) {
me.action = MouseButtonRelease;
me.buttons = 0;
} else {
if (tm_dbl.elapsed_m() <= dbl_interval && prev_p_me.x == me.x && prev_p_me.y == me.y)
me.action = MouseButtonDblClick;
else {
me.action = MouseButtonPress;
prev_p_me = me;
}
tm_dbl.reset();
}
}
if (a == 0x40) me.action = MouseMove;
PIString _s[] = {"press", "release", "move"};

View File

@@ -98,6 +98,7 @@ public:
enum MouseAction {
MouseButtonPress /** Mouse button pressed */,
MouseButtonRelease /** Mouse button released */,
MouseButtonDblClick /** Mouse button double click */,
MouseMove /** Mouse moved */,
MouseWheel /** Mouse wheel rotated */
};
@@ -156,6 +157,9 @@ public:
//! Returns exit key, default 'Q'
int exitKey() const {return exit_key;}
double doubleClickInterval() const {return dbl_interval;}
void setDoubleClickInterval(double v) {dbl_interval = v;}
void readKeyboard();
//! Returns if keyboard listening is active (not running!)
@@ -228,8 +232,10 @@ private:
bool exit_enabled, is_active;
void * kbddata_;
char rc[8];
double dbl_interval;
PITimeMeasurer tm_dbl;
KeyEvent ke;
MouseEvent me;
MouseEvent me, prev_me, prev_p_me;
WheelEvent we;
static PIKbdListener * _object;

View File

@@ -49,6 +49,7 @@ PRIVATE_DEFINITION_END(PIScreen::SystemConsole)
PIScreen::SystemConsole::SystemConsole() {
width = height = pwidth = pheight = 0;
mouse_x = mouse_y = -1;
int w, h;
#ifdef WINDOWS
PRIVATE->ulcoord.X = 0;
@@ -147,6 +148,9 @@ void PIScreen::SystemConsole::resize(int w, int h) {
void PIScreen::SystemConsole::print() {
if (mouse_x >= 0 && mouse_x < width && mouse_y >= 0 && mouse_y < height) {
///cells[mouse_y][mouse_x].format.flags ^= Inverse;
}
#ifdef WINDOWS
//static int cnt = 0;
PRIVATE->srect = PRIVATE->sbi.srWindow;
@@ -384,10 +388,13 @@ PIScreen::PIScreen(bool startNow, PIKbdListener::KBFunc slot): PIThread(), drawe
setName("screen");
setPriority(piLow);
needLockRun(true);
mouse_ = false;
ret_func = slot;
tile_focus = tile_dialog = 0;
root.screen = this;
listener = new PIKbdListener(key_eventS, this, startNow);
CONNECTU(listener, mouseEvent, this, mouse_event);
CONNECTU(listener, wheelEvent, this, wheel_event);
if (startNow) start();
}
@@ -401,6 +408,14 @@ PIScreen::~PIScreen() {
}
void PIScreen::setMouseEnabled(bool on) {
mouse_ = on;
//lock();
console.mouse_x = console.mouse_y = -1;
//unlock();
}
void PIScreen::key_event(PIKbdListener::KeyEvent key) {
/** DEBUG
if (ret_func != 0) ret_func(key, t);
@@ -423,6 +438,61 @@ void PIScreen::key_event(PIKbdListener::KeyEvent key) {
}
PIVector<PIScreenTile * > PIScreen::prepareMouse(PIKbdListener::MouseEvent * e) {
PIVector<PIScreenTile * > ret;
if (!mouse_ || !e) return ret;
console.mouse_x = e->x;
console.mouse_y = e->y;
PIVector<PIScreenTile * > tl = tilesUnderMouse(e->x, e->y);
bool ff = false;
piForeachR (PIScreenTile * t, tl) {
if (!ff) {
if (t->focus_flags[FocusOnMouse] && (e->action == PIKbdListener::MouseButtonPress)) {
t->setFocus();
ff = true;
}
if (t->focus_flags[FocusOnWheel] && (e->action == PIKbdListener::MouseWheel)) {
t->setFocus();
ff = true;
}
}
}
return tl;
}
PIVector<PIScreenTile * > PIScreen::tilesUnderMouse(int x, int y) {
PIVector<PIScreenTile * > ret;
if (x < 0 || x >= console.width || y < 0 || y >= console.height) return ret;
PIScreenTile * ct = tile_dialog ? tile_dialog : rootTile();
bool f = true;
while (ct) {
if (!f) ret << ct;
f = false;
ct = ct->childUnderMouse(x, y);
}
return ret;
}
void PIScreen::mouse_event(PIKbdListener::MouseEvent me) {
PIVector<PIScreenTile * > tl = prepareMouse(&me);
if (tl.isEmpty()) return;
piForeachR (PIScreenTile * t, tl)
if (t->mouseEvent(me)) piBreak;
}
void PIScreen::wheel_event(PIKbdListener::WheelEvent we) {
PIVector<PIScreenTile * > tl = prepareMouse(&we);
if (tl.isEmpty()) return;
piForeachR (PIScreenTile * t, tl)
if (t->wheelEvent(we)) piBreak;
}
bool PIScreen::nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key) {
PIVector<PIScreenTile*> vtl = rt->children(true), ftl;
piForeach (PIScreenTile * t, vtl) {

View File

@@ -53,6 +53,9 @@ public:
int windowWidth() const {return console.width;}
int windowHeight() const {return console.height;}
bool isMouseEnabled() const {return mouse_;}
void setMouseEnabled(bool on);
PIScreenTile * rootTile() {return &root;}
PIScreenTile * tileByName(const PIString & name);
@@ -122,6 +125,7 @@ private:
#endif
PRIVATE_DECLARATION
int width, height, pwidth, pheight;
int mouse_x, mouse_y;
PIVector<PIVector<PIScreenTypes::Cell> > cells, pcells, dcells;
};
@@ -129,13 +133,18 @@ private:
void run();
void end();
void key_event(PIKbdListener::KeyEvent key);
EVENT_HANDLER1(void, mouse_event, PIKbdListener::MouseEvent, me);
EVENT_HANDLER1(void, wheel_event, PIKbdListener::WheelEvent, we);
static void key_eventS(PIKbdListener::KeyEvent key, void * t) {((PIScreen*)t)->key_event(key);}
PIVector<PIScreenTile*> tiles() {return root.children();}
PIVector<PIScreenTile*> prepareMouse(PIKbdListener::MouseEvent * e);
PIVector<PIScreenTile*> tilesUnderMouse(int x, int y);
bool nextFocus(PIScreenTile * rt, PIKbdListener::KeyEvent key = PIKbdListener::KeyEvent());
void tileEventInternal(PIScreenTile * t, PIScreenTypes::TileEvent e);
void tileRemovedInternal(PIScreenTile * t);
void tileSetFocusInternal(PIScreenTile * t);
bool mouse_;
SystemConsole console;
PIScreenDrawer drawer_;
PIKbdListener * listener;

View File

@@ -85,6 +85,18 @@ PIVector<PIScreenTile * > PIScreenTile::children(bool only_visible) {
}
PIScreenTile * PIScreenTile::childUnderMouse(int x, int y) {
piForeach (PIScreenTile * t, tiles) {
if (!t->visible) continue;
if (x >= t->x_ && (x - t->x_) < t->width_ &&
y >= t->y_ && (y - t->y_) < t->height_) {
return t;
}
}
return 0;
}
void PIScreenTile::raiseEvent(TileEvent e) {
if (!screen) return;
screen->tileEventInternal(this, e);

View File

@@ -40,6 +40,7 @@ public:
void removeTile(PIScreenTile * t);
PIScreenTile * parentTile() const {return parent;}
PIVector<PIScreenTile * > children(bool only_visible = false);
PIScreenTile * childUnderMouse(int x, int y);
void show() {visible = true;}
void hide() {visible = false;}
void setFocus();
@@ -77,6 +78,12 @@ protected:
//! Return "true" if you process key
virtual bool keyEvent(PIKbdListener::KeyEvent key) {return false;}
//! Return "true" if you process event
virtual bool mouseEvent(PIKbdListener::MouseEvent me) {return false;}
//! Return "true" if you process wheel
virtual bool wheelEvent(PIKbdListener::WheelEvent we) {return false;}
void raiseEvent(PIScreenTypes::TileEvent e);
void setScreen(PIScreenTypes::PIScreenBase * s);
void deleteChildren();

View File

@@ -117,12 +117,18 @@ void TileScrollBar::drawEvent(PIScreenDrawer * d) {
}
bool TileScrollBar::mouseEvent(PIKbdListener::MouseEvent me) {
return true;
}
TileList::TileList(const PIString & n): PIScreenTile(n) {
alignment = Left;
focus_flags = CanHasFocus | NextByArrowsHorizontal | NextByTab;
focus_flags = CanHasFocus | NextByArrowsHorizontal | NextByTab | FocusOnMouseOrWheel;
lhei = offset = cur = 0;
mouse_sel = false;
selection_mode = NoSelection;
scroll = new TileScrollBar();
scroll->size_policy = Ignore;
@@ -277,10 +283,50 @@ bool TileList::keyEvent(PIKbdListener::KeyEvent key) {
}
bool TileList::mouseEvent(PIKbdListener::MouseEvent me) {
if (me.action == PIKbdListener::MouseButtonRelease) return true;
int mp = me.y - y() - 1 + offset;
if (mp < 0 || mp >= content.size_s()) return true;
cur = mp;
switch (me.action) {
case PIKbdListener::MouseButtonPress:
mouse_sel = !selected.contains(cur);
break;
case PIKbdListener::MouseButtonDblClick:
keyEvent(PIKbdListener::KeyEvent(PIKbdListener::Return));
//raiseEvent(TileEvent(RowPressed, cur));
return true;
default: break;
}
if (me.buttons[PIKbdListener::MouseRight]) {
switch (selection_mode) {
case SingleSelection:
selected.clear();
selected << cur;
raiseEvent(TileEvent(SelectionChanged));
break;
case MultiSelection:
if (mouse_sel) selected << cur;
else selected.remove(cur);
raiseEvent(TileEvent(SelectionChanged));
break;
default: break;
}
}
return true;
}
bool TileList::wheelEvent(PIKbdListener::WheelEvent we) {
keyEvent(PIKbdListener::KeyEvent(we.direction ? PIKbdListener::PageUp : PIKbdListener::PageDown));
return true;
}
TileButton::TileButton(const PIString & n): PIScreenTile(n) {
focus_flags = CanHasFocus | NextByTab | NextByArrowsAll;
focus_flags = CanHasFocus | NextByTab | NextByArrowsAll | FocusOnMouse;
}
@@ -310,10 +356,17 @@ bool TileButton::keyEvent(PIKbdListener::KeyEvent key) {
}
bool TileButton::mouseEvent(PIKbdListener::MouseEvent me) {
if (me.action != PIKbdListener::MouseButtonRelease) return true;
keyEvent(PIKbdListener::KeyEvent(PIKbdListener::Return));
return true;
}
TileButtons::TileButtons(const PIString & n): PIScreenTile(n) {
focus_flags = CanHasFocus | NextByTab;
focus_flags = CanHasFocus | NextByTab | FocusOnMouse;
direction = Horizontal;
alignment = PIScreenTypes::Center;
cur = 0;
@@ -339,6 +392,7 @@ void TileButtons::sizeHint(int & w, int & h) const {
void TileButtons::drawEvent(PIScreenDrawer * d) {
int cx = x_, cy = y_, shw, shh;
sizeHint(shw, shh);
btn_rects.resize(content.size());
int dx = 0;
switch (alignment) {
case PIScreenTypes::Center: dx = (width_ - shw) / 2; break;
@@ -362,6 +416,7 @@ void TileButtons::drawEvent(PIScreenDrawer * d) {
cw = width_ - 2;
xo = (cw - b.first.size_s()) / 2 - 1;
}
btn_rects[i] = (Rect){cx, cy, cx + cw + 2, cy + 1};
d->fillRect(cx, cy, cx + cw + 2, cy + 1, ' ', Default, cb);
d->drawText(cx, cy, "[", ct, Transparent, ff);
d->drawText(cx + xo + 2, cy, b.first, ct, Transparent, ff);
@@ -395,10 +450,26 @@ bool TileButtons::keyEvent(PIKbdListener::KeyEvent key) {
}
bool TileButtons::mouseEvent(PIKbdListener::MouseEvent me) {
if (me.action == PIKbdListener::MouseMove || me.action == PIKbdListener::MouseButtonPress) {
for (int i = 0; i < btn_rects.size_s(); ++i)
if (me.x >= btn_rects[i].x0 && me.x < btn_rects[i].x1 &&
me.y >= btn_rects[i].y0 && me.y < btn_rects[i].y1) {
cur = i;
break;
}
return true;
}
if (me.action != PIKbdListener::MouseButtonRelease) return true;
keyEvent(PIKbdListener::KeyEvent(PIKbdListener::Return));
return true;
}
TileCheck::TileCheck(const PIString & n): PIScreenTile(n) {
focus_flags = CanHasFocus | NextByTab | NextByArrowsAll;
focus_flags = CanHasFocus | NextByTab | NextByArrowsAll | FocusOnMouse;
toggled = false;
}
@@ -431,6 +502,12 @@ bool TileCheck::keyEvent(PIKbdListener::KeyEvent key) {
}
bool TileCheck::mouseEvent(PIKbdListener::MouseEvent me) {
if (me.action == PIKbdListener::MouseButtonPress)
keyEvent(PIKbdListener::KeyEvent(PIKbdListener::Return));
}
TileProgress::TileProgress(const PIString & n): PIScreenTile(n) {
@@ -504,7 +581,7 @@ bool TilePICout::keyEvent(PIKbdListener::KeyEvent key) {
TileInput::TileInput(const PIString & n): PIScreenTile(n) {
focus_flags = CanHasFocus | NextByTab;
focus_flags = CanHasFocus | NextByTab | FocusOnMouse;
back_format.color_back = White;
format.color_char = Black;
format.color_back = White;

View File

@@ -27,6 +27,7 @@
class PIP_EXPORT TileSimple: public PIScreenTile {
PIOBJECT_SUBCLASS(TileSimple, PIScreenTile)
public:
typedef PIPair<PIString, PIScreenTypes::CellFormat> Row;
TileSimple(const PIString & n = PIString());
@@ -42,6 +43,7 @@ protected:
class TileList;
class PIP_EXPORT TileScrollBar: public PIScreenTile {
PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile)
friend class TileList;
public:
TileScrollBar(const PIString & n = PIString());
@@ -56,12 +58,14 @@ protected:
void _check();
void sizeHint(int & w, int & h) const;
void drawEvent(PIScreenDrawer * d);
bool mouseEvent(PIKbdListener::MouseEvent me);
int minimum_, maximum_, value_;
PIChar line_char;
};
class PIP_EXPORT TileList: public PIScreenTile {
PIOBJECT_SUBCLASS(TileList, PIScreenTile)
public:
TileList(const PIString & n = PIString());
~TileList();
@@ -85,11 +89,15 @@ protected:
void resizeEvent(int w, int h);
void drawEvent(PIScreenDrawer * d);
bool keyEvent(PIKbdListener::KeyEvent key);
bool mouseEvent(PIKbdListener::MouseEvent me);
bool wheelEvent(PIKbdListener::WheelEvent we);
TileScrollBar * scroll;
bool mouse_sel;
};
class PIP_EXPORT TileButton: public PIScreenTile {
PIOBJECT_SUBCLASS(TileButton, PIScreenTile)
public:
TileButton(const PIString & n = PIString());
enum EventType {
@@ -101,12 +109,14 @@ protected:
void sizeHint(int & w, int & h) const;
void drawEvent(PIScreenDrawer * d);
bool keyEvent(PIKbdListener::KeyEvent key);
bool mouseEvent(PIKbdListener::MouseEvent me);
};
class PIP_EXPORT TileButtons: public PIScreenTile {
PIOBJECT_SUBCLASS(TileButtons, PIScreenTile)
public:
TileButtons(const PIString & n = PIString());
enum EventType {
@@ -120,10 +130,14 @@ protected:
void sizeHint(int & w, int & h) const;
void drawEvent(PIScreenDrawer * d);
bool keyEvent(PIKbdListener::KeyEvent key);
bool mouseEvent(PIKbdListener::MouseEvent me);
struct Rect {int x0,y0,x1,y1;};
PIVector<Rect> btn_rects;
};
class PIP_EXPORT TileCheck: public PIScreenTile {
PIOBJECT_SUBCLASS(TileCheck, PIScreenTile)
public:
TileCheck(const PIString & n = PIString());
enum EventType {
@@ -136,10 +150,12 @@ protected:
void sizeHint(int & w, int & h) const;
void drawEvent(PIScreenDrawer * d);
bool keyEvent(PIKbdListener::KeyEvent key);
bool mouseEvent(PIKbdListener::MouseEvent me);
};
class PIP_EXPORT TileProgress: public PIScreenTile {
PIOBJECT_SUBCLASS(TileProgress, PIScreenTile)
public:
TileProgress(const PIString & n = PIString());
PIScreenTypes::CellFormat format;
@@ -154,6 +170,7 @@ protected:
class PIP_EXPORT TilePICout: public TileList {
PIOBJECT_SUBCLASS(TilePICout, PIScreenTile)
public:
TilePICout(const PIString & n = PIString());
PIScreenTypes::CellFormat format;
@@ -165,6 +182,7 @@ protected:
class PIP_EXPORT TileInput: public PIScreenTile {
PIOBJECT_SUBCLASS(TileInput, PIScreenTile)
public:
TileInput(const PIString & n = PIString());
/*enum EventType {
@@ -185,6 +203,7 @@ protected:
class PIP_EXPORT TileTabs: public PIScreenTile {
PIOBJECT_SUBCLASS(TileTabs, PIScreenTile)
public:
TileTabs(const PIString & n = PIString());
enum EventType {

View File

@@ -86,7 +86,10 @@ namespace PIScreenTypes {
NextByTab /** Focus passed to next tile by tab key */ = 0x2,
NextByArrowsHorizontal /** Focus passed to next tile by arrow keys left or right */ = 0x4,
NextByArrowsVertical /** Focus passed to next tile by arrow keys up or down */ = 0x8,
NextByArrowsAll /** Focus passed to next tile by any arrow key */ = NextByArrowsHorizontal | NextByArrowsVertical
NextByArrowsAll /** Focus passed to next tile by any arrow key */ = NextByArrowsHorizontal | NextByArrowsVertical,
FocusOnMouse /** Tile focused on mouse press */ = 0x10,
FocusOnWheel /** Tile focused on wheel */ = 0x20,
FocusOnMouseOrWheel /** Tile focused on mouse press or wheel */ = FocusOnMouse | FocusOnWheel
};
typedef PIFlags<CharFlag> CharFlags;

View File

@@ -249,6 +249,15 @@ template<typename T> inline void piSwapBinary(T & f, T & s) {
}
}
/*! \brief Function for compare two values without "=" by raw content
* \details Example:\n \snippet piincludes.cpp compareBinary */
inline bool piCompareBinary(const void * f, const void * s, size_t size) {
for (size_t i = 0; i < size; ++i)
if (((const uchar*)f)[i] != ((const uchar*)s)[i])
return false;
return true;
}
/*! \brief Templated function return round of float falue
* \details Round is the nearest integer value \n
* There are some macros:

View File

@@ -5,6 +5,6 @@
#define PIP_VERSION_MAJOR 1
#define PIP_VERSION_MINOR 0
#define PIP_VERSION_REVISION 0
#define PIP_VERSION_SUFFIX "_rc4"
#define PIP_VERSION_SUFFIX "_rc5"
#endif // PIVERSION_H

View File

@@ -390,6 +390,7 @@ int main(int argc, char * argv[]) {
PIINTROSPECTION_START
//cli.addArgument("");
screen = new PIScreen(false);
screen->setMouseEnabled(true);
Daemon * daemon = new Daemon();
if (!sip.isEmpty()) daemon->setTcpServerIP(sip);
sys_mon.startOnSelf();