fltkhs
fltkhs copied to clipboard
Modal issues
I'm having trouble figuring out how to do a modal window from scratch. I think there's at least one API issue, but even with that, it's not working.
First, FL.modal should be returning Ref WindowBase, not Ref Widget. That's an easy fix. But then when I call it and compare it to my modal window, I get a different pointer back. Am I missing something obvious, and/or is there a more straightforward way to do this than whileM_?
Here's my test code:
showTextEditor :: Text -> IO (Maybe Text)
showTextEditor t = do
curActive <- FL.modal
putStrLn $ show ("curActive is ", curActive)
let size = toSize (300, 200)
-- TODO: Just Position.
win <- doubleWindowNew size Nothing (Just "Title")
setModal win
buff <- textBufferNew Nothing Nothing
edit <- textEditorNew (toRectangle (20,20,(300-40),(200-40))) Nothing
setBuffer edit (Just buff)
setText buff t
showWidget win
let showing = do
active <- FL.modal
putStrLn $ show ("showing; active is ", active)
putStrLn $ show ("showing; win is ", win)
case active of
Nothing -> return False
Just w -> return $ w == (safeCast win)
putStrLn "Showing"
whileM_ showing (void FL.wait)
t' <- getText buff
putStrLn "Done"
return $ Just t'
Output:
("curActive is ",Nothing)
Showing
("showing; active is ",Just (Ref 0x00007fa9d0232b30))
("showing; win is ",Ref 0x00007fa9d0204f40)
Done
I think you're right and there's an issue with modal
, when I did it I used shown
and yes I believe looping on FL.wait
is currently the best way. And you're right that making modals should be much easier.
Aha! I was looking for shown first and couldn't find it. That's what I used in my old C++ app that I've been replacing. That works fine. Still have to figure out how to detect OK/Cancel without using an IORef.
I'm making a bunch of modal editors for various attributes, some of which may be complex enough to need runtime generation, which is why I'm not using Fluid. Plus I'd like to avoid C++ entirely.
Ah, looking at your code, I see you just use an IORef. So I'll just do that. Thanks!
Incidentally, regarding the pointer mismatches, I recall having similar problems when using FLTK with C++ years ago [my bugs, not theirs]. I hit problems due to multiple inheritance and using the wrong order of casts, such that I'd get a slightly wrong pointer, since it got confused about base class offsets. I don't understand out safeCast works. I doubt that's the problem here since the two pointers are so far apart, but I thought I'd mention it just in case.
I'm not sure how much making-modals-easier you want to build into the library, and how much you want to remain a thin wrapper around FLTK. But you can always supply sample code. Here's what I'm playing around with to cut down on repetition:
showModal widget getValue = do
Width widgetW <- getW widget
Height widgetH <- getH widget
ref <- newIORef Nothing
let buttonW = 80
buttonH = 35
borderPadX = 4
borderPadY = 4
buttonPadX = 2 * borderPadX + (widgetW - 2 * buttonW) `div` 3
buttonPadY = 4
widgetX = borderPadX
widgetY = borderPadY
windowW = widgetW + 2 * borderPadX
windowH = widgetH + buttonH + borderPadY + 2 * buttonPadY
size = toSize (windowW, windowH)
-- TODO: Just Position.
window <- doubleWindowNew size Nothing (Just "Edit Comment")
setModal window
cancel <- buttonNew (toRectangle (buttonPadX,
widgetY + widgetH + buttonPadY,
buttonW, buttonH)) (Just "Cancel")
let cancelCallback _ = hide window
setCallback cancel cancelCallback
ok <- buttonNew (toRectangle (2 * buttonPadX + buttonW,
widgetY + widgetH + buttonPadY,
buttonW, buttonH)) (Just "OK")
let okCallback _ = do
v <- getValue widget
writeIORef ref $ Just v
hide window
setCallback ok okCallback
addResizable window widget
resize widget $ toRectangle (widgetX, widgetY, widgetW, widgetH)
showWidget window
whileM_ (shown window) (void FL.wait)
readIORef ref
showTextEditor :: Text -> IO (Maybe Text)
showTextEditor t = do
let editorW = 300
editorH = 400
buff <- textBufferNew Nothing Nothing
edit <- textEditorNew (toRectangle (0, 0, editorW, editorH)) Nothing
setBuffer edit (Just buff)
setText buff t
showModal (safeCast edit) (\_ -> getText buff)
I fixed the issue with modal
.
If this fix mentioned above works could you close this issue?
The compilation issue is fixed; the pointer mismatch remains. It's not stopping me from working--I coded it around it as above. But FL.modal isn't returning what it's supposed to.