Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal issues #142

Open
ericu opened this issue Jul 13, 2019 · 6 comments
Open

Modal issues #142

ericu opened this issue Jul 13, 2019 · 6 comments

Comments

@ericu
Copy link
Contributor

ericu commented Jul 13, 2019

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
@deech
Copy link
Owner

deech commented Jul 13, 2019

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.

@ericu
Copy link
Contributor Author

ericu commented Jul 13, 2019

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.

@ericu
Copy link
Contributor Author

ericu commented Jul 14, 2019

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)

@deech
Copy link
Owner

deech commented Jul 18, 2019

I fixed the issue with modal.

@deech
Copy link
Owner

deech commented Jul 30, 2019

If this fix mentioned above works could you close this issue?

@ericu
Copy link
Contributor Author

ericu commented Jul 31, 2019

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants