/* TUIpeer works in conjunction with an implementation of java.awt.Toolkit to provide a Text User Interface for programs using the Java AWT. Copyright (C) 1997-2000 Stuart D. Gathman This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #pragma implementation #include #include "wincomp.h" #include "menucomp.h" #include "windraw.h" #include struct WindowComponentContext: WindowContext { WindowComponentContext(WindowComponent *win) { this->win = win; } void paint(DrawingContext *dc); private: WindowComponent *win; }; void WindowComponentContext::paint(DrawingContext *dc) { win->paint(dc); } WindowComponent::WindowComponent(FrameComponent *frame) { owner = frame; win = new WindowComponentContext(this); win->setCaption("Java Window"); setDC(); } WindowComponent::~WindowComponent() { delete win; } IndirectContext *WindowComponent::getDC() { return new IndirectContext(win); } IndirectContext *Dialog::getDC() { IndirectContext *dc = WindowComponent::getDC(); //dc->translate(-1,-1); return dc; } void WindowComponent::remoteMethod(int cmd) { switch (cmd) { case TOBACK: win->bury(); return; case TOFRONT: win->top(); return; } ContainerComponent::remoteMethod(cmd); } void WindowComponent::reshape(int x,int y,int w,int h) { bool resized = (w != width || h != height); ContainerComponent::reshape(x,y,w,h); //win->setphys(bounds().intersect(win->screen)); // done by show if (resized) invalidate(); } static WindowComponent *active = 0; void WindowComponent::getfocus() { win->top(); win->setActive(true); if (this != active) { toolkit->callMethod(compID,TOFRONT); active = this; } ContainerComponent::getfocus(); } void WindowComponent::losefocus() { if (this == active) win->setActive(false); } Dialog::Dialog(FrameComponent *frame): WindowComponent(frame) { win->setCaption("Java Dialog"); win->translate(-1,-1); sizable = true; modalDialog = 0; } Dialog::~Dialog() { toolkit->removeFrame(this); } FrameComponent::FrameComponent(): Dialog(0) { win->setCaption("Java Frame"); menu = 0; } FrameComponent::~FrameComponent() { setMenu(0); } void WindowComponent::repaint(const Rect &r) { // FIXME: queue up in dirtyRect //fprintf(stderr,"WindowComponent::repaint(%d,%d,%d,%d)\n", // r.c1,r.r1,r.width(),r.height()); IndirectContext gc(win); gc.clipRect(r); paint(&gc); } void Dialog::repaint(const Rect &r) { IndirectContext gc(win); //gc.translate(-1,-1); gc.clipRect(r); paint(&gc); } void FrameComponent::setMenu(MenuContainer *m) { if (menu) { MenuContainer *oldm = menu; menu = 0; oldm->setFrame(0); } if (m) m->setFrame(this); menu = m; } void FrameComponent::key(int c) { switch (c) { case KEY_OPTIONS: if (menu) { menu->show(true); Ksync(); } return; case KEY_F(20): invalidate(); return; } Dialog::key(c); } void Dialog::key(int c) { switch (c) { case KEY_F(15): if (sizable) { win->sizeFromUser(); int x = (win->loc.c1 - 1) * toolkit->scalex; int y = (win->loc.r1 - 1) * toolkit->scaley; int w = (win->loc.width() + 2) * toolkit->scalex; int h = (win->loc.height() + 2) * toolkit->scaley; toolkit->callMethod(compID,RESHAPE,x,y,w,h); } return; case KEY_F(17): if (sizable) { if (win->isZoomed()) win->unzoom(); else win->zoom(Rect(Point(0,0),win->screen.width(),win->screen.height())); int x = (win->loc.c1 - 1) * toolkit->scalex; int y = (win->loc.r1 - 1) * toolkit->scaley; int w = (win->loc.width() + 2) * toolkit->scalex; int h = (win->loc.height() + 2) * toolkit->scaley; toolkit->callMethod(compID,RESHAPE,x,y,w,h); } return; } WindowComponent::key(c); } void WindowComponent::key(int c) { int x = win->getX(); int y = win->getY(); switch (c) { //case KEY_F(1): case KEY_CLOSE: toolkit->callMethod(compID,DISPOSE); return; #if 0 case KEY_LEFT: if (x > 0) setCursor(--x,y); break; case KEY_RIGHT: if (x + 1 < bounds().width()) setCursor(++x,y); break; case KEY_UP: if (y > 0) setCursor(x,--y); break; case KEY_DOWN: if (y + 1 < bounds().height()) setCursor(x,++y); break; #endif default: ContainerComponent::key(c); return; } Component *comp = locate(x,y); if (comp && comp != Controller::curfocus()) setfocus(comp); } void WindowComponent::setfocus(Controller *c) { //fprintf(stderr,"Window%d::setfocus\n",compID); setTab(c); toolkit->setfocus(this); //Component::setfocus(c); } bool WindowComponent::nextFocus(Component *base) { if (base == 0) return false; Component *target = base; do { ContainerComponent *p = target->getParent(); if (!p) break; bool found = false; int n = p->countComponents(); for (int i = 0; i < n; ++i) { Component *c = p->getComponent(i); if (found) { if (c->focusForward()) { setTab(c); return true; } } else if (c == target) found = true; } target = p; } while (target != this); return focusForward(); // wrap around } bool WindowComponent::prevFocus(Component *base) { if (base == 0) return false; Component *target = base; do { ContainerComponent *p = target->getParent(); if (!p) break; bool found = false; int n = p->countComponents(); for (int i = n-1; i >= 0; --i) { Component *c = p->getComponent(i); if (found) { if (c->focusBackward()) { setTab(c); return true; } } else if (c == target) found = true; } target = p; } while (target != this); return focusBackward(); // wrap around } void WindowComponent::nextFocus() { if (nextFocus(getTab())) setfocus(getTab()); } void WindowComponent::prevFocus() { if (prevFocus(getTab())) setfocus(getTab()); } void Dialog::setTitle(const string &s) { title = s; win->setTitle(title.c_str()); } void FrameComponent::remoteMethod(int cmd) { switch (cmd) { case SETMENU: { int id = (short)readShort(); if (id < 0) setMenu(0); else setMenu(toolkit->componentAt(id)->asMenu()); return; } } Dialog::remoteMethod(cmd); } void Dialog::remoteMethod(int cmd) { switch (cmd) { case SETRESIZABLE: sizable = readShort() != 0; return; case SETTITLE: setTitle(readUTF()); Ksync(); return; case TOFRONT: toolkit->addFrame(this); // fall through } WindowComponent::remoteMethod(cmd); } void WindowComponent::show(bool b) { if (visible != b) { visible = b; if (visible) { int x = Component::posx; int y = Component::posy; Rect r(y + 1,x + 1,y + height - 2,x + width - 2); win->setphys(r.intersect(win->screen)); //invalidate(); toolkit->setfocus(this); } else { Controller::setfocus(0); win->hide(); } Ksync(); } else if (visible) { win->top(); toolkit->setfocus(this); } } void Dialog::show(bool b) { WindowComponent::show(b); if (b) toolkit->addFrame(this); else toolkit->removeFrame(this); } void WindowComponent::setCursor(int t) { enum { // java cursor types DEFAULT = 0, CROSSHAIR = 1, TEXT = 2, WAIT = 3, HAND = 12, MOVE = 13 }; switch (t) { case WAIT: t = 0; break; case DEFAULT: case TEXT: t = 1; break; default: t = 2; } win->curtype(t); } void WindowComponent::setCursor(int x,int y) { if (x < 0) x = 0; if (x >= width) x = width - 1; if (y < 0) y = 0; if (y >= height) y = height - 1; win->setCursor(x,y); } void Dialog::setCursor(int x,int y) { //WindowComponent::setCursor(--x, --y); WindowComponent::setCursor(x, y); } FrameComponent *WindowComponent::getFrame() const { return owner ? owner->getFrame() : 0; } /* FIXME: casting away const */ FrameComponent *FrameComponent::getFrame() const { return (FrameComponent *)this; } void FrameComponent::getfocus() { Dialog::getfocus(); if (menu) { menu->display(); fprintf(stderr,"frame::getfocus::menu::display\n"); } }