예제 #1
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::expose(unsigned line, unsigned column) 
{
	if (! canvas_)
		return;

	String string;
	if (line < text_->Height()) 
	{
		string = text_->getNth(line);
	}
	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	Coord x = columnCoord(string, column) - allocation_->left() + curLowerX_;
	bool invisibleX = (x < curLowerX_) || ((x + width(' ')) > curUpperX_);
	Coord y = line * (fbb.ascent() + fbb.descent());

	bool invisibleY = (y < curLowerY_) || ((y + fbb.ascent() +
		fbb.descent()) > curUpperY_);
	if (invisibleX) 
	{
		scroll_to(Dimension_X, x - (curUpperX_ - curLowerX_) / 2);
	}
	if (invisibleY) 
	{
		scroll_to(Dimension_Y, height() - y - (curUpperY_ - curLowerY_) / 2);
	}
}
예제 #2
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void TextLine::request(Requisition& requisition) const 
{
	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	Text::request(requisition);
	Requirement ry(fbb.ascent() + fbb.descent(), 0, 0, 0);
	requisition.require(Dimension_Y, ry);
}
예제 #3
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::scroll_backward(DimensionName dimension) {
  FontBoundingBox fbb;
  font_->font_bbox(fbb);
  if (dimension == Dimension_X) {
    scroll_to(dimension, cur_lower(Dimension_X) - width(' '));
  } else {
    scroll_to(dimension, cur_lower(Dimension_Y) -
      (fbb.ascent() + fbb.descent()));
  }
}
예제 #4
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::drawRegion(const TextRegion& region, unsigned i,
  Coord x, Coord y, const String& line) const 
{
	unsigned line1 = region.line1();
	unsigned line2 = region.line2();
	unsigned column1 = region.column1();
	unsigned column2 = region.column2();
	FontBoundingBox fbb;
	font_->font_bbox(fbb);

	if ((line1 == i) && (line1 == line2) && (column1 < column2)) 
	{
		canvas_->fill_rect(columnCoord(line, column1), y - fbb.descent(),
			columnCoord(line, column2), y + fbb.ascent(), region.color());
	}
	if ((line1 == i) && (line1 < line2)) 
	{
		canvas_->fill_rect(columnCoord(line, column1), y - fbb.descent(),
			allocation_->right(), y + fbb.ascent(), region.color());
	}
	if ((line1 < i) && (i < line2)) 
	{
		canvas_->fill_rect(x, y - fbb.descent(), allocation_->right(), y +
			fbb.ascent(), region.color());
	}
	if ((line2 == i) && (line1 < line2)) 
	{
		canvas_->fill_rect(0, y - fbb.descent(), columnCoord(line, column2),
			y + fbb.ascent(), region.color());
	}
}
예제 #5
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::request(Requisition& requisition) const 
{
	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	Requirement rx(width(' ') * initialColumns_, fil,
		width(' ') * (initialColumns_ - 1), 0);
	Requirement ry((fbb.ascent() + fbb.descent()) * initialLines_, fil,
		(fbb.ascent() + fbb.descent()) * (initialLines_ - 1), 0);
	requisition.require(Dimension_X, rx);
	requisition.require(Dimension_Y, ry);
}
예제 #6
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
bool Text::damaged(unsigned line) const 
{
	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	Coord base = allocation_->top() + curLowerY_;
	Coord lineHeight = fbb.ascent() + fbb.descent();
	Coord top = base - lineHeight * line;
	Coord bottom = base - lineHeight * (line + 1);
	return canvas_->damaged(allocation_->left(), Math::max(bottom,
		allocation_->bottom()), allocation_->right(), Math::min(top,
		allocation_->top()));
}
예제 #7
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::drawLocation(const TextLocation& location, unsigned i,
  Coord /* x */, Coord y, const String& line) const 
{
	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	if (location.line_ == i) 
	{
		Coord lb = columnCoord(line, location.column_);
		canvas_->fill_rect(lb, y - fbb.descent(), lb + location.width_,
			y + fbb.ascent(), location.color_);
	}
}
예제 #8
0
void FieldStringEditor::print(Printer* p, const Allocation& a) const {
    const Font* f = output_->GetFont();
    const Color* fg = output_->GetFgColor();
    FontBoundingBox b;
    f->font_bbox(b);
    Coord x = a.left(), y = a.bottom() + b.font_descent();
    FieldStringEditor* e = (FieldStringEditor*)this;
    for (const char* s = e->Text(); *s != '\0'; s++) {
	Coord w = f->width(*s);
	p->character(f, *s, w, fg, x, y);
	x += w;
    }
}
예제 #9
0
Strut::Strut(
    const Font* font, Coord natural, Coord stretch, Coord shrink
) : Glyph() {
    font_ = font;
    Resource::ref(font_);
    if (font_ != nil) {
	FontBoundingBox b;
	font_->font_bbox(b);
	height_ = b.ascent() + b.descent();
	alignment_ = (height_ == 0) ? 0 : b.descent() / height_;
    }
    natural_ = natural;
    stretch_ = stretch;
    shrink_ = shrink;
}
예제 #10
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::damage(const TextRegion& region) {
  if (! canvas_) {
    return;
  }

  FontBoundingBox fbb;
  font_->font_bbox(fbb);
  Coord base = allocation_->top() + curLowerY_;
  Coord lineHeight = fbb.ascent() + fbb.descent();
  Coord top = Math::min(base - lineHeight * region.line1(), allocation_->top());
  Coord bottom = Math::max(base - lineHeight * (region.line2() + 1),
    allocation_->bottom());
  if ((allocation_->left() <= allocation_->right()) && (bottom <= top)) {
    canvas_->damage(allocation_->left(), bottom, allocation_->right(), top);
  }
}
예제 #11
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::draw(Canvas*, const Allocation&) const 
{
	canvas_->push_clipping();
	canvas_->clip_rect(allocation_->left(), allocation_->bottom(),
		allocation_->right(), allocation_->top());

	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	Coord r = curLowerY_ / (fbb.ascent() + fbb.descent());
	unsigned i = unsigned(r);
	Coord y = allocation_->top() + (r - i) * (fbb.ascent() + fbb.descent());
	unsigned max = Math::max(Math::max(selection_.line2(), insertion_.line_),
		(unsigned) text_->Height() ? (unsigned) text_->Height() - 1 : 0);
	for (; i <= max; ++i) 
	{
		y -= fbb.ascent();

		if (damaged(i)) 
		{
			Coord x = allocation_->left() - curLowerX_;
			if (i < text_->Height()) 
			{
				const String line = text_->getNth(i);
				drawRegion(selection_, i, x, y, line);
				if (! readOnly_) 
				{
					drawLocation(insertion_, i, x, y, line);
				}
				for (GlyphIndex j = 0; j < annotation_.count(); ++j) 
				{
					drawRegion(*annotation_.item(j), i, x, y, line);
				}
				drawLine(i, x, y, line);
			} 
			else 
			{
				String line;
				drawRegion(selection_, i, x, y, line);
				if (! readOnly_) 
				{
					drawLocation(insertion_, i, x, y, line);
				}
				for (GlyphIndex j = 0; j < annotation_.count(); ++j) 
				{
					drawRegion(*annotation_.item(j), i, x, y, line);
				}
				drawLine(i, x, y, line);
			}
		}
  
		y -= fbb.descent();
		if (y < (allocation_->bottom() - fbb.ascent())) 
			break;
	}
	canvas_->pop_clipping();
}
예제 #12
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
void Text::damage(const TextLocation& location) {
  if (! canvas_) {
    return;
  }
//mlh to get horizontal scrolling. Not well understood yet.
  expose(0, location.column_);
  
  FontBoundingBox fbb;
  font_->font_bbox(fbb);
  Coord base = allocation_->top() + curLowerY_;
  Coord lineHeight = fbb.ascent() + fbb.descent();
  Coord top = Math::min(base - lineHeight * location.line_, allocation_->top());
  Coord bottom = Math::max(base - lineHeight * (location.line_ + 1),
    allocation_->bottom());
  if ((allocation_->left() <= allocation_->right()) && (bottom <= top)) {
    canvas_->damage(allocation_->left(), bottom, allocation_->right(), top);
  }
}
예제 #13
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
bool Text::snap(
	const Event& event, 
	unsigned& line, 
	unsigned& column) const 
{
	unsigned originalLine = line;
	unsigned originalColumn = column;

	Coord x = event.pointer_x() - allocation_->left() + curLowerX_;
	Coord y = allocation_->top() + curLowerY_ - event.pointer_y();

	FontBoundingBox fbb;
	font_->font_bbox(fbb);
	line = Math::max(int(y / (fbb.ascent() + fbb.descent())), 0);
	if (line < text_->Height()) 
	{
		const String& string = text_->getNth(line);
		unsigned i;
		for (i = 0; i < string.length(); ++i) 
		{
			x -= width(string[i]) / 2.0;
			if (x < 0) 
				break;
			x -= width(string[i]) / 2.0;
		}
		column = i;
		if (i > 0 && string[i-1] == '\n') {
			--column;
		}
  //		if (i >= string.length())
  //			column += (unsigned) ((x + width(' ') / 2) / width(' '));
	} 
	else if (text_->Height() > 0) { 
		line = text_->Height()-1;
		column = text_->getNth(line).length(); 
		//column = (unsigned) ((x + width(' ') / 2) / width(' '));
	}else{
		line = 0;
		column = 0;
	}
	column = Math::max(column, unsigned(0));

	return (line != originalLine) || (column != originalColumn);
}
예제 #14
0
Space::Space(int count, float each, const Font* f, const Color* c) : Glyph() {
    count_ = count;
    each_ = each;
    font_ = f;
    Resource::ref(font_);
    color_ = c;
    Resource::ref(color_);
    if (font_ != nil) {
	FontBoundingBox b;
	font_->font_bbox(b);
	Coord ascent = b.ascent();
	Coord descent = b.descent();
	width_ = font_->width(' ') * each_ * count_;
	height_ = ascent + descent;
	alignment_ = (height_ == 0) ? 0 : descent / height_;
    } else {
	width_ = 0;
	height_ = 0;
	alignment_ = 0;
    }
}
예제 #15
0
Character::Character(long ch, const Font* f, const Color* c) : Glyph() {
    c_ = ch;
    font_ = f;
    Resource::ref(font_);
    color_ = c;
    Resource::ref(color_);
    if (font_ != nil) {
	FontBoundingBox b;
	font_->char_bbox(c_, b);
	left_bearing_ = b.left_bearing();
	right_bearing_ = b.right_bearing();
	width_ = b.width();
	ascent_ = b.font_ascent();
	descent_ = b.font_descent();
	height_ = ascent_ + descent_;
	alignment_ = (height_ == 0) ? 0 : descent_ / height_;
    } else {
	left_bearing_ = 0;
	right_bearing_ = 0;
	ascent_ = 0;
	descent_ = 0;
	width_ = 0;
	height_ = 0;
	alignment_ = 0;
    }
}
예제 #16
0
void Text31::init () {
    LayoutKit* layout = LayoutKit::instance();
    PolyGlyph* col = layout->vbox();
    PolyGlyph* line = layout->hbox();
    FontBoundingBox bbox;
    _font->font_bbox(bbox);
    Coord lineheight = bbox.ascent() + bbox.descent();
    char ch;
    
    for (int i = 0; (*_text)[i] != '\0'; i++) {
        ch = (*_text)[i];

        if (ch == '\n') {
            line->append(layout->strut(_font));
            col->append(layout->fixed_dimension(line, Dimension_Y,lineheight));
            line = layout->hbox();
        } else if (ch == ' ') {
            line->append(new Character(' ', _font, _stroke));
        } else if (ch != ')' && ch != '(') {
            if (ch == '\\') {
                ch = (*_text)[++i];
                if (isdigit(ch)) {
                    ch -= '0';
                    ch *= 8;
                    char digit;
                    digit = (*_text)[i++];
                    ch = (ch * 8) + digit - '0';
                    digit = (*_text)[i++];
                    ch = (ch * 8) + digit - '0';
                }
            }
            line->append(new Character(ch, _font, _stroke));
        }
    }

    Transformer fixtext;
    fixtext.translate(0, bbox.descent());
    _t->premultiply(fixtext);
    _body->append(col);
}
예제 #17
0
파일: iv3text.cpp 프로젝트: PNCG/neuron
Coord Text::height() const {
  FontBoundingBox fbb;
  font_->font_bbox(fbb);
  return text_->Height() * (fbb.ascent() + fbb.descent());
}
예제 #18
0
Glyph* read_idraw_graphic (
    FILE* file, const Brush* pb, const Color* pfg, const Color* pbg,
    const Font* pf, Stipple* ps
) {
    skip(file);
    Transformer tx;
    Glyph* glyph = nil;
    const LayoutKit& layout = *LayoutKit::instance();
    if (fscanf(file, "%s", buffer) != EOF) {
        figure& fig = figures[which(figures, buffer)];

        if (strcmp(fig.name, "Idraw") == 0) {
            fscanf(file, "%d", &drawing_version);
            figures = versions[drawing_version];
        }
        const Brush* b = (fig.brush) ? read_brush(file) : nil;
        const Color* fg = (fig.foreground) ? read_color(file) : nil;
        const Color* bg = (fig.background) ? read_color(file) : nil;
        const Font* f = (fig.font) ? read_font(file) : nil;
        Stipple* s = (fig.pattern) ? read_stipple(file) : nil;
        if (fig.transformer) {
            read_transformer(file, tx);
        }

        if (pb) b = pb;
        if (pfg) fg = pfg;
        if (pbg) bg = pbg;
        if (pf) f = pf;
        if (ps) s = ps;

        if (fig.name == nil) {
            ; // error
        } else if (
            strcmp(fig.name, "Idraw") == 0 || strcmp(fig.name, "Pict") == 0
        ) {
            Glyph* pic = layout.overlay();
            Glyph* g;
            do {
                g = read_idraw_graphic(file, b, fg, bg, f, s);
                if (g != nil) {
                    pic->append(g);
                }
            } while (g != nil);
            glyph = pic;
        } else if (strcmp(fig.name, "eop") == 0) {
            glyph = nil;
        } else if (strcmp(fig.name, "Text") == 0) {
            skip(file);
            fscanf(file, "%s", buffer);
            getc(file);
            PolyGlyph* col = layout.vbox_first_aligned();
            PolyGlyph* line = layout.hbox_first_aligned();
	    FontBoundingBox bbox;
	    f->font_bbox(bbox);
            Coord lineheight = bbox.font_ascent() + bbox.font_descent();
            if (_idraw_font_metrics) {
                lineheight /= fixtextscale;
            }
            int c;
            while ((c = getc(file)) != ']') {
                if (c == '\n') {
                    line->append(layout.strut(f));
                    col->append(
			layout.v_fixed_span(line, lineheight)
		    );
                    line = layout.hbox();
                } else if (c == ' ') {
                    if (_idraw_font_metrics) {
                        line->append(
			    layout.shape_of(new Character(' ', f, fg))
			);
                    } else {
                        line->append(new Character(' ', f, fg));
                    }
                } else if (c != ')' && c != '(') {
                    if (c == '\\') {
                        c = getc(file);
			if (isdigit(c)) {
			    c -= '0';
			    c = (c * 8) + getc(file) - '0';
			    c = (c * 8) + getc(file) - '0';
			}
                    }
                    line->append(new Character(c, f, fg));
                }
            }
            Transformer fixtext;
            if (_idraw_font_metrics) {
                fixtext.scale(fixtextscale, fixtextscale);
            }
            fixtext.translate(0, bbox.font_descent() - lineheight);
            glyph = new TransformSetter(col, fixtext);
        } else {
            skip(file);
            int c = fig.coords;
            if (c == -1) { 
                fscanf(file, "%d", &c);
            }
            Coord xx, yy;
            Coord* x = new Coord[c];
            Coord* y = new Coord[c];
            for (int i = 0; i < c; ++i) {
                fscanf(file, "%g %g", &xx, &yy);
                x[i] = xx;
                y[i] = yy;
            }

            const Brush* brush = (b != no_brush) ? b : nil;
            const Color* stroke = fg;
            const Color* fill = (
                (s != no_stipple) ? dither_color(fg, bg, s->_dither) : nil
            );
            if (strcmp(fig.name, "Line") == 0) {
                glyph = new Line(brush, stroke, fill, x[0], y[0], x[1], y[1]);
            } else if (strcmp(fig.name, "BSpl") == 0) {
                glyph = new Open_BSpline(brush, stroke, fill, x, y, c);
            } else if (strcmp(fig.name, "CBSpl") == 0) {
                glyph = new Closed_BSpline(brush, stroke, fill, x, y, c);
            } else if (strcmp(fig.name, "MLine") == 0) {
                glyph = new Polyline(brush, stroke, fill, x, y, c);
            } else if (strcmp(fig.name, "Poly") == 0) {
                glyph = new Polygon(brush, stroke, fill, x, y, c);
            } else if (strcmp(fig.name, "Rect") == 0) {
                glyph = new Rectangle(brush, stroke, fill,x[0],y[0],x[1],y[1]);
            } else if (strcmp(fig.name, "Circ") == 0) {
                fscanf(file, "%f", &xx);
                glyph = new Circle(brush, stroke, fill, x[0], y[0], xx);
            } else if (strcmp(fig.name, "Elli") == 0) {
                fscanf(file, "%f %f", &xx, &yy);
                glyph = new Ellipse(brush, stroke, fill, x[0], y[0], xx, yy);
            } else {
                glyph = nil;
            }
            delete x;
            delete y;
        }
        for (int extra = fig.skip; extra > 0; --extra) {
            skip(file);
        }
    }
    if (glyph != nil && !tx.identity()) {
        glyph = new TransformSetter(glyph, tx);
    }
    return glyph;
}
예제 #19
0
int Font::Height() const {
    FontBoundingBox b;
    font_bbox(b);
    return impl_->default_rep()->display_->to_pixels(b.ascent() + b.descent());
}
예제 #20
0
int Font::Baseline() const {
    FontBoundingBox b;
    font_bbox(b);
    return impl_->default_rep()->display_->to_pixels(b.descent()) - 1;
}
예제 #21
0
void FileChooserImpl::build() {
    WidgetKit& kit = *kit_;
    const LayoutKit& layout = *LayoutKit::instance();
    Style* s = style_;
    kit.push_style();
    kit.style(s);
    String caption("");
    s->find_attribute("caption", caption);
    String subcaption("Enter filename:");
    s->find_attribute("subcaption", subcaption);
    String open("Open");
    s->find_attribute("open", open);
    String close("Cancel");
    s->find_attribute("cancel", close);
    long rows = 10;
    s->find_attribute("rows", rows);
    const Font* f = kit.font();
    FontBoundingBox bbox;
    f->font_bbox(bbox);
    Coord height = rows * (bbox.ascent() + bbox.descent()) + 1.0;
    Coord width;
    if (!s->find_attribute("width", width)) {
	width = 16 * f->width('m') + 3.0;
    }

    Action* accept = new ActionCallback(FileChooserImpl)(
	this, &FileChooserImpl::accept_browser
    );
    Action* cancel = new ActionCallback(FileChooserImpl)(
	this, &FileChooserImpl::cancel_browser
    );
    if (editor_ == nil) {
	editor_ = DialogKit::instance()->field_editor(
	    *dir_->path(), s,
	    new FieldEditorCallback(FileChooserImpl)(
		this, &FileChooserImpl::accept_editor,
		&FileChooserImpl::cancel_editor
	    )
	);
    }
    // added by ro2m: check for style for default selection
    String defsel("");
    if(s->find_attribute("defaultSelection", defsel)) {
      editor_->field(defsel);
    }

    fbrowser_ = new FileBrowser(kit_, accept, cancel);

    fchooser_->remove_all_input_handlers();
    fchooser_->append_input_handler(editor_);
    fchooser_->append_input_handler(fbrowser_);

    Glyph* g = layout.vbox();
    if (caption.length() > 0) {
	g->append(layout.rmargin(kit.fancy_label(caption), 5.0, fil, 0.0));
    }
    if (subcaption.length() > 0) {
	g->append(layout.rmargin(kit.fancy_label(subcaption), 5.0, fil, 0.0));
    }
    g->append(layout.vglue(5.0, 0.0, 2.0));
    g->append(editor_);
    g->append(layout.vglue(15.0, 0.0, 12.0));
    g->append(
	layout.hbox(
	    layout.vcenter(
		kit.inset_frame(
		    layout.margin(
			layout.natural_span(fbrowser_, width, height), 1.0
		    )
		),
		1.0
	    ),
	    layout.hspace(4.0),
	    kit.vscroll_bar(fbrowser_->adjustable())
	)
    );
    g->append(layout.vspace(15.0));
    if (s->value_is_on("filter")) {
	FieldEditorAction* action = new FieldEditorCallback(FileChooserImpl)(
	    this, &FileChooserImpl::accept_filter, nil
	);
	filter_ = add_filter(
	    s, "filterPattern", "", "filterCaption", "Filter:", g, action
	);
	if (s->value_is_on("directoryFilter")) {
	    directory_filter_ = add_filter(
		s, "directoryFilterPattern", "",
		"directoryFilterCaption", "Directory Filter:", g, action
	    );
	} else {
	    directory_filter_ = nil;
	}
    } else {
	filter_ = nil;
	directory_filter_ = nil;
    }
    g->append(
	layout.hbox(
	    layout.hglue(10.0),
	    layout.vcenter(kit.default_button(open, accept)),
	    layout.hglue(10.0, 0.0, 5.0),
	    layout.vcenter(kit.push_button(close, cancel)),
	    layout.hglue(10.0)
	)
    );

    fchooser_->body(
	layout.back(
	    layout.vcenter(kit.outset_frame(layout.margin(g, 5.0)), 1.0),
	    new Target(nil, TargetPrimitiveHit)
	)
    );
    fchooser_->focus(editor_);
    kit.pop_style();
    load();
}
예제 #22
0
void SymChooserImpl::build() {
    WidgetKit& kit = *kit_;
    const LayoutKit& layout = *LayoutKit::instance();
    Style* s = style_;
    kit.push_style();
    kit.style(s);
    String caption("");
    s->find_attribute("caption", caption);
    String subcaption("Enter  Symbol name:");
    s->find_attribute("subcaption", subcaption);
    String open("Accept");
    s->find_attribute("open", open);
    String close("Cancel");
    s->find_attribute("cancel", close);
    long rows = 10;
    s->find_attribute("rows", rows);
    const Font* f = kit.font();
    FontBoundingBox bbox;
    f->font_bbox(bbox);
    Coord height = rows * (bbox.ascent() + bbox.descent()) + 1.0;
    Coord width;
    if (!s->find_attribute("width", width)) {
	width = 16 * f->width('m') + 3.0;
    }

    int i;
    Action* accept = new ActionCallback(SymChooserImpl)(
	this, &SymChooserImpl::accept_browser
    );
    Action* cancel = new ActionCallback(SymChooserImpl)(
	this, &SymChooserImpl::cancel_browser
    );
    editor_ = DialogKit::instance()->field_editor(
	"", s,
	new FieldEditorCallback(SymChooserImpl)(
	    this, &SymChooserImpl::editor_accept, nil
	)
    );
    browser_index_ = 0;
    for (i=0; i < nbrowser_; ++i) {
	fbrowser_[i] = new FileBrowser(kit_,
		new SymBrowserAccept(this, i),
		nil);
    }
    fchooser_->remove_all_input_handlers();
    fchooser_->append_input_handler(editor_);
	for (i=0; i < nbrowser_; ++i) {
	    fchooser_->append_input_handler(fbrowser_[i]);
	}
    fchooser_->next_focus();

    Glyph* g = layout.vbox();
    if (caption.length() > 0) {
	g->append(layout.r_margin(kit.fancy_label(caption), 5.0, fil, 0.0));
    }
    if (subcaption.length() > 0) {
	g->append(layout.r_margin(kit.fancy_label(subcaption), 5.0, fil, 0.0));
    }
    g->append(layout.vglue(5.0, 0.0, 2.0));
    g->append(editor_);
    g->append(layout.vglue(5.0, 0.0, 2.0));
    g->append(makeshowmenu());
    g->append(layout.vglue(15.0, 0.0, 12.0));
    PolyGlyph* h = layout.hbox(nbrowser_);
    Glyph* b;
    for (i=0; i < nbrowser_; ++i) {
     b = layout.hbox(
	    layout.vcenter(
		kit.inset_frame(
		    layout.margin(
			layout.natural_span(fbrowser_[i], width, height), 1.0
		    )
		),
		1.0
	    ),
	    layout.hspace(4.0),
	    kit.vscroll_bar(fbrowser_[i]->adjustable())
	);
      h->append(b);
    }
    g->append(h);
    g->append(layout.vspace(15.0));
    if (s->value_is_on("filter")) {
	FieldEditorAction* action = new FieldEditorCallback(SymChooserImpl)(
	    this, &SymChooserImpl::filter_accept, nil
	);
	filter_ = add_filter(
	    s, "filterPattern", "", "filterCaption", "Filter:", g, action
	);
	if (s->value_is_on("directoryFilter")) {
	    directory_filter_ = add_filter(
		s, "directoryFilterPattern", "",
		"directoryFilterCaption", "Name Filter:", g, action
	    );
	} else {
	    directory_filter_ = nil;
	}
    } else {
	filter_ = nil;
	directory_filter_ = nil;
    }
    g->append(
	layout.hbox(
	    layout.hglue(10.0),
	    layout.vcenter(kit.default_button(open, accept)),
	    layout.hglue(10.0, 0.0, 5.0),
	    layout.vcenter(kit.push_button(close, cancel)),
	    layout.hglue(10.0)
	)
    );

    fchooser_->body(
	layout.vcenter(kit.outset_frame(layout.margin(g, 5.0)), 1.0)
    );
    kit.pop_style();
    load(0);
}