Added new flags for label alignment: FL_LEFT_TOP, FL_RIGHT_TOP, FL_LEFT_BOTTOM, and FL_RIGHT_BOTTOM align outside labels first to the side, then to the top or botton, filling a gap in possible alignment. Also FL_ALIGN_TEXT_NEXT_TO_IMAGE and FL_ALIGN_IMAGE_NEXT_TO_TEXT which do just that, and finally FL_ALIGN_IMAGE_BACKDROP which renders the image in the background and draws the label on top.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7469 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2010-04-07 23:17:33 +00:00
parent 0fe65e94c9
commit f899c3897d
7 changed files with 139 additions and 29 deletions

View File

@ -1,5 +1,6 @@
CHANGES IN FLTK 1.3.0
- Added new label and image alignments (STR #2269)
- Added documentation for event delivery (STR #1983)
- Fixed menu and tooltip window animation bug under X11 (compiz)
by setting an appropriate window type (STR #2082)

View File

@ -618,6 +618,27 @@ extern Fl_Labeltype FL_EXPORT fl_define_FL_EMBOSSED_LABEL();
* inside the widget.
*
* Flags can be or'd to achieve a combination of alignments.
*
* Outside alignments:
* \code
* TOP_LEFT TOP TOP_RIGHT
* LEFT_TOP+---------------------------------+RIGHT_TOP
* | |
* LEFT| |RIGHT
* | |
* LEFT_BOTTOM+---------------------------------+RIGHT_BOTTOM
* BOTTOM_RIGHT BOTTOM BOTTOM_LEFT
*
* Inside alignments:
* \code
* +---------------------------------+
* |TOP_LEFT TOP TOP_RIGHT|
* | |
* |LEFT RIGHT|
* | |
* |BOTTOM_RIGHT BOTTOM BOTTOM_LEFT|
* +---------------------------------+
* \endcode
* \see #FL_ALIGN_CENTER, etc.
*/
typedef unsigned Fl_Align;
@ -644,17 +665,24 @@ const Fl_Align FL_ALIGN_IMAGE_OVER_TEXT = (Fl_Align)0;
const Fl_Align FL_ALIGN_CLIP = (Fl_Align)64;
/** Wrap text that does not fit the width of the widget. */
const Fl_Align FL_ALIGN_WRAP = (Fl_Align)128;
/** If the label contains an image, draw the text to the left of the image. */
const Fl_Align FL_ALIGN_TEXT_NEXT_TO_IMAGE = (Fl_Align)0x0100;
/** If the label contains an image, draw the text to the right of the image. */
const Fl_Align FL_ALIGN_IMAGE_NEXT_TO_TEXT = (Fl_Align)0x0110;
/** If the label contains an image, draw the image or deimage in the backgroup. */
const Fl_Align FL_ALIGN_IMAGE_BACKDROP = (Fl_Align)0x0200;
const Fl_Align FL_ALIGN_TOP_LEFT = FL_ALIGN_TOP | FL_ALIGN_LEFT;
const Fl_Align FL_ALIGN_TOP_RIGHT = FL_ALIGN_TOP | FL_ALIGN_RIGHT;
const Fl_Align FL_ALIGN_BOTTOM_LEFT = FL_ALIGN_BOTTOM | FL_ALIGN_LEFT;
const Fl_Align FL_ALIGN_BOTTOM_RIGHT = FL_ALIGN_BOTTOM | FL_ALIGN_RIGHT;
const Fl_Align FL_ALIGN_LEFT_TOP = FL_ALIGN_TOP_LEFT;
const Fl_Align FL_ALIGN_RIGHT_TOP = FL_ALIGN_TOP_RIGHT;
const Fl_Align FL_ALIGN_LEFT_BOTTOM = FL_ALIGN_BOTTOM_LEFT;
const Fl_Align FL_ALIGN_RIGHT_BOTTOM = FL_ALIGN_BOTTOM_RIGHT;
const Fl_Align FL_ALIGN_LEFT_TOP = 0x0007; // magic value
const Fl_Align FL_ALIGN_RIGHT_TOP = 0x000b; // magic value
const Fl_Align FL_ALIGN_LEFT_BOTTOM = 0x000d; // magic value
const Fl_Align FL_ALIGN_RIGHT_BOTTOM = 0x000e; // magic value
const Fl_Align FL_ALIGN_NOWRAP = (Fl_Align)0; // for back compatability
/*@}*/
/** \name Font Numbers */
/*@{*/
/** A font number is an index into the internal font table.

View File

@ -170,6 +170,7 @@ protected:
void draw_box() const;
void draw_box(Fl_Boxtype t, Fl_Color c) const;
void draw_box(Fl_Boxtype t, int x,int y,int w,int h, Fl_Color c) const;
void draw_backdrop() const;
/** draws a focus rectangle around the widget */
void draw_focus() {draw_focus(box(),x(),y(),w(),h());}
void draw_focus(Fl_Boxtype t, int x,int y,int w,int h) const;
@ -497,6 +498,7 @@ public:
\return the current image
*/
Fl_Image* image() {return label_.image;}
const Fl_Image* image() const {return label_.image;}
/** Sets the image to use as part of the widget label.
This image is used when drawing the widget in the active state.
@ -515,6 +517,7 @@ public:
\return the current image for the deactivated widget
*/
Fl_Image* deimage() {return label_.deimage;}
const Fl_Image* deimage() const {return label_.deimage;}
/** Sets the image to use as part of the widget label.
This image is used when drawing the widget in the inactive state.

View File

@ -745,7 +745,23 @@ void Fl_Group::draw_outside_label(const Fl_Widget& widget) const {
int Y = widget.y();
int W = widget.w();
int H = widget.h();
if (a & FL_ALIGN_TOP) {
if ( (a & 0x0f) == FL_ALIGN_LEFT_TOP ) {
a = (a &~0x0f ) | FL_ALIGN_TOP_RIGHT;
X = x();
W = widget.x()-X-3;
} else if ( (a & 0x0f) == FL_ALIGN_LEFT_BOTTOM ) {
a = (a &~0x0f ) | FL_ALIGN_BOTTOM_RIGHT;
X = x();
W = widget.x()-X-3;
} else if ( (a & 0x0f) == FL_ALIGN_RIGHT_TOP ) {
a = (a &~0x0f ) | FL_ALIGN_TOP_LEFT;
X = X+W+3;
W = x()+this->w()-X;
} else if ( (a & 0x0f) == FL_ALIGN_RIGHT_BOTTOM ) {
a = (a &~0x0f ) | FL_ALIGN_BOTTOM_LEFT;
X = X+W+3;
W = x()+this->w()-X;
} else if (a & FL_ALIGN_TOP) {
a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
Y = y();
H = widget.y()-Y;

View File

@ -399,14 +399,19 @@ void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) {
//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx
/** Draws the widget box according its box style */
void Fl_Widget::draw_box() const {
int t = box_;
if (!t) return;
// if (this == fl_boxcheat) {
// fl_boxcheat = 0;
// if (t == FL_FLAT_BOX) return;
// t += 2; // convert box to frame
// }
draw_box((Fl_Boxtype)t, x_, y_, w_, h_, color_);
if (box_) draw_box((Fl_Boxtype)box_, x_, y_, w_, h_, color_);
draw_backdrop();
}
/** If FL_ALIGN_IMAGE_BACKDROP is set, the image or deimage will be drawn */
void Fl_Widget::draw_backdrop() const {
if (align() & FL_ALIGN_IMAGE_BACKDROP) {
const Fl_Image *img = image();
// if there is no image, we will not draw the deimage either
if (img && deimage() && !active_r())
img = deimage();
if (img)
((Fl_Image*)img)->draw(x_+(w_-img->w())/2, y_+(h_-img->h())/2);
}
}
/** Draws a box of type t, of color c at the widget's position and size. */
void Fl_Widget::draw_box(Fl_Boxtype t, Fl_Color c) const {

View File

@ -186,7 +186,8 @@ void fl_draw(
int x, int y, int w, int h, // bounding box
Fl_Align align,
void (*callthis)(const char*,int,int,int),
Fl_Image* img, int draw_symbols) {
Fl_Image* img, int draw_symbols)
{
const char* p;
const char* e;
char buf[MAXBUF];
@ -198,6 +199,9 @@ void fl_draw(
int lines;
double width;
// if the image is set as a backdrop, ignore it here
if (img && (align & FL_ALIGN_IMAGE_BACKDROP)) img = 0;
symbol[0][0] = '\0';
symwidth[0] = 0;
@ -223,10 +227,14 @@ void fl_draw(
symtotal = symwidth[0] + symwidth[1];
int strw = 0;
int strh;
if (str) {
for (p = str, lines=0; p;) {
e = fl_expand_text(p, buf, MAXBUF, w - symtotal, buflen, width,
align&FL_ALIGN_WRAP, draw_symbols);
if (strw<width) strw = width;
lines++;
if (!*e || (*e == '@' && e[1] != '@' && draw_symbols)) break;
p = e;
@ -239,12 +247,15 @@ void fl_draw(
}
symtotal = symwidth[0] + symwidth[1];
strh = lines * fl_height();
// figure out vertical position of the first line:
int xpos;
int ypos;
int height = fl_height();
int imgh = img ? img->h() : 0;
int imgvert = ((align&FL_ALIGN_TEXT_NEXT_TO_IMAGE)==0);
int imgh = img && imgvert ? img->h() : 0;
int imgw[2] = {0, 0};
symoffset = 0;
@ -253,7 +264,7 @@ void fl_draw(
else ypos = y+(h-lines*height-imgh)/2+height;
// draw the image unless the "text over image" alignment flag is set...
if (img && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) {
if (img && imgvert && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) {
if (img->w() > symoffset) symoffset = img->w();
if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0];
@ -264,6 +275,26 @@ void fl_draw(
ypos += img->h();
}
// draw the image to the side of the text
if (img && !imgvert /* && (align & !FL_ALIGN_TEXT_NEXT_TO_IMAGE)*/ ) {
if (align & FL_ALIGN_TEXT_OVER_IMAGE) { // image is right of text
imgw[1] = img->w();
if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] + strw + 1;
else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1] - imgw[1] + 1;
else xpos = x + (w - strw - symtotal - imgw[1]) / 2 + symwidth[0] + strw + 1;
} else { // image is to the left of the text
imgw[0] = img->w();
if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] - 1;
else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1] - strw - imgw[0] - 1;
else xpos = x + (w - strw - symtotal - imgw[0]) / 2 - 1;
}
int yimg = ypos - height;
if (align & FL_ALIGN_TOP) ;
else if (align & FL_ALIGN_BOTTOM) yimg += strh - img->h() - 1;
else yimg += (strh - img->h() - 1) / 2;
img->draw(xpos, yimg);
}
// now draw all the lines:
if (str) {
int desc = fl_descent();
@ -274,9 +305,9 @@ void fl_draw(
if (width > symoffset) symoffset = (int)(width + 0.5);
if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0];
else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1];
else xpos = x + (w - (int)(width + .5) - symtotal) / 2 + symwidth[0];
if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0] + imgw[0];
else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1] - imgw[1];
else xpos = x + (w - (int)(width + .5) - symtotal - imgw[0] - imgw[1]) / 2 + symwidth[0] + imgw[0];
callthis(buf,buflen,xpos,ypos-desc);
@ -289,7 +320,7 @@ void fl_draw(
}
// draw the image if the "text over image" alignment flag is set...
if (img && (align & FL_ALIGN_TEXT_OVER_IMAGE)) {
if (img && imgvert && (align & FL_ALIGN_TEXT_OVER_IMAGE)) {
if (img->w() > symoffset) symoffset = img->w();
if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0];

View File

@ -32,14 +32,19 @@
#include <FL/Fl_Toggle_Button.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Pixmap.H>
#include <FL/fl_draw.H>
#include "pixmaps/blast.xpm"
Fl_Toggle_Button *imageb, *imageovertextb, *imagenexttotextb, *imagebackdropb;
Fl_Toggle_Button *leftb,*rightb,*topb,*bottomb,*insideb,*clipb,*wrapb;
Fl_Box *text;
Fl_Input *input;
Fl_Hor_Value_Slider *fonts;
Fl_Hor_Value_Slider *sizes;
Fl_Double_Window *window;
Fl_Pixmap *img;
void button_cb(Fl_Widget *,void *) {
int i = 0;
@ -50,10 +55,21 @@ void button_cb(Fl_Widget *,void *) {
if (insideb->value()) i |= FL_ALIGN_INSIDE;
if (clipb->value()) i |= FL_ALIGN_CLIP;
if (wrapb->value()) i |= FL_ALIGN_WRAP;
if (imageovertextb->value()) i |= FL_ALIGN_TEXT_OVER_IMAGE;
if (imagenexttotextb->value()) i |= FL_ALIGN_TEXT_NEXT_TO_IMAGE;
if (imagebackdropb->value()) i |= FL_ALIGN_IMAGE_BACKDROP;
text->align(i);
window->redraw();
}
void image_cb(Fl_Widget *,void *) {
if (imageb->value())
text->image(img);
else
text->image(0);
window->redraw();
}
void font_cb(Fl_Widget *,void *) {
text->labelfont(int(fonts->value()));
window->redraw();
@ -107,6 +123,8 @@ Fl_Menu_Item choices[] = {
{0}};
int main(int argc, char **argv) {
img = new Fl_Pixmap(blast_xpm);
window = new Fl_Double_Window(400,400);
input = new Fl_Input(50,375,350,25);
@ -128,7 +146,15 @@ int main(int argc, char **argv) {
fonts->value(0);
fonts->callback(font_cb);
Fl_Group *g = new Fl_Group(50,300,350,25);
Fl_Group *g = new Fl_Group(50,275,350,50);
imageb = new Fl_Toggle_Button(50,275,50,25,"image");
imageb->callback(image_cb);
imageovertextb = new Fl_Toggle_Button(100,275,50,25,"I - T");
imageovertextb->callback(button_cb);
imagenexttotextb = new Fl_Toggle_Button(150,275,50,25,"I | T");
imagenexttotextb->callback(button_cb);
imagebackdropb = new Fl_Toggle_Button(200,275,50,25,"back");
imagebackdropb->callback(button_cb);
leftb = new Fl_Toggle_Button(50,300,50,25,"left");
leftb->callback(button_cb);
rightb = new Fl_Toggle_Button(100,300,50,25,"right");
@ -146,7 +172,7 @@ int main(int argc, char **argv) {
g->resizable(insideb);
g->end();
Fl_Choice *c = new Fl_Choice(50,275,200,25);
Fl_Choice *c = new Fl_Choice(50,250,200,25);
c->menu(choices);
text= new Fl_Box(FL_FRAME_BOX,100,75,200,100,input->value());