ede/ecolorconf/EDE_FontChooser.cpp

358 lines
9.0 KiB
C++
Raw Permalink Normal View History

2007-07-18 22:20:04 +04:00
/*
* $Id$
*
* Font chooser widget
* Part of Equinox Desktop Environment (EDE).
* Copyright (c) 2000-2006 EDE Authors.
*
* Based on:
* Font demo program for the Fast Light Tool Kit (FLTK).
* Copyright 1998-2006 by Bill Spitzak and others.
*
* This program is licenced under terms of the
* GNU General Public Licence version 2 or newer.
* See COPYING for details.
*/
#include "EDE_FontChooser.h"
#define MAXSIZE 64
static fltk::Window *form = (fltk::Window *)0;
static fltk::Widget* id_box;
// class for font preview window
class FontDisplay : public fltk::Widget {
void draw();
public:
fltk::Font* font;
unsigned size;
const char* encoding;
FontDisplay(fltk::Box* B, int X, int Y, int W, int H, const char* L = 0) :
fltk::Widget(X,Y,W,H,L) {box(B); font = 0; size = 14;}
};
void FontDisplay::draw() {
draw_box();
fltk::push_clip(2,2,w()-2,h()-2);
const char* saved_encoding = fltk::get_encoding();
fltk::set_encoding(encoding);
fltk::setfont(font, (float) size);
id_box->label(fltk::Font::current_name());
id_box->redraw();
fltk::setcolor(fltk::BLACK);
char buffer[32];
for (int Y = 1; Y < 8; Y++) {
for (int X = 0; X < 32; X++) buffer[X] = (32*Y+X);
fltk::drawtext(buffer, 32, 3, 3+(size+leading())*Y);
}
fltk::set_encoding(saved_encoding);
fltk::pop_clip();
}
// other variables
static FontDisplay *textobj;
static fltk::Browser *fontobj, *sizeobj, *encobj;
static fltk::Font** all_fonts; // list returned by fltk
static int numfonts=0;
static fltk::Group *button_group;
static fltk::CheckButton* bold_button, *italic_button;
static fltk::Button *ok_button, *cancel_button;
bool return_value = false;
// callback functions
// callback for list of fonts
void font_cb(fltk::Widget *, long)
{
int fn = fontobj->value();
//DEBUG
//printf("font: %d name: %s bigname: %s\n", fn, fonts[fn]->name(), fonts[fn]->system_name());
fltk::Font* f = all_fonts[fn];
// are bold and italic available?
if (f->bold() == f)
bold_button->deactivate();
else
bold_button->activate();
if (f->italic() == f)
italic_button->deactivate();
else
italic_button->activate();
if (bold_button->value()) f = f->bold();
if (italic_button->value()) f = f->italic();
textobj->font = f;
// Populate the encobj (browser for font encodings)
char saved[30];
if (textobj->encoding)
strncpy(saved, textobj->encoding, 29);
else
saved[0] = 0;
encobj->clear();
const char** encodings;
int ne = f->encodings(encodings);
int picked = -1;
int iso8859 = 0;
// On XFT encoding is always Unicode, so encodings() will return 0
if (ne==0)
{
encobj->add("Unicode");
encobj->deselect();
encobj->deactivate();
textobj->encoding=0;
}
else
{
encobj->activate();
for (int i = 0; i < ne; i++) {
encobj->add(encodings[i]);
if (!strcmp(encodings[i], saved)) picked = i;
if (!strcmp(encodings[i], fltk::get_encoding())) iso8859 = i;
}
if (picked < 0) picked = iso8859;
textobj->encoding = encodings[picked];
encobj->value(picked);
}
// Populate the sizeobj (browser for font sizes)
int pickedsize;
if (sizeobj->value() > 0) {
pickedsize = atoi(sizeobj->child(sizeobj->value())->label());
} else {
pickedsize = 14;
}
sizeobj->clear();
int *s;
int n = f->sizes(s);
if(!n) {
// no sizes (this only happens on X)
for (int i = 1; i<MAXSIZE; i++) {
char buf[20];
sprintf(buf,"%d",i);
sizeobj->add(buf);
}
sizeobj->value((int)fltk::getsize()-1); //pickedsize
textobj->size = (int)fltk::getsize();
// fl_font(f, pickedsize); lets fix this...
} else if (s[0] == 0) {
// many sizes;
int j = 1;
for (int i = 1; i<MAXSIZE || i<s[n-1]; i++) {
char buf[20];
sprintf(buf,"%d",i);
fltk::Widget *w = sizeobj->add(buf);
if (j < n && i==s[j]) {
w->labelfont(w->labelfont()->bold());
w->labelcolor(fltk::RED);
j++;
}
//if (j < n && i==s[j]) {sprintf(buf,"@b;%d",i); j++;}
}
sizeobj->value(pickedsize-1);
textobj->size = pickedsize;
} else {
// some sizes -- when is this used?
int w = 0;
for (int i = 0; i < n; i++) {
if (s[i]<=pickedsize) w = i;
char buf[20];
sprintf(buf,"%d",s[i]);
fltk::Widget *w = sizeobj->add(buf);
w->labelfont(w->labelfont()->bold());
//sprintf(buf,"@b;%d",s[i]);
}
sizeobj->value(w);
textobj->size = s[w];
}
encobj->redraw();
sizeobj->redraw();
textobj->redraw();
// encobj->relayout();
// sizeobj->relayout();
// textobj->relayout();
// id_box->label(textobj->font->system_name());
// id_box->redraw();
button_group->redraw(); // needed?
}
void encoding_cb(fltk::Widget *, long) {
if (encobj->children() < 2) return; // XFT
int i = encobj->value();
// textobj->encoding = encobj->text(i);
textobj->encoding = encobj->child(i)->label();
textobj->redraw();
id_box->redraw();
}
void size_cb(fltk::Widget *, long) {
int i = sizeobj->value();
//const char *c = sizeobj->text(i);
const char *c = sizeobj->child(i)->label();
while (*c < '0' || *c > '9') c++;
textobj->size = atoi(c);
textobj->redraw();
// id_box->redraw();
}
void return_cb(fltk::Widget *, long ret) {
return_value = ret;
form->hide();
}
// TODO: rewrite this in fluid...
void create_the_forms()
{
if(form) return;
form = new fltk::Window(550, 420, _("Select font..."));
form->set_double_buffer();
form->begin();
textobj = new FontDisplay(fltk::ENGRAVED_BOX,10,10,530,160);
textobj->clear_flag(fltk::ALIGN_MASK);
textobj->set_flag(fltk::ALIGN_TOP|fltk::ALIGN_LEFT|fltk::ALIGN_INSIDE|fltk::ALIGN_CLIP);
id_box = new fltk::Widget(10, 172, 530, 15);
id_box->box(fltk::ENGRAVED_BOX);
id_box->labelsize(10);
id_box->set_flag(fltk::ALIGN_INSIDE|fltk::ALIGN_CLIP);
button_group = new fltk::Group(10, 190, 140, 20);
button_group->begin();
bold_button = new fltk::CheckButton(0, 0, 70, 20, "Bold");
bold_button->labelfont(bold_button->labelfont()->bold());
bold_button->callback(font_cb, 1);
italic_button = new fltk::CheckButton(70, 0, 70, 20, "Italic");
italic_button->labelfont(italic_button->labelfont()->italic());
italic_button->callback(font_cb, 1);
button_group->end();
fontobj = new fltk::Browser(10, 210, 280, 170);
fontobj->when(fltk::WHEN_CHANGED);
fontobj->callback(font_cb);
form->resizable(fontobj);
encobj = new fltk::Browser(300, 210, 100, 170);
encobj->when(fltk::WHEN_CHANGED);
encobj->callback(encoding_cb, 1);
sizeobj = new fltk::Browser(410, 210, 130, 170);
sizeobj->when(fltk::WHEN_CHANGED);
sizeobj->callback(size_cb);
ok_button = new fltk::Button(380, 390, 80, 25, _("&OK"));
ok_button->callback(return_cb, 1);
cancel_button = new fltk::Button(465, 390, 80, 25, _("&Cancel"));
cancel_button->callback(return_cb, 0);
form->end();
}
// search for largest <= selected size:
int find_best_size(fltk::Font* font, int selected)
{
int *allsizes;
int numsizes = font->sizes(allsizes);
// This is a bug in efltk
if (numsizes <= 1) return selected;
for (int i=1; i<numsizes; i++) {
if (allsizes[i] > selected)
return allsizes[i-1];
}
return allsizes[numsizes-1];
}
EDEFont font_chooser(EDEFont current_font)
{
EDEFont return_font;
create_the_forms();
if(!numfonts) numfonts = fltk::list_fonts(all_fonts);
// populate list of fonts
fontobj->clear();
for(int i = 0; i < numfonts; i++) {
fontobj->add(all_fonts[i]->name());
if (current_font.font && (strcasecmp(current_font.font->name(),all_fonts[i]->name())==0))
// it's a substring
fontobj->value(i);
}
/*char* currentname = strdup(current_font.font->name());
fsor(int i = 0; i < numfonts; i++) {
char* fontname = strdup(all_fonts[i]->name());
fontobj->add(fontname);
if (currentname.lower_case().pos(fontname.lower_case())==0) // it's a substring
fontobj->value(i);
}*/
// set bold, italic
/*if (currentname.pos(" bold italic") == currentname.length()-12) {
bold_button->value(true);
italic_button->value(true);
} else if (currentname.pos(" italic") == currentname.length()-7) {
italic_button->value(true);
} else if (currentname.pos(" bold") == currentname.length()-5) {
bold_button->value(true);
}*/
// populate other lists
textobj->encoding = current_font.encoding; // TODO: what if we're using XFT?
font_cb(fontobj,0);
for (int i=0; i < sizeobj->children(); i++) {
if (atoi(sizeobj->child(i)->label()) == current_font.size) {
sizeobj->value(i);
size_cb(sizeobj,0);
}
}
//
form->show();
form->exec();
// we have to construct a proper EDEFont to return
return_font.defined = false;
if (return_value)
{
return_font.font = fltk::font(fontobj->child(fontobj->value())->label()); //Style.h
if (bold_button->value()) return_font.font = return_font.font->bold();
if (italic_button->value()) return_font.font = return_font.font->italic();
int size = atoi(sizeobj->child(sizeobj->value())->label());
return_font.size = find_best_size(return_font.font, size);
// on XFT encoding is always Unicode, so this field can be blank
if (encobj->children() > 1)
return_font.encoding = strdup(encobj->child(encobj->value())->label());
else
return_font.encoding = 0;
return_font.defined = true;
}
return return_font;
}
//
// End of "$Id$".
//