Skip to content

Commit 4eefc43

Browse files
einrobinRobin
and
Robin
authored
Add more pages (#29)
* Implement custom widgets page * Add custom setting types page * Change header format * Progress on the theme page * Fix indentation * Fix typo * Fix indentation in themes note --------- Co-authored-by: Robin <r.michalik@dev.asc.de>
1 parent 32b3fe9 commit 4eefc43

12 files changed

+374
-28
lines changed
Loading
Loading
Loading
Loading
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Create Your Own Widget
2+
3+
You cannot only use the Widgets we created, but you can also create your own ones.
4+
This small example will show you how to create your first Widget and add it to your Activity.
5+
The result of our little example will be a widget that displays a player's head to the left and a player's name.
6+
This Widget will be applied in a vertical list with multiple entries.
7+
8+
## Basics
9+
10+
First of all, every Widget is a subclass of `AbstractWidget`, you can also extend other widgets like
11+
for example the `ButtonWidget` or the `VerticalListWidget` to get some basic functionality. The `AutoWidget` annotation
12+
is necessary on every Widget.
13+
14+
### Generics
15+
16+
The generic type of the AbstractWidget (`AbstractWidget<...>`) defines the type of the children of this widget.
17+
If you want your widget to have children of only a specific type, you can define it here, otherwise just use `Widget`.
18+
In reality this is used for stuff like this:
19+
```java
20+
public class DropdownListWidget<T> extends VerticalListWidget<DropdownEntryWidget<T>> {}
21+
```
22+
23+
### User interaction / Custom rendering
24+
25+
=== ":octicons-file-code-16: ExampleWidget"
26+
```java
27+
@AutoWidget
28+
public class ExampleWidget extends AbstractWidget<Widget> {
29+
30+
@Override
31+
public void renderWidget(ScreenContext context) {
32+
if (this.isVisible()) {
33+
// optional: custom rendering
34+
}
35+
36+
super.renderWidget(context); // Render children
37+
}
38+
39+
@Override
40+
public boolean mouseClicked(MutableMouse mouse, MouseButton mouseButton) {
41+
// optional: handle mouse interactions
42+
return super.mouseClicked(mouse, mouseButton);
43+
}
44+
45+
@Override
46+
public boolean keyPressed(Key key, InputType type) {
47+
// optional: handle key press
48+
return super.keyPressed(key, type);
49+
}
50+
51+
/*
52+
There are more methods that you can override for user input like:
53+
- mouseDragged(...)
54+
- mouseScrolled(...)
55+
- mouseReleased(...)
56+
- keyReleased(...)
57+
- fileDropped(...) -> there may be limitations in older Minecraft versions, for file interactions you should always provide an optional file chooser (e.g. FileChooserWidget)
58+
*/
59+
}
60+
```
61+
62+
### Children / Custom style
63+
64+
Just like Activities, Widgets can also have children and styles. In your custom widget, you can add children in the initialize() method just like
65+
you can do it in the Activity.
66+
67+
=== ":octicons-file-code-16: UserListActivity"
68+
```java
69+
@AutoActivity
70+
@Link("user-list-activity.lss")
71+
public class UserListActivity extends SimpleActivity {
72+
73+
@Override
74+
public void initialize(Parent parent) {
75+
super.initialize(parent);
76+
77+
VerticalListWidget<UserWidget> users = new VerticalListWidget<>();
78+
users.addId("users");
79+
this.document().addChild(users);
80+
81+
users.addChild(new UserWidget("LabyMod"));
82+
users.addChild(new UserWidget("LabyStudio"));
83+
users.addChild(new UserWidget("LabyMarco"));
84+
85+
ButtonWidget addButton = ButtonWidget.text("Add User");
86+
addButton.setPressable(() -> {
87+
// addChildInitialized can be used to add children to a widget
88+
// after the initialize() method has already been called
89+
users.addChildInitialized(new UserWidget("Test"));
90+
91+
// Keep in mind that the VerticalListWidget users will get recreated when the Activity is being initialized again.
92+
// This means that for example when resizing the window all "Test" users will be removed again, you can
93+
// prevent this by saving the usernames in a separate list and adding to this list
94+
});
95+
addButton.addId("add-button");
96+
this.document().addChild(addButton);
97+
}
98+
}
99+
```
100+
101+
=== ":octicons-file-code-16: user-list-activity.lss"
102+
```css
103+
.users {
104+
left: 50%;
105+
alignment-x: center;
106+
top: 30;
107+
108+
width: fit-content;
109+
height: fit-content;
110+
111+
User {
112+
height: fit-content;
113+
}
114+
}
115+
116+
.add-button {
117+
left: 50%;
118+
alignment-x: center;
119+
top: 10;
120+
121+
width: 50;
122+
height: 20;
123+
}
124+
```
125+
126+
=== ":octicons-file-code-16: UserWidget"
127+
```java
128+
@AutoWidget
129+
@Link("user-widget.lss")
130+
public class UserWidget extends AbstractWidget<Widget> {
131+
132+
private final String username;
133+
134+
public UserWidget(String username) {
135+
this.username = username;
136+
}
137+
138+
@Override
139+
public void initialize(Parent parent) {
140+
super.initialize(parent);
141+
142+
IconWidget head = new IconWidget(Icon.head(this.username));
143+
head.addId("head");
144+
this.addChild(head);
145+
146+
ComponentWidget username = ComponentWidget.text(this.username);
147+
username.addId("username");
148+
this.addChild(username);
149+
}
150+
}
151+
```
152+
153+
=== ":octicons-file-code-16: user-widget.lss"
154+
```css
155+
.head {
156+
// align left
157+
left: 0;
158+
159+
// center vertically
160+
top: 50%;
161+
alignment-y: center;
162+
163+
width: 12;
164+
height: 12;
165+
}
166+
167+
.username {
168+
// align next to the head
169+
left: 14;
170+
171+
// center vertically
172+
top: 50%;
173+
alignment-y: center;
174+
175+
// width/height is set automatically for a ComponentWidget
176+
}
177+
```
178+
179+
=== ":octicons-file-media-24: Result"
180+
![Custom-Widget-Result](/assets/files/screenshots/lss-custom-widget-example.png)

docs/pages/addon/activities/lss.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ Like before, this is what the code we described above would look like:
7777
=== ":octicons-file-media-24: Result"
7878
![Config-Result](/assets/files/screenshots/lss-activity-example.png)
7979

80-
## Create Widgets With LSS
81-
82-
todo: write
8380

8481
## Injecting Blocks Into Other StyleSheets
8582

docs/pages/addon/activities/themes.md

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
One of the key advantages of our Activity System with LSS over OpenGL is that you can easily theme your Activities with LSS.
2-
With OpenGL you'd have to rewrite the screen for every theme you want to support.
1+
One of the key advantages of our Activity System with LSS over OpenGL is that you can easily theme your Activities with
2+
LSS.
3+
With OpenGL you'd have to rewrite the screen for every theme you want to support.
34
With LSS, just like with CSS, you can just have an LSS StyleSheet for each theme.
45
You can also create your own theme. All that is explained on this page.
56

@@ -8,4 +9,56 @@ You can also create your own theme. All that is explained on this page.
89

910
## How Themes Work
1011

11-
todo: write
12+
There are two types of themes:
13+
14+
- Root themes
15+
- Extending themes
16+
17+
### Root themes
18+
19+
Root themes have no parent, everything that is not implemented is not there. This means that in this type of theme
20+
everything needs to be implemented. Usually this is just the vanilla theme as this is maintained by LabyMod and
21+
implemented
22+
by every addon using the Activity System.
23+
24+
### Extending themes
25+
26+
Extending themes are themes based off of another theme, for example the LabyMod fancy theme extends the vanilla theme.
27+
Everything that is not implemented will be inherited from its parent theme. When creating your own theme, you may want
28+
to extend the vanilla theme, or you can also extend any other extending theme like the fancy theme.
29+
30+
If a resource (e.g. an LSS file, an image) or any kind of renderer is not found in an extending theme, it is
31+
simply taken from its parent.
32+
33+
## Theme files
34+
35+
Besides any other file in your `assets/<my namespace>` folder there are also theme files located
36+
in `assets/<my namespace>/themes/<theme>` with the following structure:
37+
38+
![Theme-File-Tree](/assets/files/screenshots/theme-file-structure.png)
39+
40+
Usually you don't need to access these files directly because LabyMod handles it for stuff like LSS stylesheets,
41+
icons in the settings and hud widgets. If you still need to access a ThemeFile, it works like this:
42+
43+
```java
44+
public ResourceLocation getThemeResource() {
45+
Theme theme = Laby.references().themeService().currentTheme();
46+
return theme.resource("my namespace", "textures/my-image.png");
47+
}
48+
```
49+
50+
## Implement an existing theme in your addon
51+
52+
Coming from [Understand LSS](/pages/addon/activities/lss) you already know how to create LSS stylesheets for the
53+
vanilla theme by putting them in `assets/example/themes/vanilla/lss/`. When implementing the fancy theme, you now want
54+
to put your new LSS stylesheets in `assets/example/themes/fancy/lss/` and name them exactly the same.
55+
56+
Having done this, LabyMod will now select the LSS stylesheets from the fancy theme. If a stylesheet doesn't exist in
57+
the fancy theme, LabyMod will fall back to the stylesheet from the vanilla theme. The behavior is exactly the same for
58+
textures, you may have defined your textures for your settings in `assets/example/themes/vanilla/textures/settings.png`,
59+
now you can create a file with the same name in the directory for the fancy theme and LabyMod will find it
60+
automatically.
61+
62+
### Theme your activity
63+
64+
todo: add an example Activity

docs/pages/addon/activities/widgets.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,6 @@ Like with the bare Activity, this is what the code we described above would look
5858
=== ":octicons-file-media-24: Result"
5959
![Config-Result](/assets/files/screenshots/widget-activity-example.png)
6060

61-
## Create Your Own Widget
62-
63-
You cannot only use the Widgets we created, but you can also create your own ones.
64-
This small example will show you how to create your first Widget and add it to your Activity.
65-
The result of our little example will be a widget that displays a player's head to the left and a player's name.
66-
This Widget will be applied in a vertical list with multiple entries.
67-
68-
!!! warning "Important Note"
69-
70-
As it would be too complex to explain how to create a Widget without LSS, as of now you can only find an explanation on how to create Widgets <a href="/pages/addon/activities/lss/#create-widgets-with-lss">here</a>.
71-
7261
## All Widgets
7362

7463
Below listed are all Widgets for use. They can be extended and modified for a more specific use case. <br>

docs/pages/addon/features/config.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -294,13 +294,3 @@ public class ConfigVersionListener {
294294
}
295295
}
296296
```
297-
298-
## Create Custom Settings
299-
300-
### Register Your Own Setting Type
301-
302-
todo: write, check chattime
303-
304-
### Create Custom Setting Widgets
305-
306-
todo: write, check chattime

0 commit comments

Comments
 (0)