diff options
-rw-r--r-- | engines/gargoyle/events.h | 9 | ||||
-rw-r--r-- | engines/gargoyle/glk.cpp | 8 | ||||
-rw-r--r-- | engines/gargoyle/glk_types.h | 13 | ||||
-rw-r--r-- | engines/gargoyle/streams.h | 1 | ||||
-rw-r--r-- | engines/gargoyle/window_text_buffer.cpp | 8 | ||||
-rw-r--r-- | engines/gargoyle/window_text_grid.cpp | 8 | ||||
-rw-r--r-- | engines/gargoyle/windows.cpp | 102 | ||||
-rw-r--r-- | engines/gargoyle/windows.h | 10 |
8 files changed, 122 insertions, 37 deletions
diff --git a/engines/gargoyle/events.h b/engines/gargoyle/events.h index 4ee94707ea..939e691f78 100644 --- a/engines/gargoyle/events.h +++ b/engines/gargoyle/events.h @@ -93,15 +93,16 @@ enum Keycode { * Event structure */ struct Event { - EvType _type; - Window *_window; - uint32 _val1, _val2; + EvType type; + Window *window; + uint32 val1, val2; /** * Constructor */ - Event() : _type(evtype_None), _window(nullptr), _val1(0), _val2(0) {} + Event() : type(evtype_None), window(nullptr), val1(0), val2(0) {} }; +typedef Event event_t; class Events { public: diff --git a/engines/gargoyle/glk.cpp b/engines/gargoyle/glk.cpp index ba62de1573..26b8349d75 100644 --- a/engines/gargoyle/glk.cpp +++ b/engines/gargoyle/glk.cpp @@ -73,7 +73,13 @@ winid_t Glk::glk_window_open(winid_t split, glui32 method, glui32 size, glui32 w } void Glk::glk_window_close(winid_t win, stream_result_t *result) { - // TODO + _windows->_forceRedraw = true; + + if (!win) { + warning("glk_window_close: invalid ref"); + } else { + _windows->windowClose(win, result); + } } void Glk::glk_window_get_size(winid_t win, glui32 *widthptr, glui32 *heightptr) { diff --git a/engines/gargoyle/glk_types.h b/engines/gargoyle/glk_types.h index a25a413221..81d05ac391 100644 --- a/engines/gargoyle/glk_types.h +++ b/engines/gargoyle/glk_types.h @@ -220,19 +220,6 @@ enum ImageAlign { #endif /* GLK_MODULE_IMAGE */ -struct event_struct { - glui32 type; - Window *win; - glui32 val1, val2; -}; -typedef event_struct event_t; - -struct stream_result_struct { - glui32 readcount; - glui32 writecount; -}; -typedef stream_result_struct stream_result_t; - #ifdef GLK_MODULE_DATETIME struct glktimeval_struct { diff --git a/engines/gargoyle/streams.h b/engines/gargoyle/streams.h index 82d6465eb2..51ab484eb7 100644 --- a/engines/gargoyle/streams.h +++ b/engines/gargoyle/streams.h @@ -36,6 +36,7 @@ struct StreamResult { uint32 _readCount; uint32 _writeCount; }; +typedef StreamResult stream_result_t; /** * Base class for streams diff --git a/engines/gargoyle/window_text_buffer.cpp b/engines/gargoyle/window_text_buffer.cpp index b940fe60a7..a32a64f45a 100644 --- a/engines/gargoyle/window_text_buffer.cpp +++ b/engines/gargoyle/window_text_buffer.cpp @@ -756,10 +756,10 @@ void TextBufferWindow::cancelLineEvent(Event *ev) { _attr = _origAttr; - ev->_type = evtype_LineInput; - ev->_window = this; - ev->_val1 = len; - ev->_val2 = 0; + ev->type = evtype_LineInput; + ev->window = this; + ev->val1 = len; + ev->val2 = 0; _lineRequest = false; _lineRequestUni = false; diff --git a/engines/gargoyle/window_text_grid.cpp b/engines/gargoyle/window_text_grid.cpp index bf0f39cb93..d9550bfab8 100644 --- a/engines/gargoyle/window_text_grid.cpp +++ b/engines/gargoyle/window_text_grid.cpp @@ -360,10 +360,10 @@ void TextGridWindow::cancelLineEvent(Event *ev) { _curX = 0; _attr = _origAttr; - ev->_type = evtype_LineInput; - ev->_window = this; - ev->_val1 = _inLen; - ev->_val2 = 0; + ev->type = evtype_LineInput; + ev->window = this; + ev->val1 = _inLen; + ev->val2 = 0; _lineRequest = false; _lineRequestUni = false; diff --git a/engines/gargoyle/windows.cpp b/engines/gargoyle/windows.cpp index 6fb834d381..42db6f72f6 100644 --- a/engines/gargoyle/windows.cpp +++ b/engines/gargoyle/windows.cpp @@ -73,7 +73,7 @@ Windows::Windows(Graphics::Screen *screen) : _screen(screen), _windowList(nullpt Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size, glui32 wintype, glui32 rock) { Window *newwin, *oldparent; - PairWindow *pairwin; + PairWindow *pairWin; glui32 val; _forceRedraw = true; @@ -125,24 +125,24 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size, if (!splitwin) { _rootWin = newwin; } else { - // create pairwin, with newwin as the key - pairwin = newPairWindow(method, newwin, size); - pairwin->_child1 = splitwin; - pairwin->_child2 = newwin; + // create pairWin, with newwin as the key + pairWin = newPairWindow(method, newwin, size); + pairWin->_child1 = splitwin; + pairWin->_child2 = newwin; - splitwin->_parent = pairwin; - newwin->_parent = pairwin; - pairwin->_parent = oldparent; + splitwin->_parent = pairWin; + newwin->_parent = pairWin; + pairWin->_parent = oldparent; if (oldparent) { PairWindow *parentWin = dynamic_cast<PairWindow *>(oldparent); assert(parentWin); if (parentWin->_child1 == splitwin) - parentWin->_child1 = pairwin; + parentWin->_child1 = pairWin; else - parentWin->_child2 = pairwin; + parentWin->_child2 = pairWin; } else { - _rootWin = pairwin; + _rootWin = pairWin; } } @@ -151,6 +151,62 @@ Window *Windows::windowOpen(Window *splitwin, glui32 method, glui32 size, return newwin; } +void Windows::windowClose(Window *win, StreamResult *result) { + if (win == _rootWin || win->_parent == nullptr) { + // Close the root window, which means all windows. + _rootWin = nullptr; + + // Begin (simpler) closation + win->_stream->fillResult(result); + win->close(true); + } else { + // Have to jigger parent + Window *sibWin; + PairWindow *pairWin = dynamic_cast<PairWindow *>(win->_parent); + PairWindow *grandparWin; + + if (win == pairWin->_child1) { + sibWin = pairWin->_child2; + } else if (win == pairWin->_child2) { + sibWin = pairWin->_child1; + } else { + warning("windowClose: window tree is corrupted"); + return; + } + + grandparWin = dynamic_cast<PairWindow *>(pairWin->_parent); + if (!grandparWin) { + _rootWin = sibWin; + sibWin->_parent = nullptr; + } else { + if (grandparWin->_child1 == pairWin) + grandparWin->_child1 = sibWin; + else + grandparWin->_child2 = sibWin; + sibWin->_parent = grandparWin; + } + + // Begin closation + win->_stream->fillResult(result); + + // Close the child window (and descendants), so that key-deletion can + // crawl up the tree to the root window. + win->close(true); + + // This probably isn't necessary, but the child *is* gone, so just in case. + if (win == pairWin->_child1) + pairWin->_child1 = nullptr; + else if (win == pairWin->_child2) + pairWin->_child2 = nullptr; + + // Now we can delete the parent pair. + pairWin->close(false); + + // Sort out the arrangements + rearrange(); + } +} + Window *Windows::newWindow(glui32 type, glui32 rock) { Window *win; @@ -355,6 +411,30 @@ Window::~Window() { next->_prev = prev; } +void Window::close(bool recurse) { + if (_windows->getFocusWindow() == this) + // Focused window is being removed + _windows->setFocus(nullptr); + + for (Window *wx = _parent; wx; wx = wx->_parent) { + PairWindow *pairWin = dynamic_cast<PairWindow *>(wx); + + if (pairWin && pairWin->_key == this) { + pairWin->_key = nullptr; + pairWin->_keyDamage = true; + } + } + + PairWindow *pairWin = dynamic_cast<PairWindow *>(this); + if (pairWin) { + pairWin->_child1->close(recurse); + pairWin->_child2->close(recurse); + } + + // Finally, delete the window + delete this; +} + void Window::cancelLineEvent(Event *ev) { Event dummyEv; if (!ev) diff --git a/engines/gargoyle/windows.h b/engines/gargoyle/windows.h index ba9cb9210d..f52bbdd155 100644 --- a/engines/gargoyle/windows.h +++ b/engines/gargoyle/windows.h @@ -135,6 +135,11 @@ public: glui32 wintype, glui32 rock); /** + * Close an existing window + */ + void windowClose(Window *win, StreamResult *result = nullptr); + + /** * Return the root window */ Window *getRoot() const { return _rootWin; } @@ -284,6 +289,11 @@ public: virtual ~Window(); /** + * Close and delete the window + */ + void close(bool recurse = true); + + /** * Rearranges the window */ virtual void rearrange(const Common::Rect &box) { _bbox = box; } |