Author: matt
Date: 2010-04-07 16:17:33 -0700 (Wed, 07 Apr 2010)
New Revision: 7469
Log:
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.

Modified:
   branches/branch-1.3/CHANGES
   branches/branch-1.3/FL/Enumerations.H
   branches/branch-1.3/FL/Fl_Widget.H
   branches/branch-1.3/src/Fl_Group.cxx
   branches/branch-1.3/src/fl_boxtype.cxx
   branches/branch-1.3/src/fl_draw.cxx
   branches/branch-1.3/test/label.cxx

Modified: branches/branch-1.3/CHANGES
===================================================================
--- branches/branch-1.3/CHANGES 2010-04-07 22:35:48 UTC (rev 7468)
+++ branches/branch-1.3/CHANGES 2010-04-07 23:17:33 UTC (rev 7469)
@@ -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)

Modified: branches/branch-1.3/FL/Enumerations.H
===================================================================
--- branches/branch-1.3/FL/Enumerations.H       2010-04-07 22:35:48 UTC (rev 
7468)
+++ branches/branch-1.3/FL/Enumerations.H       2010-04-07 23:17:33 UTC (rev 
7469)
@@ -618,6 +618,27 @@
  *  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_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.

Modified: branches/branch-1.3/FL/Fl_Widget.H
===================================================================
--- branches/branch-1.3/FL/Fl_Widget.H  2010-04-07 22:35:48 UTC (rev 7468)
+++ branches/branch-1.3/FL/Fl_Widget.H  2010-04-07 23:17:33 UTC (rev 7469)
@@ -170,6 +170,7 @@
   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 @@
       \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 @@
       \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.

Modified: branches/branch-1.3/src/Fl_Group.cxx
===================================================================
--- branches/branch-1.3/src/Fl_Group.cxx        2010-04-07 22:35:48 UTC (rev 
7468)
+++ branches/branch-1.3/src/Fl_Group.cxx        2010-04-07 23:17:33 UTC (rev 
7469)
@@ -745,7 +745,23 @@
   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;

Modified: branches/branch-1.3/src/fl_boxtype.cxx
===================================================================
--- branches/branch-1.3/src/fl_boxtype.cxx      2010-04-07 22:35:48 UTC (rev 
7468)
+++ branches/branch-1.3/src/fl_boxtype.cxx      2010-04-07 23:17:33 UTC (rev 
7469)
@@ -399,15 +399,20 @@
 //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 {
   draw_box(t, x_, y_, w_, h_, c);

Modified: branches/branch-1.3/src/fl_draw.cxx
===================================================================
--- branches/branch-1.3/src/fl_draw.cxx 2010-04-07 22:35:48 UTC (rev 7468)
+++ branches/branch-1.3/src/fl_draw.cxx 2010-04-07 23:17:33 UTC (rev 7469)
@@ -186,7 +186,8 @@
     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 @@
   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 @@
   }
 
   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 @@
   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 @@
     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 @@
 
       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 @@
   }
 
   // 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];

Modified: branches/branch-1.3/test/label.cxx
===================================================================
--- branches/branch-1.3/test/label.cxx  2010-04-07 22:35:48 UTC (rev 7468)
+++ branches/branch-1.3/test/label.cxx  2010-04-07 23:17:33 UTC (rev 7469)
@@ -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 @@
   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 @@
   {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 @@
   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 @@
   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());

_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit

Reply via email to