ui/gtk/button.c

changeset 109
c3dfcb8f0be7
parent 108
77254bd6dccb
child 110
c00e968d018b
equal deleted inserted replaced
108:77254bd6dccb 109:c3dfcb8f0be7
30 #include <stdlib.h> 30 #include <stdlib.h>
31 31
32 #include "button.h" 32 #include "button.h"
33 #include "container.h" 33 #include "container.h"
34 #include <cx/allocator.h> 34 #include <cx/allocator.h>
35 #include <cx/buffer.h>
36 #include <cx/json.h>
35 #include "../common/context.h" 37 #include "../common/context.h"
36 #include "../common/object.h" 38 #include "../common/object.h"
37 39
38 void ui_button_set_icon_name(GtkWidget *button, const char *icon) { 40 void ui_button_set_icon_name(GtkWidget *button, const char *icon) {
39 if(!icon) { 41 if(!icon) {
116 e.eventdata = NULL; 118 e.eventdata = NULL;
117 e.eventdatatype = 0; 119 e.eventdatatype = 0;
118 e.intval = event->value; 120 e.intval = event->value;
119 e.set = ui_get_setop(); 121 e.set = ui_get_setop();
120 event->callback(&e, event->userdata); 122 event->callback(&e, event->userdata);
123 }
124
125 void ui_button_set_label(UIWIDGET button, const char *label) {
126 gtk_button_set_label(GTK_BUTTON(button), label);
127 }
128
129 void ui_button_set_icon(UIWIDGET button, const char *icon) {
130 ui_button_set_icon_name(button, icon);
121 } 131 }
122 132
123 int64_t ui_toggle_button_get(UiInteger *integer) { 133 int64_t ui_toggle_button_get(UiInteger *integer) {
124 GtkToggleButton *button = integer->obj; 134 GtkToggleButton *button = integer->obj;
125 integer->value = (int)gtk_toggle_button_get_active(button); 135 integer->value = (int)gtk_toggle_button_get_active(button);
592 } 602 }
593 603
594 value->value = i; 604 value->value = i;
595 } 605 }
596 #endif 606 #endif
607
608
609 static void ui_destroy_linkbutton(GtkWidget *widget, UiLinkButton *data) {
610 free(data->link);
611 free(data);
612 }
613
614 static const char* linkbutton_get_uri(UiLinkButton *link) {
615 if(link->type == UI_LINK_BUTTON) {
616 return link->link;
617 } else {
618 return gtk_link_button_get_uri(GTK_LINK_BUTTON(link->widget));
619 }
620 }
621
622 static void linkbutton_set_uri(UiLinkButton *link, const char *uri) {
623 if(link->type == UI_LINK_BUTTON) {
624 free(link->link);
625 link->link = uri ? strdup(uri) : NULL;
626 } else {
627 gtk_link_button_set_uri(GTK_LINK_BUTTON(link->widget), uri);
628 }
629 }
630
631 static gboolean linkbutton_get_visited(UiLinkButton *link) {
632 if(link->type == UI_LINK_BUTTON) {
633 return FALSE;
634 } else {
635 gtk_link_button_get_visited(GTK_LINK_BUTTON(link->widget));
636 }
637 }
638
639 static void linkbutton_set_visited(UiLinkButton *link, gboolean visited) {
640 if(link->type != UI_LINK_BUTTON) {
641 gtk_link_button_set_visited(GTK_LINK_BUTTON(link->widget), visited);
642 }
643 }
644
645 /*
646 * Apply linkbutton settings from json. Expects jsonvalue to be a valid
647 * json object.
648 *
649 * {
650 * "label": "label text",
651 * "uri": "http://example.com",
652 * "visited": true
653 * }
654 *
655 */
656 static void linkbutton_apply_value(UiLinkButton *link, const char *jsonvalue) {
657 CxJson json;
658 cxJsonInit(&json, NULL);
659 cxJsonFill(&json, jsonvalue);
660
661 CxJsonValue *value;
662 if(cxJsonNext(&json, &value) == CX_JSON_NO_ERROR) {
663 if(cxJsonIsObject(value)) {
664 CxJsonValue *label = cxJsonObjGet(value, "label");
665 CxJsonValue *uri = cxJsonObjGet(value, "uri");
666 CxJsonValue *visited = cxJsonObjGet(value, "visited");
667 if(label) {
668 gtk_button_set_label(GTK_BUTTON(link->widget), cxJsonIsString(label) ? cxJsonAsString(label) : NULL);
669 }
670 if(uri) {
671 linkbutton_set_uri(link, cxJsonIsString(uri) ? cxJsonAsString(uri) : NULL);
672
673 }
674 if(visited) {
675 linkbutton_set_visited(link, cxJsonIsBool(visited) ? cxJsonAsBool(visited) : FALSE);
676 }
677 }
678 cxJsonValueFree(value);
679 }
680 cxJsonDestroy(&json);
681 }
682
683 static char* create_linkbutton_jsonvalue(const char *label, const char *uri, gboolean include_null, gboolean visited, gboolean set_visited) {
684 CxJsonValue *obj = cxJsonCreateObj(NULL);
685 if(label) {
686 cxJsonObjPutString(obj, CX_STR("label"), label);
687 } else if(include_null) {
688 cxJsonObjPutLiteral(obj, CX_STR("label"), CX_JSON_NULL);
689 }
690
691 if(uri) {
692 cxJsonObjPutString(obj, CX_STR("uri"), uri);
693 } else if(include_null) {
694 cxJsonObjPutLiteral(obj, CX_STR("uri"), CX_JSON_NULL);
695 }
696
697 if(set_visited) {
698 cxJsonObjPutLiteral(obj, CX_STR("visited"), visited ? CX_JSON_TRUE : CX_JSON_FALSE);
699 }
700
701 CxJsonWriter writer = cxJsonWriterCompact();
702 CxBuffer buf;
703 cxBufferInit(&buf, NULL, 128, NULL, CX_BUFFER_AUTO_EXTEND);
704 cxJsonWrite(&buf, obj, (cx_write_func)cxBufferWrite, &writer);
705 cxJsonValueFree(obj);
706 cxBufferTerminate(&buf);
707
708 return buf.space;
709 }
710
711 static char* linkbutton_get_value(UiLinkButton *link) {
712 const char *label = gtk_button_get_label(GTK_BUTTON(link->widget));
713 const char *uri = linkbutton_get_uri(link);
714 gboolean visited = linkbutton_get_visited(link);
715 return create_linkbutton_jsonvalue(label, uri, TRUE, visited, TRUE);
716 }
717
718 static void linkbutton_clicked(GtkWidget *widget, UiLinkButton *data) {
719 if(data->onclick) {
720 UiEvent e;
721 e.obj = data->obj;
722 e.document = e.obj->ctx->document;
723 e.window = e.obj->window;
724 e.eventdata = (char*)linkbutton_get_uri(data);
725 e.eventdatatype = UI_EVENT_DATA_STRING;
726 e.intval = 0;
727 e.set = ui_get_setop();
728 data->onclick(&e, data->onclickdata);
729 }
730 }
731
732 static gboolean linkbutton_activate_link(GtkLinkButton *self, UiLinkButton *data) {
733 linkbutton_clicked(data->widget, data);
734 return data->nofollow;
735 }
736
737 UIWIDGET ui_linkbutton_create(UiObject *obj, UiLinkButtonArgs *args) {
738 UiLinkButton *data = malloc(sizeof(UiLinkButton));
739 memset(data, 0, sizeof(UiLinkButton));
740 data->obj = obj;
741 data->type = args->type;
742 data->nofollow = args->nofollow;
743 data->onclick = args->onclick;
744 data->onclickdata = args->onclickdata;
745
746 GtkWidget *button;
747 if(args->type == UI_LINK_BUTTON) {
748 button = gtk_button_new();
749 g_signal_connect(
750 button,
751 "clicked",
752 G_CALLBACK(linkbutton_clicked),
753 data);
754 } else {
755 button = gtk_link_button_new("file:///");
756 g_signal_connect(
757 button,
758 "activate-link",
759 G_CALLBACK(linkbutton_activate_link),
760 data);
761 }
762 gtk_button_set_label(GTK_BUTTON(button), args->label);
763 g_object_set_data(G_OBJECT(button), "ui_linkbutton", data);
764 g_signal_connect(
765 button,
766 "destroy",
767 G_CALLBACK(ui_destroy_linkbutton),
768 data);
769
770 data->widget = button;
771
772 UiObject* current = uic_current_obj(obj);
773 UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING);
774 if(var) {
775 UiString *str = var->value;
776 char *current_value = ui_get(str);
777 if(current_value) {
778 linkbutton_apply_value(data, current_value);
779 }
780
781 str->obj = data;
782 str->get = ui_linkbutton_get;
783 str->set = ui_linkbutton_set;
784 }
785
786 ui_set_name_and_style(button, args->name, args->style_class);
787 ui_set_widget_groups(obj->ctx, button, args->groups);
788 UI_APPLY_LAYOUT2(current, args);
789 current->container->add(current->container, button);
790
791 return button;
792 }
793
794 char* ui_linkbutton_get(UiString *s) {
795 UiLinkButton *link = s->obj;
796 if(s->value.free) {
797 s->value.free(s->value.ptr);
798 }
799 s->value.ptr = linkbutton_get_value(link);
800 s->value.free = free;
801 return s->value.ptr;
802 }
803
804 void ui_linkbutton_set(UiString *s, const char *str) {
805 linkbutton_apply_value(s->obj, str);
806 if(s->value.free) {
807 s->value.free(s->value.ptr);
808 }
809 }
810
811
812 void ui_linkbutton_value_set(UiString *str, const char *label, const char *uri) {
813 char *value = create_linkbutton_jsonvalue(label, uri, TRUE, FALSE, TRUE);
814 ui_set(str, value);
815 free(value);
816 }
817
818 void ui_linkbutton_value_set_label(UiString *str, const char *label) {
819 char *value = create_linkbutton_jsonvalue(label, NULL, FALSE, FALSE, TRUE);
820 ui_set(str, value);
821 free(value);
822 }
823
824 void ui_linkbutton_value_set_uri(UiString *str, const char *uri) {
825 char *value = create_linkbutton_jsonvalue(NULL, uri, FALSE, FALSE, TRUE);
826 ui_set(str, value);
827 free(value);
828 }
829
830 void ui_linkbutton_value_set_visited(UiString *str, UiBool visited) {
831 char *value = create_linkbutton_jsonvalue(NULL, NULL, FALSE, visited, TRUE);
832 ui_set(str, value);
833 free(value);
834 }
835
836
837 void ui_linkbutton_set_label(UIWIDGET button, const char *label) {
838 gtk_button_set_label(GTK_BUTTON(button), label);
839 }
840
841 void ui_linkbutton_set_uri(UIWIDGET button, const char *label) {
842 UiLinkButton *link = g_object_get_data(G_OBJECT(button), "ui_linkbutton");
843 if(link) {
844 linkbutton_set_uri(link, label);
845 } else {
846 fprintf(stderr, "Error: ui_linkbutton_set_label: widget is not a linkbutton\n");
847 }
848 }
849
850 void ui_linkbutton_set_visited(UIWIDGET button, UiBool visited) {
851 UiLinkButton *link = g_object_get_data(G_OBJECT(button), "ui_linkbutton");
852 if(link) {
853 linkbutton_set_visited(link, visited);
854 } else {
855 fprintf(stderr, "Error: ui_linkbutton_set_label: widget is not a linkbutton\n");
856 }
857 }
858
859 char* ui_linkbutton_get_label(UIWIDGET button) {
860 const char *label = gtk_button_get_label(GTK_BUTTON(button));
861 return label ? strdup(label) : NULL;
862 }
863
864 char* ui_linkbutton_get_uri(UIWIDGET button) {
865 UiLinkButton *link = g_object_get_data(G_OBJECT(button), "ui_linkbutton");
866 if(link) {
867 const char *uri = linkbutton_get_uri(link);
868 return uri ? strdup(uri) : NULL;
869 } else {
870 fprintf(stderr, "Error: ui_linkbutton_set_label: widget is not a linkbutton\n");
871 }
872 return NULL;
873 }
874
875 UiBool ui_linkbutton_get_visited(UIWIDGET button) {
876 UiLinkButton *link = g_object_get_data(G_OBJECT(button), "ui_linkbutton");
877 if(link) {
878 return linkbutton_get_visited(link);
879 } else {
880 fprintf(stderr, "Error: ui_linkbutton_set_label: widget is not a linkbutton\n");
881 }
882 return FALSE;
883 }

mercurial