| 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 } |