simonkrauter / NiGui

Cross-platform desktop GUI toolkit written in Nim
MIT License
724 stars 49 forks source link

Win10 - TextArea newline character error #76

Closed WilliamDraco closed 4 years ago

WilliamDraco commented 4 years ago
import nigui

app.init()

var window = newWindow("test")
var cPrime = newLayoutContainer(Layout_Horizontal)
var textarea = newTextArea()

window.add(cPrime)
cPrime.add(textarea)
textarea.text = "This code has\nnewline characters \nbut doesn't work"

window.show()
app.run()

On Win10, the resultant text area is:

This code hasnewline charactersbut doesn't work

Due to the windows newline requiring \r\n (or \p) to achieve.

In my usecase, user types multi-line text into textarea. I save the textarea.text to file, and when saved this way it saves with only the \n escape characters. When textarea.text is then populated on loading the same file, the single-line version appears per above.

Recommended to have textarea.text receive enter/return presses as a \p escape character instead of \n

simonkrauter commented 4 years ago

@WilliamDraco The handling of line break characters is done by Windows. When I press return in a text area and read the text, I get a Windows line break (\p). If you have a string with only \n like in the example, then you have to convert it. I see no problem here.

WilliamDraco commented 4 years ago

Sorry for the lazy initial example. Here's a better example that might bring certainty:

import parsecfg
import nigui

app.init()

var window = newWindow("test")
var cPrime = newLayoutContainer(Layout_Horizontal)
var loadButton = newButton("Load")
var saveButton = newButton("Save")
var textarea = newTextArea()

window.add(cPrime)
cPrime.add(loadButton)
cPrime.add(saveButton)
cPrime.add(textarea)

loadButton.onClick = proc(event:ClickEvent) =
  var cfg:Config
  try:
    cfg = loadConfig("test.cfg")
    textarea.text = cfg.getSectionvalue("Testing", "TextAreaText")
  except:
    return

saveButton.onClick = proc(event:ClickEvent) =
  var cfg: Config
  try:
    cfg = loadConfig("test.cfg")
  except:
    cfg = newConfig()

  cfg.setSectionkey("Testing", "TextAreaText", textarea.text)
  cfg.writeConfig("test.cfg")

window.show()
app.run()

If you type a text into the textarea, including at least one return/enter/newline, then hit the save button, then the load button - all new lines are removed. Reviewing the test.cfg file written shows that only a \n character was written to file.

simonkrauter commented 4 years ago

I've added the helper proc convertLineBreaks to make line break compatible for Windows, see https://github.com/trustable-code/NiGui/commit/edcdbe648f2b795905832228b08df506fcd31847. I think it's better to not call this proc inside from NiGui every time the text of a text area is changed, because of the additional runtime costs. Instead the application has to call convertLineBreaks when it uses a text with potentially wrong line breaks. For the given example, this means to change the line to:

textarea.text = cfg.getSectionvalue("Testing", "TextAreaText").convertLineBreaks

A related question is, why the line breaks stored not exactly by parsecfg. I will have a look on that. See https://github.com/nim-lang/Nim/issues/12970