]> uap-core.de Git - note.git/commitdiff
implement markdown links
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 12 Mar 2025 18:41:45 +0000 (19:41 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Wed, 12 Mar 2025 18:41:45 +0000 (19:41 +0100)
application/editor.c
application/editor.h
application/gtk-text.c
application/gtk-text.h
application/window.c

index 045fb5d6538dff91dff9e37dc4ef8da0bb47d799..179d4ea19c11e404d20ea2cecaf8e2e3a1816e9a 100644 (file)
@@ -335,6 +335,7 @@ static void linearize_paragraph(CxBuffer *buf, CxList *sections, MDPara *p) {
     sec.pos = start_pos;
     sec.length = buf->pos - start_pos;
     sec.style = paragraph_style(p);
+    sec.link = NULL;
     cxListAdd(sections, &sec);
     
     cxBufferPut(buf, '\n');
index 3c1499bbe04b2ad74d59e48d56fb1d4deea779b4..15dc2ab91bb41844ff146a8093a0e0176b17975b 100644 (file)
@@ -111,7 +111,7 @@ MDDocLinear mddoc_linearization(MDDoc *doc);
 // platform specific implementation
 // (gtk-text.c)
 void editor_global_init();
-void editor_init_textview(UIWIDGET textview);
+void editor_init_textview(UiObject *obj, UIWIDGET textview);
 void editor_init_textbuf(UiText *text);
 void editor_apply_styles(UiText *text, CxList /* MDDocStyleSection */ *styles);
 cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a);
index ab7a4fb9ae2f8445ae6ff3135936a3fb6b1adc2a..e0b7f5c70a08174bd7cc0187eb223f02009b5c5f 100644 (file)
 
 static CxMap *markdown_tags;
 
+static void editor_button_released_cb(
+        GtkGestureClick *gesture,
+        guint n_press,
+        double x,
+        double y,
+        NoteEditor *editor);
+
 void editor_global_init() {
     markdown_tags = cxHashMapCreateSimple(sizeof(MDTag));
     
@@ -48,11 +55,70 @@ void editor_global_init() {
 }
 
 
-void editor_init_textview(UIWIDGET textview) {
+void editor_init_textview(UiObject *obj, UIWIDGET textview) {
     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD_CHAR);
+    gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textview), 16);
+    
+    NoteEditor *editor = malloc(sizeof(NoteEditor));
+    memset(editor, 0, sizeof(NoteEditor));
+    
+    editor->obj = obj;
+    editor->textview = textview;
+    
+    g_object_set_data(G_OBJECT(textview), "editor", editor);
+    
+    GtkEventController *controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
+    g_signal_connect(controller, "released", G_CALLBACK (editor_button_released_cb), editor);
+    gtk_widget_add_controller(textview, controller);
+}
+
+static void editor_button_released_cb(
+        GtkGestureClick *gesture,
+        guint n_press,
+        double x,
+        double y,
+        NoteEditor *editor)
+{
+    GtkTextView *textview = GTK_TEXT_VIEW(editor->textview);
+    if(gtk_gesture_single_get_current_button(GTK_GESTURE_SINGLE(gesture)) != 1) {
+        return;
+    }
+    
+    GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview);
+    
+    if(gtk_text_buffer_get_has_selection(buffer)) {
+        return;
+    }
     
+    int buffer_x, buffer_y;
+    gtk_text_view_window_to_buffer_coords(
+            textview,
+            GTK_TEXT_WINDOW_WIDGET,
+            x,
+            y,
+            &buffer_x,
+            &buffer_y);
+    
+    GtkTextIter pos;
+    if(gtk_text_view_get_iter_at_location(textview, &pos, buffer_x, buffer_y)) {
+        editor_try_follow_link(editor, &pos);
+    }
 }
 
+void editor_try_follow_link(NoteEditor *editor, GtkTextIter *pos) {
+    GSList *tags = gtk_text_iter_get_tags(pos);
+    while(tags) {
+        GtkTextTag *tag = tags->data;
+        TextLink *link = g_object_get_data(G_OBJECT(tag), "link");
+        if(link) {
+            printf("open link: %s\n", link->link);
+            break;
+        }
+        tags = tags->next;
+    }
+}
+
+
 void editor_init_textbuf(UiText *text) {
     // toolkit internals: data1 is a GtkTextBuffer, but it is only
     // initialized after UiText is bound to the textview
@@ -143,7 +209,9 @@ void editor_apply_styles(UiText *text, CxList /* MDDocStyleSection */ *styles) {
         }
         if(sec->link) {
             GtkTextTag *linktag = gtk_text_tag_new(NULL);
-            char *link = strdup(sec->link);
+            TextLink *link = malloc(sizeof(TextLink));
+            link->link = strdup(sec->link);
+            link->type = 0;
             g_object_set_data(G_OBJECT(linktag), "link", link);
             // TODO: destroy handler
             gtk_text_tag_table_add(tagtable, linktag);
@@ -184,10 +252,7 @@ static void map_subtract(CxMap *map, CxMap *sub) {
     }
 }
 
-cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a) {
-    char *str = ui_get(text);
-    
-    
+cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a) { 
     CxBuffer out;
     cxBufferInit(&out, NULL, 1024, a, CX_BUFFER_AUTO_EXTEND);
     
index f09d4db0e63faf26438eca9399a791b8882f0474..57e69a90ddaa9645f317f831e950bbee68a07569 100644 (file)
 extern "C" {
 #endif
     
+typedef struct NoteEditor {
+    UiObject *obj;
+    GtkWidget *textview;
+} NoteEditor;
+    
 typedef struct MDTag {
     const char *begin;
     const char *end;
 } MDTag;
 
+typedef struct TextLink {
+    char *link;
+    int type;
+} TextLink;
+
+void editor_try_follow_link(NoteEditor *editor, GtkTextIter *pos);
+
 void init_textbuf(GtkTextBuffer *buf);
 void init_tagtable(GtkTextTagTable *table);
 
index 64ca1188ac316019eeb80afb04e6a184286c11a8..fec346bed57e6fa36ce8772a7778084f6f4454b1 100644 (file)
@@ -30,6 +30,7 @@
 #include "application.h"
 #include "store.h"
 #include "notebook.h"
+#include "editor.h"
 
 #include <cx/array_list.h>
 #include <cx/hash_map.h>
@@ -83,6 +84,7 @@ void window_create() {
                         ui_button(obj, .icon = "insert-link");
                     }
                     wdata->textview = ui_textarea(obj, .varname = "note_text", .vfill = TRUE, .hfill = TRUE, .hexpand = TRUE, .vexpand = TRUE, .colspan = 2, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED), .fill = UI_ON);
+                    editor_init_textview(obj, ui_textarea_gettextwidget(wdata->textview));
                 } 
             }
         }