#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "compat.h" #include "global.h" #include "data.h" #include "set.h" #include "mymem.h" #include "hid.h" #include "../hidint.h" #include "lesstif.h" /* There are three places where styles are kept: First, the "active" style is in Settings.LineThickness et al. Second, there are NUM_STYLES styles in PCB->RouteStyle[]. Third, there are NUM_STYLES styles in Settings.RouteStyle[] Selecting a style copies its values to the active style. We also need a way to modify the active style, copy the active style to PCB->RouteStyle[], and copy PCB->RouteStyle[] to Settings.RouteStyle[]. Since Lesstif reads the default style from .Xdefaults, we can ignore Settings.RouteStyle[] in general, as it's only used to initialize new PCB files. So, we need to do PCB->RouteStyle <-> active style. */ static Arg args[30]; static int n; #define stdarg(t,v) XtSetArg(args[n], t, v); n++ typedef enum { SSthick, SSdiam, SShole, SSkeep, SSNUM } StyleValues; static Widget style_dialog = 0; static Widget style_values[SSNUM]; static Widget style_pb[NUM_STYLES]; static Widget units_pb[NUM_STYLES]; static int name_hashes[NUM_STYLES]; static Widget value_form, value_labels, value_texts, units_form; static int local_update = 0; XmString xms_mm, xms_mil; static int use_mm = 0; #define USTR (use_mm ? xms_mm : xms_mil) static int hash(char *cp) { int h = 0; while (*cp) { h = h * 13 + *(unsigned char *)cp; h ^= (h>>16); cp++; } return h; } typedef struct { Widget w[NUM_STYLES]; } StyleButtons; static StyleButtons *style_button_list = 0; static int num_style_buttons = 0; static char *value_names[] = { "Thickness", "Diameter", "Hole", "Keepaway" }; static int value_max[] = { MAX_LINESIZE, MAX_PINORVIASIZE, MAX_PINORVIASIZE, MAX_LINESIZE }; static int RouteStylesChanged (int argc, char **argv, int x, int y); static void update_one_value(int i, int v) { char buf[100]; double d; if (use_mm) d = PCB_TO_MM (v); else d = PCB_TO_MIL (v); sprintf(buf, "%.2f", d); XmTextSetString(style_values[i], buf); n = 0; stdarg(XmNlabelString, USTR); XtSetValues(units_pb[i], args, n); } static void update_values() { local_update = 1; update_one_value(SSthick, Settings.LineThickness); update_one_value(SSdiam, Settings.ViaThickness); update_one_value(SShole, Settings.ViaDrillingHole); update_one_value(SSkeep, Settings.Keepaway); local_update = 0; lesstif_update_status_line (); } void lesstif_styles_update_values() { if (!style_dialog) return; use_mm = Settings.grid_units_mm; update_values(); } static void update_style_buttons() { int i = hid_get_flag("style"); int j, n; for (n=0; nRouteStyle[i].Name); free(PCB->RouteStyle[i].Name); PCB->RouteStyle[i].Name = newname; RouteStylesChanged(0, 0, 0, 0); } static void style_set_cb(Widget w, int i, XmToggleButtonCallbackStruct *cbs) { PCB->RouteStyle[i].Thick = Settings.LineThickness; PCB->RouteStyle[i].Diameter = Settings.ViaThickness; PCB->RouteStyle[i].Hole = Settings.ViaDrillingHole; PCB->RouteStyle[i].Keepaway = Settings.Keepaway; update_style_buttons(); } static void style_selected(Widget w, int i, XmToggleButtonCallbackStruct *cbs) { RouteStyleType *style; int j, n; if (cbs && cbs->set == 0) { XmToggleButtonSetState(w, 1, 0); return; } style = PCB->RouteStyle + i; SetLineSize(style->Thick); SetViaSize(style->Diameter, True); SetViaDrillingHole(style->Hole, True); SetKeepawayWidth(style->Keepaway); if (style_dialog) { for (j=0; jRouteStyle[i].Name)); stdarg(XmNindicatorType, XmONE_OF_MANY); stdarg(XmNalignment, XmALIGNMENT_BEGINNING); pb = XmCreateToggleButton(style_dialog, "style", args, n); XtManageChild(pb); XtAddCallback(pb, XmNvalueChangedCallback, (XtCallbackProc)style_selected, (XtPointer)i); return pb; } static int AdjustStyle(int argc, char **argv, int x, int y) { if (!mainwind) return 1; if (style_dialog == 0) { int i; xms_mm = XmStringCreateLocalized("mm"); xms_mil = XmStringCreateLocalized("mil"); n = 0; stdarg(XmNautoUnmanage, False); stdarg(XmNtitle, "Route Styles"); style_dialog = XmCreateFormDialog(mainwind, "style", args, n); n = 0; stdarg(XmNtopAttachment, XmATTACH_FORM); stdarg(XmNleftAttachment, XmATTACH_FORM); stdarg(XmNrightAttachment, XmATTACH_FORM); value_form = XmCreateForm(style_dialog, "values", args, n); XtManageChild(value_form); n = 0; stdarg(XmNtopAttachment, XmATTACH_FORM); stdarg(XmNrightAttachment, XmATTACH_FORM); stdarg(XmNbottomAttachment, XmATTACH_FORM); stdarg(XmNfractionBase, 4); stdarg(XmNresizePolicy, XmRESIZE_GROW); units_form = XmCreateForm(value_form, "units", args, n); XtManageChild(units_form); n = 0; stdarg(XmNtopAttachment, XmATTACH_FORM); stdarg(XmNbottomAttachment, XmATTACH_FORM); stdarg(XmNleftAttachment, XmATTACH_FORM); stdarg(XmNfractionBase, 4); value_labels = XmCreateForm(value_form, "values", args, n); XtManageChild(value_labels); n = 0; stdarg(XmNtopAttachment, XmATTACH_FORM); stdarg(XmNbottomAttachment, XmATTACH_FORM); stdarg(XmNrightAttachment, XmATTACH_WIDGET); stdarg(XmNrightWidget, units_form); stdarg(XmNleftAttachment, XmATTACH_WIDGET); stdarg(XmNleftWidget, value_labels); stdarg(XmNfractionBase, 4); value_texts = XmCreateForm(value_form, "values", args, n); XtManageChild(value_texts); for (i=0; iRouteStyle[i].Name); } for (i=0; iRouteStyle[0].Name) return 0; update_style_buttons(); if (!style_dialog) return; for (j=0; jRouteStyle[j].Name); if (name_hashes[j] == h) continue; name_hashes[j] = h; n = 0; stdarg(XmNlabelString, XmStringCreateLocalized(PCB->RouteStyle[j].Name)); if (style_dialog) XtSetValues(style_pb[j], args, n); for (i=0; iRouteStyle[i].Name)); Widget btn = XmCreateToggleButton(menu, "style", args, n); XtManageChild(btn); XtAddCallback(btn, XmNvalueChangedCallback, (XtCallbackProc)style_selected, (XtPointer)i); sb->w[i] = btn; } update_style_buttons(); } HID_Action lesstif_styles_action_list[] = { { "AdjustStyle", 0, 0, AdjustStyle }, { "RouteStylesChanged", 0, 0, RouteStylesChanged }, }; REGISTER_ACTIONS(lesstif_styles_action_list)