-
Hi, just wondering, but would you have an example with a form + layout? I'm looking for something like this, and I'm not sure if there's a formlayout or tablelayout which I could use for this? |
Beta Was this translation helpful? Give feedback.
Replies: 27 comments 1 reply
-
At the moment, I'm actually struggling to even add a button or a label to a view. I see a lot of examples with the render method, but how do I do something like:
|
Beta Was this translation helpful? Give feedback.
-
So the // or, object: View() { ... }, etc.
display += container {
size = display.size
children += Label("my text")
children += Button("my buttton")
} |
Beta Was this translation helpful? Give feedback.
-
This is achievable using a val someContainer: Container // or a View that exposes Layout, or the Display
container.layout = constrain(child1, ... childN) { child1, ... childN ->
child1.left = parent.left + 10
...
} This gives fine grained control over relative positions for items that all share the same parent. https://nacular.github.io/doodle/#/positioning You can also use a |
Beta Was this translation helpful? Give feedback.
-
Hi @pusolito ,thanks for the examples, but neither one works for me. I'm perfectly sure the issue on my end, but If I try the example using the When I try a new instance of a View (I created a subclass) the code compiles, but doesn't show anything:
What am I missing here? |
Beta Was this translation helpful? Give feedback.
-
I've attempted another one, based on the Calculator example, but also this one renders an empty screen: https://gist.github.com/bodiam/053e81f93b36e5b69e7e6200c7988503 |
Beta Was this translation helpful? Give feedback.
-
The issue with += for display is an IDE one. It doesn't auto import that method from the Display file for some reason. Just import plusAssign yourself. Then, things aren't showing because both Label and PushButton need a You can use a Theme that includes items for each: https://nacular.github.io/doodle/#/themes. The BasicTheme has modules for both. Or you can install them directly to each via the The Todo tutorial also uses themes: https://github.com/nacular/doodle-tutorials/tree/master/Todo/src/jsMain/kotlin/io.nacular.doodle.examples/FullScreen.kt. Calculator uses Behaviors directly : https://github.com/nacular/doodle-tutorials/blob/647ba646dea65d9637f534aa0a2abea7859255a9/Calculator/src/commonMain/kotlin/io/nacular/doodle/examples/Calculator.kt#L248. |
Beta Was this translation helpful? Give feedback.
-
Be sure to set a bounds (or place it in a parent with a Layout that does) for the button. Label has a |
Beta Was this translation helpful? Give feedback.
-
Thanks! I'll try it out later today. Thanks for your support! |
Beta Was this translation helpful? Give feedback.
-
Are you sure about that one? The If I do the following, it compiles:
If I inline it, it doesn't (probably because What am I missing here? |
Beta Was this translation helpful? Give feedback.
-
Container is a View though: https://github.com/nacular/doodle/blob/master/Core/src/commonMain/kotlin/io/nacular/doodle/core/Container.kt. Will have to investigate this more when at my computer later during the week. At any rate, you can use display.children directly as well. |
Beta Was this translation helpful? Give feedback.
-
Hmm, good point. I'll do some more investigation myself, I'll let you know how I go. Btw, I'm sorry for the amount of questions I have, but I appreciate your support! |
Beta Was this translation helpful? Give feedback.
-
Ah, I think I've seen this a few times and it's an ambiguous resolution issue. This is a total hack, and should actually be filed as a bug with Jetbrains if it is the case. |
Beta Was this translation helpful? Give feedback.
-
Not at all. This kind of feedback is very helpful. It helps me see gaps that I overlooked, and things needed to support real projects. |
Beta Was this translation helpful? Give feedback.
-
@pusolito I've tried the hack, but IntelliJ doesn't seem to like it. I mean, with This will probably go against your design, but wouldn't it be an option to have Container not be both a |
Beta Was this translation helpful? Give feedback.
-
Interesting. Let me follow up on this to see what makes sense. |
Beta Was this translation helpful? Give feedback.
-
I've tried again to get my HelloWorld working, but again I'm running into issues. This time I'm getting:
This is my code:
|
Beta Was this translation helpful? Give feedback.
-
I've tried using one of your examples from here: https://nacular.github.io/doodle/#/themes This one:
But besides missing the shutdown method, the listOf(NativeTheme) also doesn't work. Not sure how to fix. |
Beta Was this translation helpful? Give feedback.
-
In short, so far still not able to display a Label and a Button on the screen. |
Beta Was this translation helpful? Give feedback.
-
Ok, the docs need more love to be updated. The example doesn't show the basicLabelBehavior() . This function loads the BasicLabelBehavior via a module.
|
Beta Was this translation helpful? Give feedback.
-
What do you mean with that? I've got the import for NativeTheme (see for an example here: https://gist.github.com/bodiam/1cfadca819a16f352ca5588c3008ade1), it just doesn't like the import.
I had a look at the TodoApp before (I had a look at all the examples), but that example injects the behaviour of every component separately, and I have a bit of a hard time understanding why I'd want to do that if injecting a Theme is also an option. |
Beta Was this translation helpful? Give feedback.
-
That's example the import I've used in my example here: https://gist.github.com/bodiam/1cfadca819a16f352ca5588c3008ade1, which is the one causing the issue. |
Beta Was this translation helpful? Give feedback.
-
Code size (JS) was the reason I moved towards individually selecting the behaviors this way. You'll see the NativeTheme has a function that installs everything: . Unfortunately it is missing a preconfigured one for Label. But BasicTheme has one: . |
Beta Was this translation helpful? Give feedback.
-
@pusolito Thanks, but I'm getting a bit lost now. I've tried another variation, which also doesn't work, now with the nativeThemeBehaviors:
It would really help me if there was an example which would display a label and a button. It seems beyond my skill at this moment to accomplish this, and I'm feeling that this conversation is bringing me further away from a solution than closer. |
Beta Was this translation helpful? Give feedback.
-
I'll write an example when back from holiday on Wed morning. Here's an example from a private repo: import Demo.Companion.demoAppModules
import io.nacular.doodle.application.Application
import io.nacular.doodle.application.Modules.Companion.FontModule
import io.nacular.doodle.application.application
import io.nacular.doodle.controls.buttons.CheckBox
import io.nacular.doodle.controls.text.Label
import io.nacular.doodle.controls.text.TextFit
import io.nacular.doodle.drawing.Color
import io.nacular.doodle.drawing.FontLoader
import io.nacular.doodle.geometry.Size
import io.nacular.doodle.theme.ThemeManager
import io.nacular.doodle.theme.adhoc.DynamicTheme
import io.nacular.doodle.theme.basic.BasicTheme.Companion.basicCheckBoxBehavior
import io.nacular.doodle.theme.basic.BasicTheme.Companion.basicLabelBehavior
import io.nacular.doodle.utils.Resizer
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.kodein.di.instance
import org.w3c.dom.HTMLElement
class LabelDemo(fonts: FontLoader, themeManager: ThemeManager, theme: DynamicTheme, demo: Demo): Application {
init {
GlobalScope.launch {
val font = fonts {
family = DEFAULT_FONT_FAMILY
size = DEFAULT_FONT_SIZE
}
themeManager.selected = theme
val label = Label("Some Text").apply {
this.font = font
size = Size(200, 40)
Resizer(this).apply { movable = false }
}
demo(label, ControlDrawer().apply {
val background = CheckBox("Background").apply {
size = Size(16)
selectedChanged += { _,_,selected ->
label.backgroundColor = when {
selected -> Color.Lightgray
else -> null
}
}
}
val fitText = CheckBox("Fit Text").apply {
selected = label.fitText.isNotEmpty()
size = Size(16)
selectedChanged += { _,_,selected ->
label.fitText = when {
selected -> setOf(TextFit.Width, TextFit.Height)
else -> emptySet()
}
}
}
children += listOf(background, fitText)
})
}
}
override fun shutdown() {}
companion object {
private val appModules = demoAppModules + listOf(basicLabelBehavior(), basicCheckBoxBehavior(), FontModule)
operator fun invoke(root: HTMLElement) = application(root, modules = appModules) {
LabelDemo(instance(), instance(), instance(), instance())
}
}
} This file imports some other stuff, but you can ignore that and see how it pulls in just the behaviors it needs at the end with the invoke method it exposes. This code is from the Label demo in the docs. It is used as part of an external class that creates this app using LabelDemo.invoke(...). |
Beta Was this translation helpful? Give feedback.
-
I'm sorry, I had no idea you were on a holiday. This isn't that urgent at all, but thank you for providing this example, I will try it out! Appreciate it! |
Beta Was this translation helpful? Give feedback.
-
Now we're getting somewhere: import io.nacular.doodle.application.Application
import io.nacular.doodle.application.Modules.Companion.FontModule
import io.nacular.doodle.application.application
import io.nacular.doodle.controls.buttons.PushButton
import io.nacular.doodle.controls.panels.GridPanel
import io.nacular.doodle.controls.text.Label
import io.nacular.doodle.core.*
import io.nacular.doodle.drawing.FontLoader
import io.nacular.doodle.geometry.Size
import io.nacular.doodle.layout.constrain
import io.nacular.doodle.theme.ThemeManager
import io.nacular.doodle.theme.adhoc.DynamicTheme
import io.nacular.doodle.theme.basic.BasicTheme.Companion.basicButtonBehavior
import io.nacular.doodle.theme.basic.BasicTheme.Companion.basicLabelBehavior
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.kodein.di.instance
class GridPanelLabelDemo(
display: Display,
fonts: FontLoader,
themeManager: ThemeManager,
theme: DynamicTheme
) : Application {
init {
GlobalScope.launch {
val font = fonts {
family = "Arial"
size = 20
}
themeManager.selected = theme
val label = Label("Some Text").apply {
this.font = font
size = Size(300, 40)
}
val button = PushButton("Some Button").apply {
this.font = font
size = Size(200, 40)
fired += {
println("Hey! That Hurt!")
}
}
val views: Iterable<View> = listOf(label, button)
val buttonSpacing = 10.0
val outputHeight = 100.0
val gridPanel = GridPanel().apply {
add(label, 0, 0);
add(button, 1, 0);
verticalSpacing = { buttonSpacing }
horizontalSpacing = { buttonSpacing }
}
display += listOf(gridPanel)
// Place output outside grid so the height can be more easily controlled
val constraints = constrain(gridPanel) { grid ->
grid.top = parent.bottom + buttonSpacing
grid.left = parent.left
grid.right = parent.right
grid.bottom = parent.bottom
}
display += views
display.layout = object: Layout by constraints {
// Set total height to grid panel's ideal width and height, plus output and spacing
override fun idealSize(container: PositionableContainer, default: Size?) = gridPanel.idealSize?.let {
Size(it.width, it.height + outputHeight + buttonSpacing)
}
}
}
}
override fun shutdown() {}
}
fun main() {
val appModules = listOf(basicLabelBehavior(), basicButtonBehavior(), FontModule)
application(modules = appModules) {
GridPanelLabelDemo(instance(), instance(), instance(), instance())
}
} Current issues however:
Any tips? |
Beta Was this translation helpful? Give feedback.
-
The latest release brings proper support for forms. This should cover your use case. |
Beta Was this translation helpful? Give feedback.
The latest release brings proper support for forms. This should cover your use case.