Skip to content

Commit 1c4eea6

Browse files
Merge pull request #616 from rroohhh/dotted
new layer display style: dotted
2 parents e7f2d30 + 926dcdc commit 1c4eea6

File tree

3 files changed

+145
-42
lines changed

3 files changed

+145
-42
lines changed

Diff for: src/canvas/layer_display.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace horizon {
55
class LayerDisplay {
66
public:
77
// also used in shaders
8-
enum class Mode { OUTLINE = 0, HATCH = 1, FILL = 2, FILL_ONLY = 3, N_MODES };
8+
enum class Mode { OUTLINE = 0, HATCH = 1, FILL = 2, FILL_ONLY = 3, DOTTED = 4, N_MODES };
99
LayerDisplay(bool vi, Mode mo) : visible(vi), mode(mo)
1010
{
1111
}

Diff for: src/canvas/shaders/triangle-ubo.glsl

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
layout (std140) uniform layer_setup
2-
{
2+
{
33
vec3 colors[20];
44
vec3 colors2[256];
55
mat3 screenmat;
@@ -16,19 +16,30 @@ layout (std140) uniform layer_setup
1616
#define LAYER_MODE_HATCH (1U)
1717
#define LAYER_MODE_FILL (2U)
1818
#define LAYER_MODE_FILL_ONLY (3U)
19+
#define LAYER_MODE_DOTTED (4U)
1920

2021
#define PI 3.1415926535897932384626433832795
22+
#define COS_PI_SIXTH 0.86602540378443864676372317075
2123

2224
bool get_discard(vec2 fc) {
2325
if(layer_mode == LAYER_MODE_OUTLINE)
2426
return true;
2527

26-
if(layer_mode != LAYER_MODE_HATCH)
28+
if(layer_mode == LAYER_MODE_HATCH) {
29+
vec2 f = fc - offset*vec2(1,-1);
30+
float striper = f.x - f.y;
31+
return mod(striper,20)>10;
32+
} else if(layer_mode == LAYER_MODE_DOTTED) {
33+
float base_spacing = 10;
34+
vec2 f = fc - offset*vec2(1,-1);
35+
vec2 spacing = vec2(COS_PI_SIXTH * 2 * base_spacing, base_spacing);
36+
vec2 f1 = f - round(f / spacing) * spacing;
37+
vec2 ff = f + vec2(base_spacing * COS_PI_SIXTH, base_spacing / 2);
38+
vec2 f2 = ff - round(ff / spacing) * spacing;
39+
return (length(f1) < 2.5) || (length(f2) < 2.5);
40+
} else {
2741
return false;
28-
29-
vec2 f = fc - offset*vec2(1,-1);
30-
float striper = f.x - f.y;
31-
return mod(striper,20)>10;
42+
}
3243
}
3344

3445
vec3 get_color(int color, int color2) {

Diff for: src/widgets/layer_box.cpp

+127-35
Original file line numberDiff line numberDiff line change
@@ -9,52 +9,47 @@
99

1010
namespace horizon {
1111

12-
class LayerDisplayButton : public Gtk::DrawingArea {
12+
class LayerDisplayPreview : public Gtk::DrawingArea {
1313
public:
14-
LayerDisplayButton();
15-
16-
typedef Glib::Property<Gdk::RGBA> type_property_color;
17-
Glib::PropertyProxy<Gdk::RGBA> property_color()
18-
{
19-
return p_property_color.get_proxy();
20-
}
21-
typedef Glib::Property<LayerDisplay::Mode> type_property_display_mode;
22-
Glib::PropertyProxy<LayerDisplay::Mode> property_display_mode()
23-
{
24-
return p_property_display_mode.get_proxy();
25-
}
26-
void set_color(const Color &c);
14+
LayerDisplayPreview(const Glib::PropertyProxy<Gdk::RGBA> &property_color, LayerDisplay::Mode display_mode);
15+
LayerDisplayPreview(const Glib::PropertyProxy<Gdk::RGBA> &property_color,
16+
Glib::PropertyProxy<LayerDisplay::Mode> property_display_mode);
2717

2818
private:
2919
bool on_draw(const Cairo::RefPtr<::Cairo::Context> &cr) override;
30-
bool on_button_press_event(GdkEventButton *ev) override;
31-
type_property_color p_property_color;
32-
type_property_display_mode p_property_display_mode;
20+
Glib::PropertyProxy<Gdk::RGBA> property_color;
21+
LayerDisplay::Mode dm;
3322
};
3423

35-
LayerDisplayButton::LayerDisplayButton()
36-
: Glib::ObjectBase(typeid(LayerDisplayButton)), Gtk::DrawingArea(),
37-
p_property_color(*this, "color", Gdk::RGBA("#ff0000")), p_property_display_mode(*this, "display-mode")
24+
LayerDisplayPreview::LayerDisplayPreview(const Glib::PropertyProxy<Gdk::RGBA> &color, LayerDisplay::Mode mode)
25+
: Glib::ObjectBase(typeid(LayerDisplayPreview)), Gtk::DrawingArea(), property_color(color), dm(mode)
3826
{
3927
set_size_request(18, 18);
40-
add_events(Gdk::BUTTON_PRESS_MASK);
41-
property_display_mode().signal_changed().connect([this] { queue_draw(); });
42-
property_color().signal_changed().connect([this] { queue_draw(); });
28+
property_color.signal_changed().connect([this] { queue_draw(); });
29+
}
30+
31+
LayerDisplayPreview::LayerDisplayPreview(const Glib::PropertyProxy<Gdk::RGBA> &color,
32+
Glib::PropertyProxy<LayerDisplay::Mode> property_display_mode)
33+
: LayerDisplayPreview(color, property_display_mode.get_value())
34+
{
35+
property_display_mode.signal_changed().connect([this, property_display_mode] {
36+
dm = property_display_mode.get_value();
37+
queue_draw();
38+
});
4339
}
4440

45-
bool LayerDisplayButton::on_draw(const Cairo::RefPtr<::Cairo::Context> &cr)
41+
bool LayerDisplayPreview::on_draw(const Cairo::RefPtr<::Cairo::Context> &cr)
4642
{
4743

48-
const auto c = p_property_color.get_value();
44+
const auto c = property_color.get_value();
4945
cr->save();
5046
cr->translate(1, 1);
5147
cr->rectangle(0, 0, 16, 16);
5248
cr->set_source_rgb(0, 0, 0);
5349
cr->fill_preserve();
5450
cr->set_source_rgb(c.get_red(), c.get_green(), c.get_blue());
5551
cr->set_line_width(2);
56-
LayerDisplay::Mode dm = p_property_display_mode.get_value();
57-
if (dm == LayerDisplay::Mode::FILL || dm == LayerDisplay::Mode::FILL_ONLY) {
52+
if (dm == LayerDisplay::Mode::FILL || dm == LayerDisplay::Mode::FILL_ONLY || dm == LayerDisplay::Mode::DOTTED) {
5853
cr->fill_preserve();
5954
}
6055

@@ -76,20 +71,75 @@ bool LayerDisplayButton::on_draw(const Cairo::RefPtr<::Cairo::Context> &cr)
7671
cr->line_to(16, 7);
7772
cr->stroke();
7873
}
74+
if (dm == LayerDisplay::Mode::DOTTED) {
75+
cr->save();
76+
cr->set_source_rgb(0, 0, 0);
77+
cr->begin_new_sub_path();
78+
cr->arc(8, 1, 2, 0, 2 * M_PI);
79+
cr->begin_new_sub_path();
80+
cr->arc(8, 8, 2, 0, 2 * M_PI);
81+
cr->begin_new_sub_path();
82+
cr->arc(8, 15, 2, 0, 2 * M_PI);
83+
cr->begin_new_sub_path();
84+
cr->arc(2, 4.5, 2, 0, 2 * M_PI);
85+
cr->begin_new_sub_path();
86+
cr->arc(2, 12.5, 2, 0, 2 * M_PI);
87+
cr->begin_new_sub_path();
88+
cr->arc(14, 4.5, 2, 0, 2 * M_PI);
89+
cr->begin_new_sub_path();
90+
cr->arc(14, 12.5, 2, 0, 2 * M_PI);
91+
cr->fill();
92+
cr->restore();
93+
cr->rectangle(0, 0, 16, 16);
94+
cr->stroke();
95+
}
7996

8097
cr->restore();
8198
Gtk::DrawingArea::on_draw(cr);
8299
return true;
83100
}
84101

85-
bool LayerDisplayButton::on_button_press_event(GdkEventButton *ev)
102+
103+
class LayerDisplayButton : public Gtk::EventBox {
104+
public:
105+
LayerDisplayButton();
106+
void set_color(const Color &c);
107+
108+
Glib::PropertyProxy<Gdk::RGBA> property_color()
109+
{
110+
return p_property_color.get_proxy();
111+
}
112+
113+
Glib::PropertyProxy<LayerDisplay::Mode> property_display_mode()
114+
{
115+
return p_property_display_mode.get_proxy();
116+
}
117+
118+
private:
119+
void append_context_menu_item(const std::string &name, LayerDisplay::Mode mode);
120+
bool on_button_press_event(GdkEventButton *ev) override;
121+
Gtk::Menu context_menu;
122+
Gtk::RadioButtonGroup context_menu_group;
123+
std::map<LayerDisplay::Mode, Gtk::RadioMenuItem *> layer_mode_menu_items;
124+
125+
Glib::Property<Gdk::RGBA> p_property_color;
126+
Glib::Property<LayerDisplay::Mode> p_property_display_mode;
127+
128+
LayerDisplayPreview button_face;
129+
};
130+
131+
LayerDisplayButton::LayerDisplayButton()
132+
: Glib::ObjectBase(typeid(LayerDisplayButton)), Gtk::EventBox(),
133+
p_property_color(*this, "color", Gdk::RGBA("#ff0000")), p_property_display_mode(*this, "display-mode"),
134+
button_face(p_property_color.get_proxy(), p_property_display_mode.get_proxy())
86135
{
87-
if (ev->button != 1)
88-
return false;
89-
auto old_mode = static_cast<int>(static_cast<LayerDisplay::Mode>(property_display_mode()));
90-
auto new_mode = static_cast<LayerDisplay::Mode>((old_mode + 1) % static_cast<int>(LayerDisplay::Mode::N_MODES));
91-
p_property_display_mode = new_mode;
92-
return true;
136+
add(button_face);
137+
add_events(Gdk::BUTTON_PRESS_MASK);
138+
append_context_menu_item("Outline", LayerDisplay::Mode::OUTLINE);
139+
append_context_menu_item("Hatched", LayerDisplay::Mode::HATCH);
140+
append_context_menu_item("Fill", LayerDisplay::Mode::FILL);
141+
append_context_menu_item("Fill only", LayerDisplay::Mode::FILL_ONLY);
142+
append_context_menu_item("Dotted", LayerDisplay::Mode::DOTTED);
93143
}
94144

95145
void LayerDisplayButton::set_color(const Color &c)
@@ -101,6 +151,46 @@ void LayerDisplayButton::set_color(const Color &c)
101151
property_color() = rgba;
102152
}
103153

154+
void LayerDisplayButton::append_context_menu_item(const std::string &name, LayerDisplay::Mode mode)
155+
{
156+
auto it = Gtk::manage(new Gtk::RadioMenuItem(context_menu_group));
157+
158+
auto *hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 8));
159+
auto *preview = Gtk::manage(new LayerDisplayPreview(property_color(), mode));
160+
hbox->pack_start(*preview, false, false, 0);
161+
preview->show();
162+
auto *label = Gtk::manage(new Gtk::Label(name));
163+
hbox->pack_start(*label, false, false, 0);
164+
label->show();
165+
166+
it->add(*hbox);
167+
hbox->show();
168+
169+
it->signal_activate().connect([this, mode] { p_property_display_mode = mode; });
170+
context_menu.append(*it);
171+
it->show();
172+
layer_mode_menu_items.emplace(mode, it);
173+
}
174+
175+
bool LayerDisplayButton::on_button_press_event(GdkEventButton *ev)
176+
{
177+
if (gdk_event_triggers_context_menu((GdkEvent *)ev)) {
178+
layer_mode_menu_items.at(p_property_display_mode)->set_active();
179+
#if GTK_CHECK_VERSION(3, 22, 0)
180+
context_menu.popup_at_pointer((GdkEvent *)ev);
181+
#else
182+
context_menu.popup(ev->button, gtk_get_current_event_time());
183+
#endif
184+
return true;
185+
}
186+
if (ev->button != 1)
187+
return false;
188+
auto old_mode = static_cast<int>(static_cast<LayerDisplay::Mode>(property_display_mode()));
189+
auto new_mode = static_cast<LayerDisplay::Mode>((old_mode + 1) % static_cast<int>(LayerDisplay::Mode::N_MODES));
190+
p_property_display_mode = new_mode;
191+
return true;
192+
}
193+
104194

105195
class LayerBoxRow : public Gtk::Box {
106196
public:
@@ -321,13 +411,15 @@ void LayerBox::update()
321411
update_work_layer();
322412
}
323413

414+
// clang-format off
324415
static const LutEnumStr<LayerDisplay::Mode> dm_lut = {
325416
{"outline", LayerDisplay::Mode::OUTLINE},
326417
{"hatch", LayerDisplay::Mode::HATCH},
327418
{"fill", LayerDisplay::Mode::FILL},
328419
{"fill_only", LayerDisplay::Mode::FILL_ONLY},
420+
{"dotted", LayerDisplay::Mode::DOTTED},
329421
};
330-
422+
// clang-format on
331423

332424
void LayerBox::update_work_layer()
333425
{

0 commit comments

Comments
 (0)