18#include <gdkmm/cursor.h>
19#include <gdkmm/general.h>
20#include <gtkmm/drawingarea.h>
21#include <sigc++/functors/mem_fun.h>
47 Glib::ObjectBase{
"GradientWithStops"},
57 set_name(
"GradientEdit");
64 Controller::add_motion<nullptr, &GradientWithStops::on_motion, nullptr>(*
this, *
this);
65 Controller::add_key<&GradientWithStops::on_key_pressed>(*
this, *
this);
111 if (
auto wnd =
dynamic_cast<Gtk::Window*
>(this->get_root())) {
133 auto pos = [&](
double offset) {
return round(layout.
x + layout.
width * CLAMP(
offset, 0, 1)); };
140 auto prev = pos(
v[index - 1].
offset) +
dx;
143 left = round((left + prev) / 2);
148 if (index + 1 <
v.size()) {
150 auto next = pos(
v[index + 1].
offset) -
dx;
153 right = round((right + next) / 2);
169 const auto half_stop = round((stop_width + 1) / 2);
170 const auto x = half_stop;
172 const double height = get_height();
190 for (
size_t i = 0; i <
v.size(); ++i) {
192 if (x >= pos.left && x <= pos.right && y >= pos.top && y <= pos.bottom) {
193 return static_cast<int>(i);
205 auto index =
static_cast<size_t>(maybe_index);
209 if (index <
v.size()) {
214 std::vector<double> offsets;
215 offsets.reserve(
v.size());
217 offsets.push_back(s.offset);
219 std::sort(offsets.begin(), offsets.end());
223 max = offsets[index + 1];
225 else if (index + 1 ==
v.size()) {
226 min = offsets[index - 1];
230 min = offsets[index - 1];
231 max = offsets[index + 1];
244 if (!(
direction == Gtk::DirectionType::TAB_FORWARD ||
direction == Gtk::DirectionType::TAB_BACKWARD)) {
248 auto const backward =
direction == Gtk::DirectionType::TAB_BACKWARD;
249 auto const n_stops =
_stops.size();
254 if (!(new_stop >= 0 && new_stop < n_stops)) {
271 unsigned const keyval,
unsigned ,
272 GdkModifierType
const state)
284 case GDK_KEY_KP_Left:
289 case GDK_KEY_KP_Right:
293 case GDK_KEY_BackSpace:
304 double const x,
double const y)
328 if (limits.min_offset < limits.max_offset) {
339 }
else if (n_press == 2) {
345 if (layout.width > 0 && x > layout.x && x < layout.x + layout.width) {
346 auto const position = (x - layout.x) / layout.width;
357 double const x,
double const y)
367 if (layout.width > 0) {
369 if (limits.min_offset < limits.max_offset) {
370 auto new_offset = CLAMP(limits.offset + offset_shift, limits.min_offset, limits.max_offset);
371 if (new_offset != limits.offset) {
379 double const x,
double const y)
387 if (layout.width > 0) {
388 auto delta =
dx / layout.width;
390 if (limits.min_offset < limits.max_offset) {
391 auto new_offset = CLAMP(
_stop_offset + delta, limits.min_offset, limits.max_offset);
400Glib::RefPtr<Gdk::Cursor>
const *
423 if (cursor !=
nullptr) {
435 const double scale = get_scale_factor();
438 if (layout.width <= 0)
return;
448 cr->begin_new_path();
450 auto const fg = get_color();
460 for (
size_t i = 0; i <
_stops.size(); ++i) {
461 const auto& stop =
_stops[i];
468 const auto is_selected =
_focused_stop ==
static_cast<int>(i);
475 g_warning(
"Rendering gradient stop failed.");
482 if (is_selected && tip) {
487 Gdk::Cairo::set_source_pixbuf(cr, tip, round(pos.tip *
scale - tip->get_width() / 2),
495 cr->rectangle(pos.left, layout.y, pos.right - pos.left, layout.height);
500 Gdk::Cairo::set_source_pixbuf(cr, pix, round(pos.tip *
scale - pix->get_width() / 2),
Cairo integration helpers.
double get_width_px() const
double get_height_px() const
size_t set_style(const Glib::ustring &selector, const char *name, const Glib::ustring &value)
Glib::RefPtr< Gdk::Pixbuf > render(double scale)
SPObject is an abstract base class of all of the document nodes at the SVG document level.
sigc::connection connectRelease(sigc::slot< void(SPObject *)> slot)
Connects to the release request signal.
sigc::connection connectModified(sigc::slot< void(SPObject *, unsigned int)> slot)
Connects to the modification notification signal.
gfloat getOpacity() const
SPStop * getNextStop()
Virtual write: write object attributes to repr.
Utilities to more easily use Gtk::EventController & subclasses like Gesture.
static constexpr int GRADIENT_IMAGE_HEIGHT
Gradient image widget with stop handles.
MultiDegree< n > max(MultiDegree< n > const &p, MultiDegree< n > const &q)
Returns the maximal degree appearing in the two arguments for each variables.
Piecewise< SBasis > min(SBasis const &f, SBasis const &g)
Return the more negative of the two functions pointwise.
std::string get_filename(Type type, char const *filename, bool localized, bool silent)
bool has_flag(Gdk::ModifierType const state, Gdk::ModifierType const flags)
Helper to query if ModifierType state contains one or more of given flag(s).
Gtk::GestureClick & add_click(Gtk::Widget &widget, ClickSlot on_pressed, ClickSlot on_released, Button const button, Gtk::PropagationPhase const phase, When const when)
Create a click gesture for the given widget; by default claim sequence.
static void set_sensitive(Gtk::SearchEntry2 &entry, bool const sensitive)
static Geom::Point direction(Geom::Point const &first, Geom::Point const &second)
Computes an unit vector of the direction from first to second control point.
void draw_gradient(const Cairo::RefPtr< Cairo::Context > &cr, SPGradient *gradient, int x, int width)
Renders a preview of a gradient into the passed context.
Glib::ustring rgba_to_css_color(double r, double g, double b)
Glib::ustring double_to_css_value(double value)
Inkscape::IO::Resource - simple resource API.
TODO: insert short description here.
Gdk::RGBA get_color_with_class(Gtk::Widget &widget, Glib::ustring const &css_class)