summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES1
-rw-r--r--FL/Enumerations.H36
-rw-r--r--FL/Fl_Widget.H3
-rw-r--r--src/Fl_Group.cxx18
-rw-r--r--src/fl_boxtype.cxx21
-rw-r--r--src/fl_draw.cxx59
-rw-r--r--test/label.cxx30
7 files changed, 139 insertions, 29 deletions
diff --git a/CHANGES b/CHANGES
index 9eafd32bc..cc402681f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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)
diff --git a/FL/Enumerations.H b/FL/Enumerations.H
index e3e53eb36..b2e5aa367 100644
--- a/FL/Enumerations.H
+++ b/FL/Enumerations.H
@@ -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.
diff --git a/FL/Fl_Widget.H b/FL/Fl_Widget.H
index a3a2d6ad6..3e61c7534 100644
--- a/FL/Fl_Widget.H
+++ b/FL/Fl_Widget.H
@@ -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.
diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx
index a5ca1739b..8f02fcf46 100644
--- a/src/Fl_Group.cxx
+++ b/src/Fl_Group.cxx
@@ -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;
diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx
index f4ae05941..c8a824e5c 100644
--- a/src/fl_boxtype.cxx
+++ b/src/fl_boxtype.cxx
@@ -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 {
diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx
index d435bf82b..27f50afad 100644
--- a/src/fl_draw.cxx
+++ b/src/fl_draw.cxx
@@ -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;
@@ -222,29 +226,36 @@ void fl_draw(
}
symtotal = symwidth[0] + symwidth[1];
+
+ int strw = 0;
+ int strh;
if (str) {
- for (p = str, lines=0; p;) {
+ for (p = str, lines=0; p;) {
e = fl_expand_text(p, buf, MAXBUF, w - symtotal, buflen, width,
- align&FL_ALIGN_WRAP, draw_symbols);
- lines++;
- if (!*e || (*e == '@' && e[1] != '@' && draw_symbols)) break;
- p = e;
- }
+ align&FL_ALIGN_WRAP, draw_symbols);
+ if (strw<width) strw = width;
+ lines++;
+ if (!*e || (*e == '@' && e[1] != '@' && draw_symbols)) break;
+ p = e;
+ }
} else lines = 0;
-
+
if ((symwidth[0] || symwidth[1]) && lines) {
if (symwidth[0]) symwidth[0] = lines * fl_height();
if (symwidth[1]) symwidth[1] = lines * fl_height();
}
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];
diff --git a/test/label.cxx b/test/label.cxx
index 35927552f..2d5fee5cb 100644
--- a/test/label.cxx
+++ b/test/label.cxx
@@ -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());