bsnes/hiro/gtk/widget/label.cpp

143 lines
4.8 KiB
C++
Executable File

#if defined(Hiro_Label)
namespace hiro {
static auto Label_draw(GtkWidget* widget, cairo_t* context, pLabel* p) -> int {
auto color = p->state().backgroundColor;
if(auto window = p->self().parentWindow(true)) {
if(!color) color = window->backgroundColor();
}
if(color) {
double red = (double)color.red() / 255.0;
double green = (double)color.green() / 255.0;
double blue = (double)color.blue() / 255.0;
double alpha = (double)color.alpha() / 255.0;
if(gdk_screen_is_composited(gdk_screen_get_default())
&& gdk_screen_get_rgba_visual(gdk_screen_get_default())
) {
cairo_set_source_rgba(context, red, green, blue, alpha);
} else {
cairo_set_source_rgb(context, red, green, blue);
}
cairo_set_operator(context, CAIRO_OPERATOR_SOURCE);
cairo_paint(context);
} else {
#if HIRO_GTK==3
auto style = gtk_widget_get_style_context(widget);
if(auto tabFrame = p->self().parentTabFrame(true)) {
if(auto self = tabFrame->self()) style = gtk_widget_get_style_context(self->gtkWidget);
}
GtkAllocation allocation;
gtk_widget_get_allocation(widget, &allocation);
gtk_render_background(style, context, 0, 0, allocation.width, allocation.height);
#endif
}
return false;
}
static auto Label_expose(GtkWidget* widget, GdkEvent* event, pLabel* p) -> int {
cairo_t* context = gdk_cairo_create(gtk_widget_get_window(widget));
Label_draw(widget, context, p);
cairo_destroy(context);
return false;
}
static auto Label_mouseEnter(GtkWidget* widget, GdkEventButton* event, pCanvas* p) -> signed {
Widget_mouseEnter(widget, event, p);
return true;
}
static auto Label_mouseLeave(GtkWidget* widget, GdkEventButton* event, pCanvas* p) -> signed {
Widget_mouseLeave(widget, event, p);
return true;
}
static auto Label_mousePress(GtkWidget* widget, GdkEventButton* event, pLabel* p) -> int {
switch(event->button) {
case 1: p->self().doMousePress(Mouse::Button::Left); break;
case 2: p->self().doMousePress(Mouse::Button::Middle); break;
case 3: p->self().doMousePress(Mouse::Button::Right); break;
}
return true;
}
static auto Label_mouseRelease(GtkWidget* widget, GdkEventButton* event, pLabel* p) -> int {
switch(event->button) {
case 1: p->self().doMouseRelease(Mouse::Button::Left); break;
case 2: p->self().doMouseRelease(Mouse::Button::Middle); break;
case 3: p->self().doMouseRelease(Mouse::Button::Right); break;
}
return true;
}
auto pLabel::construct() -> void {
gtkWidget = gtk_event_box_new();
subWidget = gtk_label_new("");
gtk_widget_show(subWidget);
gtk_container_add(GTK_CONTAINER(gtkWidget), subWidget);
setAlignment(state().alignment);
setBackgroundColor(state().backgroundColor);
setForegroundColor(state().foregroundColor);
setText(state().text);
g_signal_connect(G_OBJECT(gtkWidget), "button-press-event", G_CALLBACK(Label_mousePress), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "button-release-event", G_CALLBACK(Label_mouseRelease), (gpointer)this);
#if HIRO_GTK==2
g_signal_connect(G_OBJECT(subWidget), "expose-event", G_CALLBACK(Label_expose), (gpointer)this);
#elif HIRO_GTK==3
g_signal_connect(G_OBJECT(subWidget), "draw", G_CALLBACK(Label_draw), (gpointer)this);
#endif
g_signal_connect(G_OBJECT(gtkWidget), "enter-notify-event", G_CALLBACK(Label_mouseEnter), (gpointer)this);
g_signal_connect(G_OBJECT(gtkWidget), "leave-notify-event", G_CALLBACK(Label_mouseLeave), (gpointer)this);
pWidget::construct();
}
auto pLabel::destruct() -> void {
gtk_widget_destroy(subWidget);
gtk_widget_destroy(gtkWidget);
}
auto pLabel::minimumSize() const -> Size {
auto size = pFont::size(self().font(true), state().text);
return {size.width(), size.height()};
}
auto pLabel::setAlignment(Alignment alignment) -> void {
if(!alignment) alignment = {0.0, 0.5};
gtk_misc_set_alignment(GTK_MISC(subWidget), alignment.horizontal(), alignment.vertical());
auto justify = GTK_JUSTIFY_CENTER;
if(alignment.horizontal() < 0.333) justify = GTK_JUSTIFY_LEFT;
if(alignment.horizontal() > 0.666) justify = GTK_JUSTIFY_RIGHT;
gtk_label_set_justify(GTK_LABEL(subWidget), justify);
}
auto pLabel::setBackgroundColor(Color color) -> void {
//GTK3 will paint the wrong background color when a label is inside of a TabFrame
//this is caused by the GtkEventBox wrapper that is required to paint custom backgrounds
//handle background painting via "draw" or "expose-event" signals instead
}
auto pLabel::setForegroundColor(Color color) -> void {
auto gdkColor = CreateColor(color);
gtk_widget_modify_fg(subWidget, GTK_STATE_NORMAL, color ? &gdkColor : nullptr);
}
auto pLabel::setText(const string& text) -> void {
gtk_label_set_text(GTK_LABEL(subWidget), text);
}
auto pLabel::setVisible(bool visible) -> void {
setBackgroundColor(state().backgroundColor);
return pWidget::setVisible(visible);
}
}
#endif