Update offsetsGtk.hs
This commit is contained in:
parent
4db33bda54
commit
7d284d8dcd
1 changed files with 46 additions and 24 deletions
|
|
@ -1,6 +1,15 @@
|
|||
{-# LANGUAGE OverloadedLabels #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
{-
|
||||
|
||||
this is a prototype of a hakurei-like tokenizer, where the sentence is clickable.
|
||||
the function must accept a list of strings, because xcdat works that way.
|
||||
also, you must FIX the current problem of just getting what's next to the cursor
|
||||
|
||||
-}
|
||||
|
||||
|
||||
module Main where
|
||||
|
||||
import qualified GI.Gtk as Gtk
|
||||
|
|
@ -9,53 +18,66 @@ import qualified Data.Text as T
|
|||
import Data.Text (Text)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Control.Monad (void)
|
||||
import Data.Int (Int32)
|
||||
|
||||
-- | 'getWordAtOffset' takes a list of words and an offset (index)
|
||||
-- and returns the word at that offset if it exists.
|
||||
getWordAtOffset :: [Text] -> Int -> Maybe Text
|
||||
getWordAtOffset wordsList offset =
|
||||
if offset >= 0 && offset < length wordsList
|
||||
then Just (wordsList !! offset)
|
||||
else Nothing
|
||||
-- | Given a list of tokens and a character offset (into the concatenated text),
|
||||
-- 'findTokenAtOffset' returns the index and token that covers that offset.
|
||||
findTokenAtOffset :: [Text] -> Int -> Maybe (Int, Text)
|
||||
findTokenAtOffset tokens offset = go tokens 0 0
|
||||
where
|
||||
go [] _ _ = Nothing
|
||||
go (t:ts) idx start =
|
||||
let tokenLength = T.length t
|
||||
in if offset < start + tokenLength
|
||||
then Just (idx, t)
|
||||
else go ts (idx + 1) (start + tokenLength)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
-- Create a new GTK application with a unique application ID.
|
||||
app <- Gtk.applicationNew (Just "com.example.HaskellGiExample") []
|
||||
|
||||
-- Connect to the application's "activate" signal.
|
||||
void $ Gio.onApplicationActivate app $ do
|
||||
-- Create an application window (GTK 4 style).
|
||||
window <- Gtk.applicationWindowNew app
|
||||
|
||||
-- Create a text view widget.
|
||||
window <- Gtk.applicationWindowNew app
|
||||
textView <- Gtk.textViewNew
|
||||
|
||||
-- Define some sample text.
|
||||
let sampleText = "Haskell GI makes GUI programming and text processing elegant"
|
||||
-- Assume these are the tokens from a tokenizer.
|
||||
let tokens = ["これ", "は", "日本語", "の", "文章", "です"]
|
||||
sampleText = T.concat tokens -- Concatenate tokens without spaces.
|
||||
|
||||
-- Set the sample text in the text view's buffer.
|
||||
buffer <- Gtk.textViewGetBuffer textView
|
||||
Gtk.textBufferSetText buffer sampleText (-1)
|
||||
|
||||
-- Process the text: split into words and retrieve the word at a given offset.
|
||||
let wordsList = T.words sampleText
|
||||
offset = 3 -- For example, get the 4th word (zero-indexed)
|
||||
wordAtOffset = fromMaybe "No word found" (getWordAtOffset wordsList offset)
|
||||
-- Add a click gesture to the text view.
|
||||
gesture <- Gtk.gestureClickNew
|
||||
Gtk.widgetAddController textView gesture
|
||||
|
||||
putStrLn $ "The word at offset " ++ show offset ++ " is: " ++ T.unpack wordAtOffset
|
||||
-- When the user clicks, get the text iterator at that location.
|
||||
void $ Gtk.onGestureClickPressed gesture $ \_ x y -> do
|
||||
-- Convert the x and y coordinates (Double) to Int32 as required.
|
||||
let ix = fromIntegral (round x) :: Int32
|
||||
iy = fromIntegral (round y) :: Int32
|
||||
(success, iter) <- Gtk.textViewGetIterAtLocation textView ix iy
|
||||
if success
|
||||
then do
|
||||
offset32 <- Gtk.textIterGetOffset iter
|
||||
let offset = fromIntegral offset32 :: Int
|
||||
tokenInfo = findTokenAtOffset tokens offset
|
||||
case tokenInfo of
|
||||
Just (i, token) ->
|
||||
putStrLn $ "Clicked token " ++ show i ++ ": " ++ T.unpack token
|
||||
Nothing ->
|
||||
putStrLn "Clicked outside any token."
|
||||
else putStrLn "Could not determine text position."
|
||||
|
||||
-- Set the text view as the sole child of the window (wrap in Just).
|
||||
-- Set the text view as the sole child of the window.
|
||||
Gtk.windowSetChild window (Just textView)
|
||||
|
||||
-- Connect the window's close-request signal to quit the application.
|
||||
void $ Gtk.on window #closeRequest $ do
|
||||
Gio.applicationQuit app
|
||||
return False
|
||||
|
||||
-- Show the window.
|
||||
Gtk.widgetShow window
|
||||
|
||||
-- Run the application (which handles initialization and the main loop).
|
||||
_ <- Gio.applicationRun app Nothing
|
||||
return ()
|
||||
|
|
|
|||
Loading…
Reference in a new issue