Fixes and optimizes cursor drawing for input windows.

This commit is contained in:
casey 2016-08-30 08:48:35 -07:00
parent 6baac20b9f
commit 604c589b47
3 changed files with 24 additions and 39 deletions

View File

@ -54,14 +54,6 @@
#include <csignal> #include <csignal>
#endif #endif
#ifdef WIN32
#define IDLE_TIMEOUT_MS 0
#define REDRAW_DEBOUNCE_MS 100
#else
#define IDLE_TIMEOUT_MS 75
#define REDRAW_DEBOUNCE_MS 100
#endif
using namespace cursespp; using namespace cursespp;
using namespace boost::chrono; using namespace boost::chrono;
@ -144,15 +136,12 @@ void App::Run(ILayoutPtr layout) {
if (this->state.input) { if (this->state.input) {
/* if the focused window is an input, allow it to draw a cursor */ /* if the focused window is an input, allow it to draw a cursor */
WINDOW *c = this->state.focused->GetContent(); WINDOW *c = this->state.focused->GetContent();
wtimeout(this->state.focused->GetContent(), IDLE_TIMEOUT_MS);
curs_set(1);
keypad(c, TRUE); keypad(c, TRUE);
ch = wgetch(c); ch = wgetch(c);
} }
else { else {
/* otherwise, no cursor */ /* otherwise, no cursor */
ch = wgetch(stdscr); ch = wgetch(stdscr);
curs_set(0);
} }
if (ch == ERR) { if (ch == ERR) {
@ -209,25 +198,11 @@ void App::Run(ILayoutPtr layout) {
} }
} }
void App::CheckDrawCursor() {
if (this->state.input != NULL) {
curs_set(1);
if (this->state.focused) {
wtimeout(this->state.focused->GetContent(), IDLE_TIMEOUT_MS);
}
}
else {
curs_set(0);
}
}
void App::UpdateFocusedWindow(IWindowPtr window) { void App::UpdateFocusedWindow(IWindowPtr window) {
if (this->state.focused != window) { if (this->state.focused != window) {
this->state.focused = window; this->state.focused = window;
this->state.input = dynamic_cast<IInput*>(window.get()); this->state.input = dynamic_cast<IInput*>(window.get());
this->state.keyHandler = dynamic_cast<IKeyHandler*>(window.get()); this->state.keyHandler = dynamic_cast<IKeyHandler*>(window.get());
this->CheckDrawCursor();
} }
} }

View File

@ -46,25 +46,27 @@ static int NEXT_ID = 0;
static bool drawPending = false; static bool drawPending = false;
static bool freeze = false; static bool freeze = false;
static inline void DrawCursor(IInput* input) {
if (input) {
Window* inputWindow = dynamic_cast<Window*>(input);
if (inputWindow) {
WINDOW* content = inputWindow->GetContent();
curs_set(1);
wtimeout(content, IDLE_TIMEOUT_MS);
wmove(content, 0, input->Position());
}
}
else {
curs_set(0);
}
}
void Window::WriteToScreen(IInput* input) { void Window::WriteToScreen(IInput* input) {
if (drawPending && !freeze) { if (drawPending && !freeze) {
drawPending = false; drawPending = false;
update_panels(); update_panels();
doupdate(); doupdate();
DrawCursor(input);
/* had problems finding reliable documentation here, but it seems like
manually moving the cursor requires a refresh() -- doupdate() is not
good enough. further, we allow windows to repaint themselves at will,
which may change the cursor position. after each draw cycle, move the
cursor back to the focused input. */
if (input) {
Window* inputWindow = dynamic_cast<Window*>(input);
if (inputWindow) {
wmove(inputWindow->GetContent(), 0, input->Position());
wrefresh(inputWindow->GetContent());
}
}
} }
} }

View File

@ -37,6 +37,14 @@
#include "curses_config.h" #include "curses_config.h"
#include "IWindow.h" #include "IWindow.h"
#ifdef WIN32
#define IDLE_TIMEOUT_MS 0
#define REDRAW_DEBOUNCE_MS 100
#else
#define IDLE_TIMEOUT_MS 75
#define REDRAW_DEBOUNCE_MS 100
#endif
namespace cursespp { namespace cursespp {
class IInput; class IInput;