summaryrefslogtreecommitdiffstats
path: root/src/ui/widget/marker-combo-box.h
blob: 8e3436d4ecfac728c80f5f1565df41937eaf80a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef SEEN_SP_MARKER_SELECTOR_NEW_H
#define SEEN_SP_MARKER_SELECTOR_NEW_H

/* Authors:
 *   Lauris Kaplinski <lauris@kaplinski.com>
 *   Maximilian Albert <maximilian.albert> (gtkmm-ification)
 *
 * Copyright (C) 2002 Lauris Kaplinski
 *
 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
 */
#include <vector>

#include <gtkmm/bin.h>
#include <gtkmm/box.h>
#include <gtkmm/builder.h>
#include <gtkmm/checkbutton.h>
#include <gtkmm/flowbox.h>
#include <gtkmm/image.h>
#include <gtkmm/liststore.h>
#include <gtkmm/menubutton.h>
#include <gtkmm/spinbutton.h>
#include <gio/gliststore.h>

#include <sigc++/signal.h>

#include "document.h"
#include "inkscape.h"
#include "scrollprotected.h"
#include "display/drawing.h"
#include "ui/operation-blocker.h"

class SPMarker;

namespace Gtk {

class Container;
class Adjustment;
}

namespace Inkscape {
namespace UI {
namespace Widget {

/**
 * ComboBox-like class for selecting stroke markers.
 */
class MarkerComboBox : public Gtk::Bin {
    using parent_type = Gtk::Bin;

public:
    MarkerComboBox(Glib::ustring id, int loc);
    ~MarkerComboBox() override;

    void setDocument(SPDocument *);

    sigc::signal<void ()> changed_signal;
    sigc::signal<void ()> edit_signal;

    void set_current(SPObject *marker);
    std::string get_active_marker_uri();
    bool in_update() { return _update.pending(); };
    const char* get_id() { return _combo_id.c_str(); };
    int get_loc() { return _loc; };

    sigc::signal<void()> signal_changed() { return _signal_changed; }

private:
    struct MarkerItem : Glib::Object {
        Cairo::RefPtr<Cairo::Surface> pix;
        SPDocument* source = nullptr;
        std::string id;
        std::string label;
        bool stock = false;
        bool history = false;
        bool separator = false;
        int width = 0;
        int height = 0;

        bool operator == (const MarkerItem& item) const;
    };

    SPMarker* get_current() const;
    Glib::ustring _current_marker_id;
    // SPMarker* _current_marker = nullptr;
    sigc::signal<void()> _signal_changed;
    Glib::RefPtr<Gtk::Builder> _builder;
    Gtk::FlowBox& _marker_list;
    Gtk::Label& _marker_name;
    Glib::RefPtr<Gio::ListStore<MarkerItem>> _marker_store;
    std::vector<Glib::RefPtr<MarkerItem>> _stock_items;
    std::vector<Glib::RefPtr<MarkerItem>> _history_items;
    std::map<Gtk::Widget*, Glib::RefPtr<MarkerItem>> _widgets_to_markers;
    Gtk::Image& _preview;
    bool _preview_no_alloc = true;
    Gtk::Button& _link_scale;
    Gtk::SpinButton& _angle_btn;
    Gtk::MenuButton& _menu_btn;
    Gtk::SpinButton& _scale_x;
    Gtk::SpinButton& _scale_y;
    Gtk::CheckButton& _scale_with_stroke;
    Gtk::SpinButton& _offset_x;
    Gtk::SpinButton& _offset_y;
    Gtk::Widget& _input_grid;
    Gtk::RadioButton& _orient_auto_rev;
    Gtk::RadioButton& _orient_auto;
    Gtk::RadioButton& _orient_angle;
    Gtk::Button& _orient_flip_horz;
    Gtk::Image& _current_img;
    Gtk::Button& _edit_marker;
    bool _scale_linked = true;
    guint32 _background_color;
    guint32 _foreground_color;
    Glib::ustring _combo_id;
    int _loc;
    OperationBlocker _update;
    SPDocument *_document = nullptr;
    std::unique_ptr<SPDocument> _sandbox;
    Gtk::CellRendererPixbuf _image_renderer;

    class MarkerColumns : public Gtk::TreeModel::ColumnRecord {
    public:
        Gtk::TreeModelColumn<Glib::ustring> label;
        Gtk::TreeModelColumn<const gchar *> marker;   // ustring doesn't work here on windows due to unicode
        Gtk::TreeModelColumn<gboolean> stock;
        Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf>> pixbuf;
        Gtk::TreeModelColumn<gboolean> history;
        Gtk::TreeModelColumn<gboolean> separator;

        MarkerColumns() {
            add(label); add(stock);  add(marker);  add(history); add(separator); add(pixbuf);
        }
    };
    MarkerColumns marker_columns;

    void update_ui(SPMarker* marker, bool select);
    void update_widgets_from_marker(SPMarker* marker);
    void update_store();
    Glib::RefPtr<MarkerItem> add_separator(bool filler);
    void update_scale_link();
    Glib::RefPtr<MarkerItem> get_active();
    Glib::RefPtr<MarkerItem> find_marker_item(SPMarker* marker);
    void on_style_updated() override;
    void update_preview(Glib::RefPtr<MarkerItem> marker_item);
    void update_menu_btn(Glib::RefPtr<MarkerItem> marker_item);
    void set_active(Glib::RefPtr<MarkerItem> item);
    void init_combo();
    void set_history(Gtk::TreeModel::Row match_row);
    void marker_list_from_doc(SPDocument* source, bool history);
    std::vector<SPMarker*> get_marker_list(SPDocument* source);
    void add_markers (std::vector<SPMarker *> const& marker_list, SPDocument *source,  gboolean history);
    void remove_markers (gboolean history);
    Cairo::RefPtr<Cairo::Surface> create_marker_image(Geom::IntPoint pixel_size, gchar const *mname,
        SPDocument *source, Inkscape::Drawing &drawing, unsigned /*visionkey*/, bool checkerboard, bool no_clip, double scale);
    void refresh_after_markers_modified();
    sigc::connection modified_connection;
    sigc::connection _idle;
};

} // namespace Widget
} // namespace UI
} // namespace Inkscape
#endif // SEEN_SP_MARKER_SELECTOR_NEW_H

/*
  Local Variables:
  mode:c++
  c-file-style:"stroustrup"
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
  indent-tabs-mode:nil
  fill-column:99
  End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :