static gboolean gx_knob_expose(GtkWidget *widget, GdkEventExpose *event) { g_assert(GX_IS_KNOB(widget)); GdkRectangle image_rect, value_rect; GdkPixbuf *pb = gtk_widget_render_icon(widget, get_stock_id(widget), GtkIconSize(-1), NULL); if (GDK_IS_PIXBUF (pb)) { gint fcount; get_image_dimensions (widget, pb, &image_rect, &fcount); gdouble knobstate = _gx_regler_get_step_pos(GX_REGLER(widget), 1); _gx_regler_get_positions(GX_REGLER(widget), &image_rect, &value_rect); _gx_knob_expose(widget, &image_rect, knobstate, pb, fcount, gtk_widget_has_focus(widget)); _gx_regler_display_value(GX_REGLER(widget), &value_rect); g_object_unref(pb); } return FALSE; }
static gboolean gx_selector_button_press (GtkWidget *widget, GdkEventButton *event) { g_assert(GX_IS_SELECTOR(widget)); GxSelector *selector = GX_SELECTOR(widget); int i, n; gboolean ret; GdkRectangle rect; switch (event->button) { case 1: // left button if (event->type != GDK_BUTTON_PRESS) { return TRUE; } gtk_widget_grab_focus(widget); gtk_grab_add(widget); n = gtk_tree_model_iter_n_children(selector->model, NULL); i = get_selector_state(GX_SELECTOR(widget)) + 1; if (i >= n) { i = 0; } set_value_from_selector_state(GX_SELECTOR(widget), i); break; case 3: // right button show num entry rect.width = widget->requisition.width; rect.height = widget->requisition.height; rect.x = widget->allocation.x + (widget->allocation.width - widget->requisition.width) / 2; rect.y = widget->allocation.y + (widget->allocation.height - widget->requisition.height) / 2; g_signal_emit_by_name(GX_REGLER(widget), "value-entry", &rect, event, &ret); return ret; break; } return TRUE; }
static gboolean gx_knob_leave_out (GtkWidget *widget, GdkEventCrossing *event) { g_assert(GX_IS_KNOB(widget)); if (gtk_widget_has_grab(widget) || gtk_widget_has_focus(widget)== TRUE) { return TRUE; } GdkRectangle image_rect; GdkPixbuf *pb = gtk_widget_render_icon(widget, get_stock_id(widget), GtkIconSize(-1), NULL); gint fcount; get_image_dimensions (widget, pb, &image_rect, &fcount); g_object_unref(pb); gdouble knobstate = _gx_regler_get_step_pos(GX_REGLER(widget), 1); _gx_regler_get_positions(GX_REGLER(widget), &image_rect, NULL); if (fcount == -1) { _gx_knob_expose(widget, &image_rect, knobstate, pb, fcount, FALSE); } return TRUE; }
static gboolean gx_port_display_expose(GtkWidget *widget, GdkEventExpose *event) { if (GDK_IS_WINDOW (widget->window)) { g_assert(GX_IS_PORT_DISPLAY(widget)); gint display_width; GdkRectangle image_rect, value_rect; GdkPixbuf *pb = gtk_widget_render_icon(widget, get_stock_id(widget), GtkIconSize(-1), NULL); gtk_widget_style_get(widget, "display-width", &display_width, NULL); image_rect.height = gdk_pixbuf_get_height(pb); image_rect.width = (gdk_pixbuf_get_width(pb) + display_width) / 2; gdouble sliderstate = _gx_regler_get_step_pos(GX_REGLER(widget), image_rect.width-display_width); _gx_regler_get_positions(GX_REGLER(widget), &image_rect, &value_rect); port_display_expose(event, widget, &image_rect, sliderstate, pb); _gx_regler_simple_display_value(GX_REGLER(widget), &value_rect); g_object_unref(pb); } return FALSE; }
static void gx_port_display_size_request (GtkWidget *widget, GtkRequisition *requisition) { g_assert(GX_IS_PORT_DISPLAY(widget)); gint display_width; gtk_widget_style_get(widget, "display-width", &display_width, NULL); GdkPixbuf *pb = gtk_widget_render_icon(widget, get_stock_id(widget), GtkIconSize(-1), NULL); requisition->height = 2+gdk_pixbuf_get_height(pb); requisition->width = (gdk_pixbuf_get_width(pb) + display_width) / 2; _gx_regler_calc_size_request(GX_REGLER(widget), requisition); g_object_unref(pb); }
static void gx_regler_cp_configure(GxControlParameter *self, gchar* group, gchar *name, gdouble lower, gdouble upper, gdouble step) { g_return_if_fail(GX_IS_REGLER(self)); GxRegler *regler = GX_REGLER(self); if (regler->label) { gtk_label_set_text(regler->label, name); } GtkRange *range = GTK_RANGE(self); gtk_range_set_range(range, lower, upper); gtk_range_set_increments(range, step, 0); }
static void gx_knob_size_request (GtkWidget *widget, GtkRequisition *requisition) { g_assert(GX_IS_KNOB(widget)); GdkPixbuf *pb = gtk_widget_render_icon(widget, get_stock_id(widget), GtkIconSize(-1), NULL); if (GDK_IS_PIXBUF (pb)) { gint fcount; GdkRectangle rect; get_image_dimensions (widget, pb, &rect, &fcount); requisition->width = rect.width; requisition->height = rect.height; _gx_regler_calc_size_request(GX_REGLER(widget), requisition); g_object_unref(pb); } }
gboolean _gx_knob_pointer_event(GtkWidget *widget, gdouble x, gdouble y, const gchar *icon, gboolean drag, int state, int button, GdkEventButton *event) { int fcount; bool finemode = ((state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) != 0); GdkRectangle image_rect, value_rect; GxKnob *knob = GX_KNOB(widget); GdkPixbuf *pb = gtk_widget_render_icon(widget, icon, GtkIconSize(-1), NULL); GxKnobPrivate *priv = knob->priv; get_image_dimensions (widget, pb, &image_rect, &fcount); g_object_unref(pb); x += widget->allocation.x; y += widget->allocation.y; _gx_regler_get_positions(GX_REGLER(widget), &image_rect, &value_rect); if (!drag) { if (_gx_regler_check_display_popup(GX_REGLER(widget), &image_rect, &value_rect, event)) { return FALSE; } } static double last_y = 2e20; GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); double radius = min(image_rect.width, image_rect.height) / 2; double posx = radius - x + image_rect.x; // x axis right -> left double posy = radius - y + image_rect.y; // y axis top -> bottom double value; if (!drag) { if (event && event->type == GDK_2BUTTON_PRESS) { last_y = 2e20; } else { last_y = posy; return TRUE; } } if (last_y < 1e20) { // in drag started in linear mode const double scaling = 0.005; double scal = (finemode ? scaling*0.1 : scaling); value = (posy - last_y) * scal; last_y = posy; gtk_range_set_value(GTK_RANGE(widget), adj->value + value * (adj->upper - adj->lower)); return TRUE; } double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI if (drag) { // block "forbidden zone" and direct moves between quadrant 1 and 4 int quadrant = 1 + (int)(angle/M_PI_2); if (priv->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) { angle = scale_zero; } else if (priv->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) { angle = 2*M_PI - scale_zero; } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } priv->last_quadrant = quadrant; } } else { if (angle < scale_zero) { angle = scale_zero; } else if (angle > 2*M_PI - scale_zero) { angle = 2*M_PI - scale_zero; } priv->last_quadrant = 0; } angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1 gtk_range_set_value(GTK_RANGE(widget), adj->lower + angle * (adj->upper - adj->lower)); return TRUE; }