diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2005-02-26 20:27:19 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2005-02-26 20:27:19 +0000 |
| commit | 5b49a9ae51218ae045043725fd6484dcc828935f (patch) | |
| tree | 7d541bdaf2e1be17642c340228dd84c14cb4e8bb | |
| parent | 3145a0d0107e9b0808aa7cc8fbdff0dba66bab3c (diff) | |
Added visual gudelines for widget distances and sizes to fluid. It is disabled by default, but can be enabled in the "Grid" dialog box. I am not sure if this is actually a good change, but thanks to SVN I'll risk a commit to get some feedback fro the early adopters.
Fluid now indicates a "good" (according to some Apple guidelines, but that's not permanent y any means) distance of widgets to the window border, indicates vertical and horizontal alignment with other widgets, shows "good" sizes for buttons, and indicates a good distance between two buttons at the same y-position.
Achtung, Baby: I wrote this on a WIndows machine, hoping that SVN will replce CR/LF with LF's, as promised by the documentation. Unix users: please check and blame me!
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.1@4057 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
| -rw-r--r-- | fluid/Fl_Window_Type.cxx | 137 | ||||
| -rw-r--r-- | fluid/alignment_panel.cxx | 59 | ||||
| -rw-r--r-- | fluid/alignment_panel.fl | 26 | ||||
| -rw-r--r-- | fluid/alignment_panel.h | 24 | ||||
| -rw-r--r-- | fluid/fluid.cxx | 14 |
5 files changed, 204 insertions, 56 deletions
diff --git a/fluid/Fl_Window_Type.cxx b/fluid/Fl_Window_Type.cxx index 3a9a114d6..7bfa5e1c8 100644 --- a/fluid/Fl_Window_Type.cxx +++ b/fluid/Fl_Window_Type.cxx @@ -38,9 +38,12 @@ #include "alignment_panel.h" #include <stdio.h> +#define DRAW_GUIDES + extern int gridx; extern int gridy; extern int snap; +extern int show_guides; int include_H_from_C = 1; extern int i18n_type; @@ -64,6 +67,18 @@ static void update_xywh() { } } +void guides_cb(Fl_Check_Button *i, long) { + show_guides = i->value(); + fluid_prefs.set("show_guides", show_guides); + + for (Fl_Type *p = Fl_Type::first; p; p = p->next) { + if (p->is_window()) { + Fl_Window_Type *w = (Fl_Window_Type *)p; + ((Fl_Overlay_Window *)(w->o))->redraw_overlay(); + } + } +} + void grid_cb(Fl_Input *i, long v) { int n = atoi(i->value()); if (n < 0) n = 0; @@ -187,6 +202,7 @@ void show_grid_cb(Fl_Widget *, void *) { sprintf(buf,"%d",gridx); horizontal_input->value(buf); sprintf(buf,"%d",gridy); vertical_input->value(buf); sprintf(buf,"%d",snap); snap_input->value(buf); + guides_toggle->value(show_guides); grid_window->hotspot(grid_window); grid_window->show(); } @@ -463,6 +479,81 @@ void Fl_Window_Type::newposition(Fl_Widget_Type *myo,int &X,int &Y,int &R,int &T if (T<Y) {int n = Y; Y = T; T = n;} } +// draw a vertical arrow pointing toward y2 +static void draw_v_arrow(int x, int y1, int y2) { + int dy = (y1>y2) ? -1 : 1 ; + fl_yxline(x, y1, y2); + fl_xyline(x-4, y2, x+4); + fl_line(x-2, y2-dy*5, x, y2-dy); + fl_line(x+2, y2-dy*5, x, y2-dy); + char buf[16]; + sprintf(buf, "%d", dy*(y2-y1)); + fl_font(FL_HELVETICA, 9); + fl_draw(buf, x+3, y1+0.5*(y2-y1)+3); +} + +static void draw_h_arrow(int x1, int y, int x2) { + int dx = (x1>x2) ? -1 : 1 ; + fl_xyline(x1, y, x2); + fl_yxline(x2, y-4, y+4); + fl_line(x2-dx*5, y-2, x2-dx, y); + fl_line(x2-dx*5, y+2, x2-dx, y); + char buf[16]; + sprintf(buf, "%d", dx*(x2-x1)); + fl_font(FL_HELVETICA, 9); + fl_draw(buf, x1+0.5*(x2-x1)-6, y+9); +} + +static void draw_top_brace(const Fl_Widget *w) { + fl_yxline(w->x(), w->y()-2, w->y()+6); + fl_yxline(w->x()+w->w()-1, w->y()-2, w->y()+6); + fl_xyline(w->x()-2, w->y(), w->x()+w->w()+1); +} + +static void draw_left_brace(const Fl_Widget *w) { + fl_xyline(w->x()-2, w->y(), w->x()+6); + fl_xyline(w->x()-2, w->y()+w->h()-1, w->x()+6); + fl_yxline(w->x(), w->y()-2, w->y()+w->h()+1); +} + +static void draw_right_brace(const Fl_Widget *w) { + int xx = w->x() + w->w() - 1; + fl_xyline(xx-6, w->y(), xx+2); + fl_xyline(xx-6, w->y()+w->h()-1, xx+2); + fl_yxline(xx, w->y()-2, w->y()+w->h()+1); +} + +static void draw_bottom_brace(const Fl_Widget *w) { + int yy = w->y() + w->h() - 1; + fl_yxline(w->x(), yy-6, yy+2); + fl_yxline(w->x()+w->w()-1, yy-6, yy+2); + fl_xyline(w->x()-2, yy, w->x()+w->w()+1); +} + +static void draw_height(int x, int y, int b) { + b--; + fl_yxline(x, y, y+8); + fl_yxline(x, b-8, b); + fl_line(x-2, y+5, x, y+1, x+2, y+5); + fl_line(x-2, b-5, x, b-1, x+2, b-5); + char buf[16]; + sprintf(buf, "%d", b-y+1); + fl_font(FL_HELVETICA, 9); + fl_draw(buf, x+3, b-3); +} + +static void draw_width(int x, int y, int r) { + r--; + fl_xyline(x, y, x+8); + fl_xyline(r-8, y, r); + fl_line(x+5, y-2, x+1, y, x+5, y+2); + fl_line(r-5, y-2, r-1, y, r-5, y+2); + char buf[16]; + sprintf(buf, "%d", r-x+1); + fl_font(FL_HELVETICA, 9); + fl_draw(buf, r-5-fl_width(buf), y-1); +} + void Fl_Window_Type::draw_overlay() { if (recalc) { bx = o->w(); by = o->h(); br = 0; bt = 0; @@ -489,8 +580,10 @@ void Fl_Window_Type::draw_overlay() { if (!numselected) return; int mybx,myby,mybr,mybt; mybx = o->w(); myby = o->h(); mybr = 0; mybt = 0; + Fl_Type *selection = 0L; // used to store the one selcted widget (if n==1) for (Fl_Type *q=next; q && q->level>level; q = q->next) if (q->selected && q->is_widget() && !q->is_menu_item()) { + selection = q; Fl_Widget_Type* myo = (Fl_Widget_Type*)q; int x,y,r,t; newposition(myo,x,y,r,t); @@ -506,6 +599,50 @@ void Fl_Window_Type::draw_overlay() { fl_rectf(mybr-5,myby,5,5); fl_rectf(mybr-5,mybt-5,5,5); fl_rectf(mybx,mybt-5,5,5); + + if (show_guides) { + // draw overlays for UI Guideline distances + // - check for distance to the window edge + // * Apple suggest 14 pixels from the top + if (myby==14) draw_v_arrow(mybx+5, myby, 0); + // * Apple suggest 20 pixels from the top + if (o->h()-mybt-1==20) draw_v_arrow(mybx+5, mybt, o->h()-1); + // * Apple suggest 20 pixels from the left + if (mybx==20) draw_h_arrow(mybx, myby+5, 0); + // * Apple suggest 20 pixels from the right + if (o->w()-mybr-1==20) draw_h_arrow(mybr, myby+5, o->w()-1); + // - the following measuremetnt only apply to single selections + if (numselected==1 && selection) { + // check for Apple prefered button sizes + if (selection->is_button()) { + int h = mybt-myby; + if (h==20 || h==17 || h==15) draw_height(mybx+10, myby, mybt); + int w = mybr-mybx; + if (w==68) draw_width(mybx, myby+10, mybr); + } + // - check distances between individual widgets + for (Fl_Type *q=next; q && q->level>level; q = q->next) + if (q != selection) { + Fl_Widget_Type *qw = (Fl_Widget_Type*)q; + // - check horizontal and vertical alignment with other widgets + if (myby == qw->o->y()) draw_top_brace(qw->o); + if (mybx == qw->o->x()) draw_left_brace(qw->o); + if (mybr == qw->o->x()+qw->o->w()) draw_right_brace(qw->o); + if (mybt == qw->o->y()+qw->o->h()) draw_bottom_brace(qw->o); + if (selection->is_button()) { + // - check distances between buttons + if (q->is_button() && qw->o->y()==myby) { + // * horizontal button to button is 12 or 24 pixels + int dx = mybx - (qw->o->x()+qw->o->w()); + if (dx==12 || dx==24) draw_h_arrow(mybx-1, myby+10, mybx-dx-1); + dx = qw->o->x() - mybr; + if (dx==12 || dx==24) draw_h_arrow(mybr, myby+10, mybr+dx); + } + } + } + } + // \todo add more cases, maybe an interpreter? + } } // Calculate new bounding box of selected widgets: diff --git a/fluid/alignment_panel.cxx b/fluid/alignment_panel.cxx index c7d6c6a7c..1b7a24d42 100644 --- a/fluid/alignment_panel.cxx +++ b/fluid/alignment_panel.cxx @@ -1,8 +1,8 @@ -// generated by Fast Light User Interface Designer (fluid) version 1.0104 +// generated by Fast Light User Interface Designer (fluid) version 1.0107 #include "alignment_panel.h" -Fl_Window *project_window=(Fl_Window *)0; +Fl_Double_Window *project_window=(Fl_Double_Window *)0; static void cb_Close(Fl_Button*, void*) { project_window->hide(); @@ -17,10 +17,10 @@ Fl_Light_Button *include_H_from_C_button=(Fl_Light_Button *)0; Fl_Choice *i18n_type_chooser=(Fl_Choice *)0; Fl_Menu_Item menu_i18n_type_chooser[] = { - {"None", 0, 0, 0, 0, 0, 0, 14, 56}, - {"GNU gettext", 0, 0, 0, 0, 0, 0, 14, 56}, - {"POSIX catgets", 0, 0, 0, 0, 0, 0, 14, 56}, - {0} + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 56}, + {"GNU gettext", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 56}, + {"POSIX catgets", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 56}, + {0,0,0,0,0,0,0,0,0} }; Fl_Input *i18n_include_input=(Fl_Input *)0; @@ -31,9 +31,9 @@ Fl_Input *i18n_set_input=(Fl_Input *)0; Fl_Input *i18n_function_input=(Fl_Input *)0; -Fl_Window* make_project_window() { - Fl_Window* w; - { Fl_Window* o = project_window = new Fl_Window(365, 210, "Project Settings"); +Fl_Double_Window* make_project_window() { + Fl_Double_Window* w; + { Fl_Double_Window* o = project_window = new Fl_Double_Window(365, 210, "Project Settings"); w = o; { Fl_Button* o = new Fl_Button(295, 175, 60, 25, "Close"); o->tooltip("Close this dialog."); @@ -112,7 +112,7 @@ Fl_Window* make_project_window() { } Fl_Text_Buffer *shell_run_buffer; -Fl_Window *settings_window=(Fl_Window *)0; +Fl_Double_Window *settings_window=(Fl_Double_Window *)0; static void cb_Close1(Fl_Button*, void*) { settings_window->hide(); @@ -143,9 +143,9 @@ static void cb_prevpos_button(Fl_Check_Button*, void*) { fluid_prefs.set("prev_window_pos", prevpos_button->value()); } -Fl_Window* make_settings_window() { - Fl_Window* w; - { Fl_Window* o = settings_window = new Fl_Window(255, 210, "GUI Settings"); +Fl_Double_Window* make_settings_window() { + Fl_Double_Window* w; + { Fl_Double_Window* o = settings_window = new Fl_Double_Window(255, 210, "GUI Settings"); w = o; { Fl_Button* o = new Fl_Button(185, 179, 60, 25, "Close"); o->tooltip("Close this dialog."); @@ -192,7 +192,7 @@ Fl_Window* make_settings_window() { return w; } -Fl_Window *shell_window=(Fl_Window *)0; +Fl_Double_Window *shell_window=(Fl_Double_Window *)0; Fl_Input *shell_command_input=(Fl_Input *)0; @@ -222,7 +222,7 @@ static void cb_Cancel(Fl_Button*, void*) { shell_window->hide(); } -Fl_Window *shell_run_window=(Fl_Window *)0; +Fl_Double_Window *shell_run_window=(Fl_Double_Window *)0; Fl_Return_Button *shell_run_button=(Fl_Return_Button *)0; @@ -232,9 +232,9 @@ static void cb_shell_run_button(Fl_Return_Button*, void*) { Fl_Text_Display *shell_run_display=(Fl_Text_Display *)0; -Fl_Window* make_shell_window() { - Fl_Window* w; - { Fl_Window* o = shell_window = new Fl_Window(450, 145, "Shell Command"); +Fl_Double_Window* make_shell_window() { + Fl_Double_Window* w; + { Fl_Double_Window* o = shell_window = new Fl_Double_Window(450, 145, "Shell Command"); w = o; { Fl_Tabs* o = new Fl_Tabs(10, 10, 430, 90); { Fl_Group* o = new Fl_Group(10, 30, 430, 70, "Shell Command"); @@ -278,7 +278,7 @@ Fl_Window* make_shell_window() { } o->end(); } - { Fl_Window* o = shell_run_window = new Fl_Window(555, 435, "Shell Command Output"); + { Fl_Double_Window* o = shell_run_window = new Fl_Double_Window(555, 435, "Shell Command Output"); w = o; { Fl_Return_Button* o = shell_run_button = new Fl_Return_Button(465, 400, 80, 25, "Close"); o->callback((Fl_Callback*)cb_shell_run_button); @@ -295,7 +295,7 @@ Fl_Window* make_shell_window() { return w; } -Fl_Window *grid_window=(Fl_Window *)0; +Fl_Double_Window *grid_window=(Fl_Double_Window *)0; Fl_Input *horizontal_input=(Fl_Input *)0; @@ -303,17 +303,19 @@ Fl_Input *vertical_input=(Fl_Input *)0; Fl_Input *snap_input=(Fl_Input *)0; +Fl_Check_Button *guides_toggle=(Fl_Check_Button *)0; + static void cb_Close2(Fl_Button*, void*) { grid_window->hide(); } -Fl_Window* make_grid_window() { - Fl_Window* w; - { Fl_Window* o = grid_window = new Fl_Window(155, 175, "Grid"); +Fl_Double_Window* make_grid_window() { + Fl_Double_Window* w; + { Fl_Double_Window* o = grid_window = new Fl_Double_Window(155, 208, "Grid"); w = o; - { Fl_Tabs* o = new Fl_Tabs(10, 10, 135, 120); + { Fl_Tabs* o = new Fl_Tabs(10, 10, 135, 150); o->align(FL_ALIGN_TOP_LEFT); - { Fl_Group* o = new Fl_Group(10, 30, 135, 100, "Grid"); + { Fl_Group* o = new Fl_Group(10, 30, 135, 130, "Grid"); o->align(FL_ALIGN_TOP_LEFT); { Fl_Input* o = horizontal_input = new Fl_Input(95, 40, 40, 20, "Horizontal:"); o->tooltip("Horizontal grid spacing."); @@ -336,11 +338,16 @@ Fl_Window* make_grid_window() { o->callback((Fl_Callback*)grid_cb, (void*)(3)); o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY); } + { Fl_Check_Button* o = guides_toggle = new Fl_Check_Button(30, 125, 105, 25, "Show Guides"); + o->tooltip("Show distance and alignment guides in overlay"); + o->down_box(FL_DOWN_BOX); + o->callback((Fl_Callback*)guides_cb, (void*)(4)); + } o->end(); } o->end(); } - { Fl_Button* o = new Fl_Button(85, 140, 60, 25, "Close"); + { Fl_Button* o = new Fl_Button(85, 170, 60, 25, "Close"); o->tooltip("Close this dialog."); o->callback((Fl_Callback*)cb_Close2); } diff --git a/fluid/alignment_panel.fl b/fluid/alignment_panel.fl index 31e6bc9f1..e991c8bc5 100644 --- a/fluid/alignment_panel.fl +++ b/fluid/alignment_panel.fl @@ -1,5 +1,5 @@ # data file for the Fltk User Interface Designer (fluid) -version 1.0103 +version 1.0107 header_name {.h} code_name {.cxx} decl {\#include <FL/Fl_Text_Buffer.H>} {public @@ -12,7 +12,7 @@ Function {make_project_window()} {open } { Fl_Window project_window { label {Project Settings} open - xywh {469 112 365 210} + xywh {217 589 365 210} type Double code0 {\#include <FL/Fl_Preferences.H>} code1 {\#include <FL/Fl_Tooltip.H>} modal visible } { @@ -103,14 +103,14 @@ decl {extern void i18n_cb(Fl_Choice *,void *);} {public decl {extern Fl_Preferences fluid_prefs;} {public } -decl {Fl_Text_Buffer *shell_run_buffer;} {selected public +decl {Fl_Text_Buffer *shell_run_buffer;} {public } Function {make_settings_window()} {open } { Fl_Window settings_window { label {GUI Settings} open - xywh {340 243 255 210} visible + xywh {321 150 255 210} type Double visible } { Fl_Button {} { label Close @@ -167,7 +167,7 @@ Function {make_shell_window()} {open } { Fl_Window shell_window { label {Shell Command} open - xywh {630 219 450 145} visible + xywh {588 153 450 145} type Double visible } { Fl_Tabs {} {open xywh {10 10 430 90} @@ -222,7 +222,7 @@ Function {make_shell_window()} {open } Fl_Window shell_run_window { label {Shell Command Output} open - xywh {693 386 555 435} resizable visible + xywh {592 332 555 435} type Double resizable visible } { Fl_Return_Button shell_run_button { label Close @@ -241,14 +241,14 @@ Function {make_grid_window()} {open } { Fl_Window grid_window { label Grid open - xywh {1120 236 155 175} visible + xywh {51 589 155 208} type Double visible } { Fl_Tabs {} { - xywh {10 10 135 120} align 5 + xywh {10 10 135 150} align 5 } { Fl_Group {} { label Grid - xywh {10 30 135 100} align 5 + xywh {10 30 135 130} align 5 } { Fl_Input horizontal_input { label {Horizontal:} @@ -271,12 +271,18 @@ Function {make_grid_window()} {open tooltip {Snap to grid within this many pixels.} xywh {95 100 40 20} type Int box THIN_DOWN_BOX code0 {o->when(FL_WHEN_RELEASE|FL_WHEN_ENTER_KEY);} } + Fl_Check_Button guides_toggle { + label {Show Guides} + user_data 4 user_data_type long + callback guides_cb selected + tooltip {Show distance and alignment guides in overlay} xywh {30 125 105 25} down_box DOWN_BOX + } } } Fl_Button {} { label Close callback {grid_window->hide();} - tooltip {Close this dialog.} xywh {85 140 60 25} + tooltip {Close this dialog.} xywh {85 170 60 25} } } } diff --git a/fluid/alignment_panel.h b/fluid/alignment_panel.h index 92794bf9c..87d51339b 100644 --- a/fluid/alignment_panel.h +++ b/fluid/alignment_panel.h @@ -1,14 +1,14 @@ -// generated by Fast Light User Interface Designer (fluid) version 1.0104 +// generated by Fast Light User Interface Designer (fluid) version 1.0107 #ifndef alignment_panel_h #define alignment_panel_h #include <FL/Fl.H> #include <FL/Fl_Text_Buffer.H> #include <FL/Fl_Text_Display.H> -#include <FL/Fl_Window.H> +#include <FL/Fl_Double_Window.H> #include <FL/Fl_Preferences.H> #include <FL/Fl_Tooltip.H> -extern Fl_Window *project_window; +extern Fl_Double_Window *project_window; #include <FL/Fl_Button.H> #include <FL/Fl_Tabs.H> #include <FL/Fl_Group.H> @@ -29,34 +29,36 @@ extern Fl_Input *i18n_include_input; extern Fl_Input *i18n_file_input; extern Fl_Input *i18n_set_input; extern Fl_Input *i18n_function_input; -Fl_Window* make_project_window(); +Fl_Double_Window* make_project_window(); extern Fl_Menu_Item menu_i18n_type_chooser[]; extern void i18n_cb(Fl_Choice *,void *); extern Fl_Preferences fluid_prefs; extern Fl_Text_Buffer *shell_run_buffer; -extern Fl_Window *settings_window; +extern Fl_Double_Window *settings_window; #include <FL/Fl_Check_Button.H> extern Fl_Check_Button *tooltips_button; extern Fl_Check_Button *completion_button; extern Fl_Check_Button *openlast_button; extern Fl_Check_Button *prevpos_button; -Fl_Window* make_settings_window(); -extern Fl_Window *shell_window; +Fl_Double_Window* make_settings_window(); +extern Fl_Double_Window *shell_window; extern Fl_Input *shell_command_input; extern Fl_Check_Button *shell_savefl_button; extern Fl_Check_Button *shell_writecode_button; extern Fl_Check_Button *shell_writemsgs_button; #include <FL/Fl_Return_Button.H> extern void do_shell_command(Fl_Return_Button*, void*); -extern Fl_Window *shell_run_window; +extern Fl_Double_Window *shell_run_window; extern Fl_Return_Button *shell_run_button; #include <FL/Fl_Text_Display.H> extern Fl_Text_Display *shell_run_display; -Fl_Window* make_shell_window(); -extern Fl_Window *grid_window; +Fl_Double_Window* make_shell_window(); +extern Fl_Double_Window *grid_window; extern void grid_cb(Fl_Input*, long); extern Fl_Input *horizontal_input; extern Fl_Input *vertical_input; extern Fl_Input *snap_input; -Fl_Window* make_grid_window(); +extern void guides_cb(Fl_Check_Button*, long); +extern Fl_Check_Button *guides_toggle; +Fl_Double_Window* make_grid_window(); #endif diff --git a/fluid/fluid.cxx b/fluid/fluid.cxx index 1eee53660..f2acf480c 100644 --- a/fluid/fluid.cxx +++ b/fluid/fluid.cxx @@ -65,6 +65,7 @@ Fl_Preferences fluid_prefs(Fl_Preferences::USER, "fltk.org", "fluid"); int gridx = 5; int gridy = 5; int snap = 1; +int show_guides = 1; // File history info... char absolute_history[10][1024]; @@ -558,16 +559,11 @@ Fl_Menu_Item Main_Menu[] = { extern void fill_in_New_Menu(); void make_main_window() { - int i; - fluid_prefs.get("snap", i, 1); - snap = i; - - fluid_prefs.get("gridx", i, 5); - gridx = i; - - fluid_prefs.get("gridy", i, 5); - gridy = i; + fluid_prefs.get("snap", snap, 1); + fluid_prefs.get("gridx", gridx, 5); + fluid_prefs.get("gridy", gridy, 5); + fluid_prefs.get("show_guides", show_guides, 0); load_history(); |
