## GwyMarkerBox

GwyMarkerBox — Base class for box with movable markers.

## Synopsis

    #include <libgwydgets/gwydgets.h>

    gboolean            (*GwyMarkerValidateFunc)            (GwyMarkerBox *mbox,
                                                             GwyMarkerOperationType optype,
                                                             gint *i,
                                                             gdouble *pos);
                        GwyMarkerBox;
                        GwyMarkerBoxClass;
    gint                gwy_marker_box_get_selected_marker  (GwyMarkerBox *mbox);
    void                gwy_marker_box_set_selected_marker  (GwyMarkerBox *mbox,
                                                             gint i);
    gdouble             gwy_marker_box_get_marker_position  (GwyMarkerBox *mbox,
                                                             gint i);
    gboolean            gwy_marker_box_set_marker_position  (GwyMarkerBox *mbox,
                                                             gint i,
                                                             gdouble pos);
    gint                gwy_marker_box_add_marker           (GwyMarkerBox *mbox,
                                                             gint i,
                                                             gdouble pos);
    gboolean            gwy_marker_box_remove_marker        (GwyMarkerBox *mbox,
                                                             gint i);
    gint                gwy_marker_box_get_nmarkers         (GwyMarkerBox *mbox);
    const gdouble*      gwy_marker_box_get_markers          (GwyMarkerBox *mbox);
    void                gwy_marker_box_set_markers          (GwyMarkerBox *mbox,
                                                             gint n,
                                                             const gdouble *markers);
    void                gwy_marker_box_set_flipped          (GwyMarkerBox *mbox,
                                                             gboolean flipped);
    gboolean            gwy_marker_box_get_flipped          (GwyMarkerBox *mbox);
    void                gwy_marker_box_set_highlight_selected
                                                            (GwyMarkerBox *mbox,
                                                             gboolean highlight);
    gboolean            gwy_marker_box_get_highlight_selected
                                                            (GwyMarkerBox *mbox);
    void                gwy_marker_box_set_validator        (GwyMarkerBox *mbox,
                                                             GwyMarkerValidateFunc validate);
    GwyMarkerValidateFunc gwy_marker_box_get_validator      (GwyMarkerBox *mbox);

## Object Hierarchy

      GObject
       +----GInitiallyUnowned
             +----GtkObject
                   +----GtkWidget
                         +----GwyMarkerBox
                               +----GwyHMarkerBox

## Implemented Interfaces

GwyMarkerBox implements AtkImplementorIface and GtkBuildable.

## Properties

      "flipped"                  gboolean              : Read / Write
      "highlight-selected"       gboolean              : Read / Write
      "selected-marker"          gint                  : Read / Write

## Signals

      "marker-added"                                   : Run First
      "marker-moved"                                   : Run First
      "marker-removed"                                 : Run First
      "marker-selected"                                : Run First
      "markers-set"                                    : Run First

## Description

GwyMarkerBox is a box with triangular markers that can be moved, added, and/or deleted. One or no marker can be selected.

Marker coordinates are always from the range [0.0, 1.0].

It is possible to fully control where and how user can move, add, and/or delete markers with marker validation function set with `gwy_marker_box_set_validator()`. By default, no validator is in effect and user can change markers completely freely.

## Details

### GwyMarkerValidateFunc ()

    gboolean            (*GwyMarkerValidateFunc)            (GwyMarkerBox *mbox,
                                                             GwyMarkerOperationType optype,
                                                             gint *i,
                                                             gdouble *pos);

Marker validation function.

It is called for each single-marker change, both by user and by GwyMarkerBox methods. However, it is NOT called upon `gwy_marker_box_set_markers()` as it is unclear how the validation should proceed.

The function must not have any side-effects, that is it must not assume the operation will be actually performed when it returns `TRUE`.

Marker validator that allows free marker movement but disables insertion and removal could look:

    static gboolean
    validate_marker(GwyMarkerBox *mbox,
                    GwyMarkerOperationType optype,
                    gint *i,
                    gdouble *pos)
    {
        if (optype == GWY_MARKER_OPERATION_ADD
            || optype == GWY_MARKER_OPERATION_REMOVE)
            return FALSE;
        return TRUE;
    }

Marker validator that assures markers are sorted and there is always a marker at 0.0 and another at 1.0 could look:

    static gboolean
    validate_marker(GwyMarkerBox *mbox,
                    GwyMarkerOperationType optype,
                    gint *i,
                    gdouble *pos)
    {
        const gdouble *markers;
        gint j, n;

        n = gwy_marker_box_get_nmarkers(mbox);

        /* Insertions are sorted */
        if (optype == GWY_MARKER_OPERATION_ADD) {
            markers = gwy_marker_box_get_markers(mbox);
            for (j = 0; j < n; j++) {
                if (*pos < markers[j])
                    break;
            }
            if (j == 0 || j == n)
                return FALSE;
            *i = j;
            return TRUE;
        }

        /* Nothing at all can be done with border markers */
        if (*i == 0 || *i == n-1)
            return FALSE;

        /* Inner markers can be moved only from previous to next */
        if (optype == GWY_MARKER_OPERATION_MOVE) {
            markers = gwy_marker_box_get_markers(mbox);
            *pos = CLAMP(*pos, markers[*i - 1], markers[*i + 1]);
        }
        return TRUE;
    }

`mbox` : | The GwyMarkerBox to validate markers for.
`optype` : | Marker operation to validate.
`i` : | Pointer to index of marker to validate. For insertion, it's the position the marker would be inserted to (but it's not there yet), for removal it's the position where it still is. The validator can change the index, but it has an effect only when a marker is being added.
`pos` : | Pointer to requested marker position. The validator can change the position and the marker will be then moved or inserted to the changed position. For removal, its changes have no effect.
Returns : | `TRUE` to allow requested the operation, `FALSE` to disallow it.

### GwyMarkerBox

    typedef struct _GwyMarkerBox GwyMarkerBox;

### GwyMarkerBoxClass

    typedef struct {
        GtkWidgetClass parent_class;

        /* signals */
        void (*marker_selected)(GwyMarkerBox *mbox,
                                gint i);
        void (*marker_moved)(GwyMarkerBox *mbox,
                             gint i);
        void (*marker_added)(GwyMarkerBox *mbox,
                             gint i);
        void (*marker_removed)(GwyMarkerBox *mbox,
                               gint i);
        void (*markers_set)(GwyMarkerBox *mbox);

        /* virtual methods */
        void (*draw_box)(GwyMarkerBox *mbox);
        void (*draw_marker)(GwyMarkerBox *mbox,
                            gint i);

        void (*reserved1)(void);
        void (*reserved2)(void);
        void (*reserved3)(void);
    } GwyMarkerBoxClass;

### gwy_marker_box_get_selected_marker ()

    gint                gwy_marker_box_get_selected_marker  (GwyMarkerBox *mbox);

Gets the index of the currently selected marker in a marker box.

`mbox` : | A marker box.
Returns : | The index of currently selected marker, -1 when none is selected.

### gwy_marker_box_set_selected_marker ()

    void                gwy_marker_box_set_selected_marker  (GwyMarkerBox *mbox,
                                                             gint i);

Selects a marker in a marker box.

`mbox` : | A marker box.
`i` : | The index of marker to select. Pass -1 to unselect.

### gwy_marker_box_get_marker_position ()

    gdouble             gwy_marker_box_get_marker_position  (GwyMarkerBox *mbox,
                                                             gint i);

Gets the position of a marker in a marker box.

`mbox` : | A marker box.
`i` : | The index of marker to get position of.
Returns : | The marker position, in the range [0.0, 1.0].

### gwy_marker_box_set_marker_position ()

    gboolean            gwy_marker_box_set_marker_position  (GwyMarkerBox *mbox,
                                                             gint i,
                                                             gdouble pos);

Moves a marker in a marker box.

`mbox` : | A marker box.
`i` : | Index of marker to move.
`pos` : | The new marker position, in the range [0.0, 1.0].
Returns : | `TRUE` on success. If the move does not validate, `FALSE` is returned and the marker position does not change.

### gwy_marker_box_add_marker ()

    gint                gwy_marker_box_add_marker           (GwyMarkerBox *mbox,
                                                             gint i,
                                                             gdouble pos);

Adds a marker to a marker box.

`mbox` : | A marker box.
`i` : | Index to insert marker at.
`pos` : | Position to insert marker to, in the range [0.0, 1.0].
Returns : | On success, the index the marker was added at. If the insertion does not validate, -1 is returned and no marker is added.

### gwy_marker_box_remove_marker ()

    gboolean            gwy_marker_box_remove_marker        (GwyMarkerBox *mbox,
                                                             gint i);

Removes a marker from a marker box.

`mbox` : | A marker box.
`i` : | Index of marker to remove.
Returns : | `TRUE` on success. If the removal does not validate, `FALSE` is returned and the marker is kept.

### gwy_marker_box_get_nmarkers ()

    gint                gwy_marker_box_get_nmarkers         (GwyMarkerBox *mbox);

Gets the number of markers in a marker box.

`mbox` : | A marker box.
Returns : | The number of markers.

### gwy_marker_box_get_markers ()

    const gdouble*      gwy_marker_box_get_markers          (GwyMarkerBox *mbox);

Gets all markers in a marker box.

`mbox` : | A marker box.
Returns : | The markers as an array of positions, owned by `mbox`. It must not be modified nor freed by caller and it's valid only until next marker change.

### gwy_marker_box_set_markers ()

    void                gwy_marker_box_set_markers          (GwyMarkerBox *mbox,
                                                             gint n,
                                                             const gdouble *markers);

Sets positions of all markers in a marker box.

No validation is performed, even if validator is set. It's up to caller to set markers that do not logically conflict with the validator.

`mbox` : | A marker box.
`n` : | The number of markers to set. If it is zero, `markers` can be `NULL`.
`markers` : | Markers position.

### gwy_marker_box_set_flipped ()

    void                gwy_marker_box_set_flipped          (GwyMarkerBox *mbox,
                                                             gboolean flipped);

Sets whether a marker box is drawn upside down.

`mbox` : | A marker box.
`flipped` : | `TRUE` to draw markers upside down.

### gwy_marker_box_get_flipped ()

    gboolean            gwy_marker_box_get_flipped          (GwyMarkerBox *mbox);

Returns whether a marker box is drawn upside down.

`mbox` : | A marker box.
Returns : | `TRUE` if markers are drawn upside down.

### gwy_marker_box_set_highlight_selected ()

    void                gwy_marker_box_set_highlight_selected
                                                            (GwyMarkerBox *mbox,
                                                             gboolean highlight);

Sets whether a marker box highlights selected marker.

`mbox` : | A marker box.
`highlight` : | `TRUE` to visually differentiate selected marker, `FALSE` to draw markers uniformly.

### gwy_marker_box_get_highlight_selected ()

    gboolean            gwy_marker_box_get_highlight_selected
                                                            (GwyMarkerBox *mbox);

Returns whether a marker box highlights selected marker.

`mbox` : | A marker box.
Returns : | `TRUE` if selected marker is visually differentiated, `FALSE` if markers are drawn uniformly.

### gwy_marker_box_set_validator ()

    void                gwy_marker_box_set_validator        (GwyMarkerBox *mbox,
                                                             GwyMarkerValidateFunc validate);

Sets marker box marker validation function.

It is used the next time an attempt to change markers is made, no revalidation is done immediately. It's up to caller to set a validator that do not logically conflict with the distribution of markers.

`mbox` : | A marker box.
`validate` : | Marker validation function. Pass `NULL` to disable validation.

### gwy_marker_box_get_validator ()

    GwyMarkerValidateFunc gwy_marker_box_get_validator      (GwyMarkerBox *mbox);

Gets the marker validation function currently in use.

`mbox` : | A marker box.
Returns : | The marker validation function.

## Property Details

### The `"flipped"` property

      "flipped"                  gboolean              : Read / Write

Whether marks are drawn upside down.

Default value: FALSE

### The `"highlight-selected"` property

      "highlight-selected"       gboolean              : Read / Write

Whether to visually differentiate selected marker.

Default value: TRUE

### The `"selected-marker"` property

      "selected-marker"          gint                  : Read / Write

The index of selected marker, -1 if none.

Allowed values: [-1,1024]

Default value: -1

## Signal Details

### The `"marker-added"` signal

    void                user_function                      (GwyMarkerBox *arg1,
                                                            gint          gwymarkerbox,
                                                            gpointer      user_data)         : Run First

The ::marker-added signal is emitted when a marker is added.

`arg1` : | The index a marker was added at.
`gwymarkerbox` : | The GwyMarkerBox which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"marker-moved"` signal

    void                user_function                      (GwyMarkerBox *arg1,
                                                            gint          gwymarkerbox,
                                                            gpointer      user_data)         : Run First

The ::marker-moved signal is emitted when a marker is moved.

`arg1` : | The index of moved marker.
`gwymarkerbox` : | The GwyMarkerBox which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"marker-removed"` signal

    void                user_function                      (GwyMarkerBox *arg1,
                                                            gint          gwymarkerbox,
                                                            gpointer      user_data)         : Run First

The ::marker-removed signal is emitted when a marker is removed.

`arg1` : | The index a marker was removed from.
`gwymarkerbox` : | The GwyMarkerBox which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"marker-selected"` signal

    void                user_function                      (GwyMarkerBox *arg1,
                                                            gint          gwymarkerbox,
                                                            gpointer      user_data)         : Run First

The ::marker-selected signal is emitted when marker selection changes.

`arg1` : | The index of selected marker, -1 when marker was unselected.
`gwymarkerbox` : | The GwyMarkerBox which received the signal.
`user_data` : | user data set when the signal handler was connected.

### The `"markers-set"` signal

    void                user_function                      (GwyMarkerBox *gwymarkerbox,
                                                            gpointer      user_data)         : Run First

The ::markers-set signal is emitted when markers are explicitly set with `gwy_marker_box_set_markers()`.

`gwymarkerbox` : | The GwyMarkerBox which received the signal.
`user_data` : | user data set when the signal handler was connected.