/* TUIpeer works in conjunction with an implementation of java.awt.Toolkit to provide a Text User Interface for programs using the Java AWT. ContainerComponent is the C++ peer of java.awt.Container 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. */ /* * $Log: container.cc,v $ * Revision 1.2 2000/12/18 01:58:57 stuart * Removed dependencies on libg++. * Changed all references to String to string. * Changed libg++ String idioms to string idioms. * Copied Obstack from libg++ and hacked it to throw an exception on error. * Hacked Set.cc to throw an exception on error. * Added Str.cc to relace the split function from libg++. * * Revision 1.1.1.1 2000/12/16 20:44:52 stuart * Released TUIPeer sources * * Revision 1.2 2000/12/14 20:58:53 stuart * Container for components * */ #pragma implementation #include #include #include "container.h" #include "textdraw.h" #include "wincomp.h" #include "menucomp.h" #include "textcomp.h" #include "listcomp.h" #include "canvas.h" #include "scrollbar.h" #include ContainerComponent::ContainerComponent() { bgColor = 1; fgColor = 0; textAttr = getAttr(); curfocus = 0; } ContainerComponent::~ContainerComponent() { removeAll(); } int ContainerComponent::indexOf(Controller *c) { int n = components.size(); if (n > 0) { Component **a = &components[0]; for (int i = 0; i < n; ++i) if (a[i] == c) return i; } return -1; } void ContainerComponent::add(Component *c) { int i = indexOf(c); if (i < 0) { components.add(c); c->setParent(this); } else { components.del(i); components.add(c); } } void ContainerComponent::remove(Component *c) { int i = indexOf(c); if (i >= 0) { components.del(i); c->setParent(0); } } void ContainerComponent::removeAll() { if (components.size() == 0) return; Component **a = &components[0]; int n = components.size(); for (int i = 0; i < n; ++i) { Component *c = a[i]; a[i] = 0; c->setParent(0); } components.clear(); } void ContainerComponent::remoteMethod(int cmd) { Component *obj; switch (cmd) { case NEWFRAME: obj = new FrameComponent; // NOTE: TUIKit is not prepared for gotfocus event at this point break; case NEWWINDOW: obj = new WindowComponent(getFrame()); break; case NEWDIALOG: obj = new Dialog(getFrame()); break; case NEWMENUBAR: add(obj = new MenuBarComponent); break; case NEWMENU: add(obj = new MenuComponent); break; case NEWMENUITEM: case NEWCHECKMENUITEM: add(obj = new MenuItemComponent); break; case NEWLABEL: add(obj = new LabelComponent); break; case NEWBUTTON: add(obj = new Button); break; case NEWTEXTFIELD: add(obj = new TextField); break; case NEWTEXTAREA: add(obj = new TextArea); break; case NEWPANEL: add(obj = new ContainerComponent); break; case NEWCHECKBOX: add(obj = new CheckBox); break; case NEWCHOICE: add(obj = new Choice); break; case NEWLIST: add(obj = new ListComponent); break; case NEWCANVAS: add(obj = new Canvas); break; case NEWVERTSCROLL: add(obj = new Scrollbar(Scrollbar::VERT)); break; case NEWHORZSCROLL: add(obj = new Scrollbar(Scrollbar::HORZ)); break; case ADDCOMPONENT: { int id = readShort(); Component *c = toolkit->componentAt(id); if (c) add(c); return; } case BEEP: Window::beep(); return; case SYNC: Ksync(); return; case SHOWURL: { string s = readUTF(); string cmd("lynx " + s); toolkit->runProg(cmd); return; } case REQUESTFOCUS: if (parent) { Component *c = getTab(); ContainerComponent *p = c->getParent(); p->setfocus(c); return; } case NEWSCROLLPANE: case NEWPOPUPMENU: default: Canvas::remoteMethod(cmd); return; } toolkit->addComponent(obj,readShort()); } void ContainerComponent::paint(DrawingContext *dc) { //fprintf(stderr,"DC(%d): %s\n",compID,dc->asString().chars()); Canvas::paint(dc); int n = components.size(); if (n > 0) { Rect clip(dc->clipRect()); Component **a = &components[0]; for (int i = n; --i >= 0;) { Component *c = a[i]; if (!c) continue; if (!c->isVisible()) continue; Rect r1(c->bounds().intersect(clip)); if (r1.isempty()) continue; IndirectContext gc(dc->create()); gc.clipRect(r1); Point loc(c->location()); gc.translate(loc.col,loc.row); //fprintf(stderr,"GC: %s\n",gc.asString().chars()); fflush(stderr); c->paint(&gc); } } } void ContainerComponent::getfocus() { Component *c = getTab(); if (c == this) { if (parent) parent->nextFocus(); } else if (c->isEnabled()) setfocus(c); else nextFocus(); } void ContainerComponent::losefocus() { } void ContainerComponent::setfocus(Controller *c) { //fprintf(stderr,"Container%d::setfocus\n",compID); setTab(c); if (parent) parent->setfocus(c); else Component::setfocus(c); } void ContainerComponent::setTab(Controller *c) { int i = indexOf(c); if (i >= 0) { curfocus = i; if (parent) parent->setTab(this); } } Component *ContainerComponent::getTab() { if (curfocus >= 0 && curfocus < countComponents()) return components[curfocus]; return this; } void ContainerComponent::nextFocus() { int n = countComponents(); if (n) for (int i = curfocus + 1; i != curfocus; ++i) { if (i >= n) { i = 0; if (parent) { curfocus = i; parent->nextFocus(); return; } break; } Component *c = components[i]; if (c->isEnabled()) { curfocus = i; setfocus(c); return; } } Component::getfocus(); // no enabled components! } void ContainerComponent::prevFocus() { int n = countComponents(); if (n) for (int i = curfocus - 1; i != curfocus; --i) { if (i < 0) { i = n - 1; if (parent) { curfocus = i; parent->prevFocus(); return; } break; } Component *c = components[i]; if (c->isEnabled()) { curfocus = i; setfocus(c); return; } } Component::getfocus(); // no enabled components! } // set focus to first enabled component bool ContainerComponent::focusForward() { int n = components.size(); if (n > 0) { Component **a = &components[0]; for (int i = 0; i < n; ++i) { Component *c = a[i]; if (c->focusForward()) { setTab(c); return true; } } } return false; } // set focus to last enabled component bool ContainerComponent::focusBackward() { int n = components.size(); if (n > 0) { Component **a = &components[0]; for (int i = n - 1; i >= 0; --i) { Component *c = a[i]; if (c->focusBackward()) { setTab(c); return true; } } } return false; } Component *ContainerComponent::locate(int x,int y) const { if (!inside(x,y)) return 0; int n = components.size(); if (!n) return 0; Component **a = &components[0]; for (int i = 0; i < n; ++i) { Point p(a[i]->location()); if (a[i]->inside(x - p.col,y - p.row)) return a[i]; } return 0; } FrameComponent *ContainerComponent::getFrame() const { return parent ? parent->getFrame() : 0; } ContainerComponent *ContainerComponent::obscured() { ContainerComponent *p = Canvas::obscured(); if (p) return this; int n = components.size(); if (!n) return 0; Component **a = &components[0]; for (int i = 0; i < n; ++i) { if (a[i]->isVisible()) return this; } return 0; }