home *** CD-ROM | disk | FTP | other *** search
- // $Id: toolbar.C,v 1.21 1998/11/11 10:29:32 zeller Exp $ -*- C++ -*-
- // Create toolbar
-
- // Copyright (C) 1998 Technische Universitaet Braunschweig, Germany.
- // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
- //
- // This file is part of DDD.
- //
- // DDD is free software; you can redistribute it and/or
- // modify it under the terms of the GNU General Public
- // License as published by the Free Software Foundation; either
- // version 2 of the License, or (at your option) any later version.
- //
- // DDD is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- // See the GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public
- // License along with DDD -- see the file COPYING.
- // If not, write to the Free Software Foundation, Inc.,
- // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- //
- // DDD is the data display debugger.
- // For details, see the DDD World-Wide-Web page,
- // `http://www.cs.tu-bs.de/softech/ddd/',
- // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
-
- char toolbar_rcsid[] =
- "$Id: toolbar.C,v 1.21 1998/11/11 10:29:32 zeller Exp $";
-
- #ifdef __GNUG__
- #pragma implementation
- #endif
-
- #include "toolbar.h"
-
- #include "ddd.h"
- #include "logo.h"
- #include "misc.h"
- #include "verify.h"
- #include "HelpCB.h"
- #include "Delay.h"
- #include "AppData.h"
- #include "converters.h"
-
- #include <Xm/Xm.h>
- #include <Xm/Form.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/PanedW.h>
-
-
- //-----------------------------------------------------------------------
- // Helpers
- //-----------------------------------------------------------------------
-
- // Return the preferred height of W
- static Dimension preferred_height(Widget w)
- {
- XtWidgetGeometry size;
- size.request_mode = CWHeight;
- XtQueryGeometry(w, NULL, &size);
- Dimension real_height;
- XtVaGetValues(w, XmNheight, &real_height, NULL);
- return max(size.height, real_height);
- }
-
- static void set_label_type(MMDesc items[], unsigned char label_type)
- {
- for (MMDesc *item = items; item != 0 && item->name != 0; item++)
- {
- Widget w = item->widget;
- if (w != 0 && XmIsLabel(w))
- {
- XtVaSetValues(w, XmNlabelType, label_type, NULL);
-
- if (label_type != XmSTRING)
- continue;
-
- // In OSF/Motif, setting both labelString and labelPixmap
- // causes the button to use the Pixmap extent and to
- // ignore the labelString extent, even if its labelType is
- // XmSTRING. Hence, we set the size explicitly instead.
- //
- // (This only happens in OSF/Motif; LessTif works fine.)
- unsigned char label_type;
- XmString label_string;
- XmFontList font_list;
- Dimension border_width, shadow_thickness;
- Dimension margin_bottom, margin_top, margin_left, margin_right;
- Dimension margin_height, margin_width;
- XtVaGetValues(w,
- XmNlabelType, &label_type,
- XmNlabelString, &label_string,
- XmNfontList, &font_list,
- XmNborderWidth, &border_width,
- XmNshadowThickness, &shadow_thickness,
- XmNmarginBottom, &margin_bottom,
- XmNmarginTop, &margin_top,
- XmNmarginLeft, &margin_left,
- XmNmarginRight, &margin_right,
- XmNmarginHeight, &margin_height,
- XmNmarginWidth, &margin_width,
- NULL);
-
- Dimension label_width, label_height;
- XmStringExtent(font_list, label_string,
- &label_width, &label_height);
-
- Dimension width =
- border_width * 2 + shadow_thickness * 2 +
- margin_width * 2 +
- margin_left + label_width + margin_right;
-
- Dimension height =
- border_width * 2 + shadow_thickness * 2 +
- margin_height * 2 +
- margin_top + label_height + margin_bottom;
-
- XtVaSetValues(w,
- XmNrecomputeSize, False,
- XmNwidth, width + 4,
- XmNheight, height + 4,
- NULL);
-
- XmStringFree(label_string);
- }
- }
- }
-
- static void flatten_buttons(MMDesc items[])
- {
- // Replace all `MMPush' by `MMFlatPush'
- for (MMDesc *item = items; item != 0 && item->name != 0; item++)
- {
- if ((item->type & MMTypeMask) == MMPush)
- item->type = (MMFlatPush | (item->type & ~MMTypeMask));
- }
- }
-
- static Widget align_buttons(MMDesc *items1, MMDesc *items2)
- {
- Widget last_button = 0;
-
- for (int j = 1; j >= 0; j--)
- {
- MMDesc *items = (j == 0 ? items1 : items2);
- if (items == 0)
- continue;
-
- int i = -1;
- while (items[i + 1].widget != 0)
- i++;
- for (; i >= 0; i--)
- {
- Widget w = items[i].widget;
-
- if (!XtIsManaged(w))
- continue;
-
- Arg args[10];
- Cardinal arg = 0;
-
- XtSetArg(args[arg], XmNresizable, False); arg++;
- XtSetArg(args[arg], XmNtopAttachment, XmATTACH_FORM); arg++;
- XtSetArg(args[arg], XmNbottomAttachment, XmATTACH_FORM); arg++;
-
- if (last_button == 0)
- {
- XtSetArg(args[arg], XmNrightAttachment, XmATTACH_FORM); arg++;
- }
- else
- {
- XtSetArg(args[arg],
- XmNrightAttachment, XmATTACH_WIDGET); arg++;
- XtSetArg(args[arg],
- XmNrightWidget, last_button); arg++;
- }
-
- XtSetValues(w, args, arg);
-
- last_button = w;
- }
- }
-
- return last_button;
- }
-
-
-
- static void ResetLabelEH(Widget w, XtPointer, XEvent *, Boolean *)
- {
- XmString label_string;
- XtVaGetValues(w, XmNlabelString, &label_string, NULL);
-
- MString empty("");
-
- XtVaSetValues(w, XmNlabelString, empty.xmstring(), NULL);
- XtVaSetValues(w, XmNlabelString, label_string, NULL);
- XmStringFree(label_string);
-
- XtRemoveEventHandler(w, ExposureMask, False,
- ResetLabelEH, XtPointer(0));
- }
-
- static void center_buttons(MMDesc items[], Dimension offset)
- {
- for (MMDesc *item = items; item != 0 && item->name != 0; item++)
- {
- Widget w = item->widget;
- if (w == 0)
- continue;
-
- XtVaSetValues(w,
- XmNtopOffset, offset / 2,
- XmNbottomOffset, (offset + 1) / 2,
- NULL);
-
- // In OSF/Motif, setting both labelString and labelPixmap
- // causes the button to ignore the labelString extent, giving
- // a bad alignment of the labelString. This goes away as soon
- // as the label string is reset. Hence, reset it upon creation.
- XtAddEventHandler(w, ExposureMask, False,
- ResetLabelEH, XtPointer(0));
- }
- }
-
-
- //-----------------------------------------------------------------------
- // Toolbar creation
- //-----------------------------------------------------------------------
-
- // Create a toolbar as child of parent, named `toolbar', having
- // the buttons ITEMS. Return LABEL and ARGFIELD.
- Widget create_toolbar(Widget parent, string /* name */,
- MMDesc *items1, MMDesc *items2,
- Widget& label, ArgField*& argfield,
- unsigned char label_type)
- {
- assert(label_type == XmPIXMAP || label_type == XmSTRING);
-
- Arg args[10];
- Cardinal arg = 0;
-
- // Create toolbar
- string toolbar_name = "toolbar";
-
- arg = 0;
- XtSetArg(args[arg], XmNmarginWidth, 0); arg++;
- XtSetArg(args[arg], XmNmarginHeight, 0); arg++;
- XtSetArg(args[arg], XmNborderWidth, 0); arg++;
- XtSetArg(args[arg], XmNhighlightThickness, 0); arg++;
- Widget toolbar = verify(XmCreateForm(parent, toolbar_name, args, arg));
-
- // Create `():'
- label = create_arg_label(toolbar);
-
- // Create argument field
- string argfield_name = "arg";
- argfield = new ArgField (toolbar, argfield_name);
- Widget combobox = argfield->top();
-
- registerOwnConverters();
-
- // We install the icons AFTER having created the argument field,
- // because otherwise we might eat up all colors.
- install_icons(toolbar,
- app_data.button_color_key,
- app_data.active_button_color_key);
-
- if (label_type == XmPIXMAP && app_data.flat_toolbar_buttons)
- {
- // Use flat buttons
- flatten_buttons(items1);
- flatten_buttons(items2);
- }
-
- // Create buttons
- MMaddItems(toolbar, items1);
- MMaddCallbacks(items1);
- MMaddHelpCallback(items1, ImmediateHelpCB);
- set_label_type(items1, label_type);
-
- if (items2 != 0)
- {
- MMaddItems(toolbar, items2);
- MMaddCallbacks(items2);
- MMaddHelpCallback(items2, ImmediateHelpCB);
- set_label_type(items2, label_type);
- }
-
- Widget first_button = align_buttons(items1, items2);
-
- // Set form constraints
- XtVaSetValues(label,
- XmNresizable, False,
- XmNleftAttachment, XmATTACH_FORM,
- XmNtopAttachment, XmATTACH_FORM,
- XmNbottomAttachment, XmATTACH_FORM,
- NULL);
-
- XtVaSetValues(combobox,
- XmNresizable, False,
- XmNleftAttachment, XmATTACH_WIDGET,
- XmNleftWidget, label,
- XmNrightAttachment, XmATTACH_WIDGET,
- XmNrightWidget, first_button,
- XmNtopAttachment, XmATTACH_FORM,
- NULL);
-
- XtManageChild(toolbar);
- register_menu_shell(items1);
-
- if (items2 != 0)
- register_menu_shell(items2);
-
- // Check geometry
- Dimension button_height = preferred_height(items1[0].widget);
- Dimension arg_height = preferred_height(combobox);
- Dimension toolbar_height = max(button_height, arg_height);
- XtVaSetValues(toolbar, XmNheight, toolbar_height, NULL);
-
- if (XmIsPanedWindow(parent))
- {
- // Make sure the toolbar cannot be resized
- XtVaSetValues(toolbar,
- XmNpaneMaximum, toolbar_height,
- XmNpaneMinimum, toolbar_height,
- NULL);
-
- if (label_type == XmSTRING)
- {
- Dimension offset = max(arg_height - button_height, 0);
-
- // Center all labels. This must also be done if offset is
- // zero, since OSF/Motif 2.0 has trouble centering the
- // labels.
- center_buttons(items1, offset);
- center_buttons(items2, offset);
- }
-
- if (button_height > arg_height)
- {
- Dimension offset = max(button_height - arg_height, 0);
-
- // Center arg field
- XtVaSetValues(argfield->top(),
- XmNtopOffset, offset / 2,
- XmNbottomOffset, (offset + 1) / 2,
- NULL);
- }
- }
-
- return toolbar;
- }
-