clay/examples/playdate-project-example/clay-video-demo-playdate.c

345 lines
16 KiB
C

// This is the video demo with some adjustments so it works on the playdate
// console The playdate screen is only 400x240 pixels and it can only display
// black and white, so some fixed sizes and colours needed tweaking! The file
// menu was also removed as it does not really make sense when there is no
// pointer
//
// Note: The playdate console also does not support dynamic font sizes - fonts must be
// created at a specific size with the pdc tool - so any font size set in the clay layout
// will have noe ffect.
#include "../../clay.h"
#include <stdlib.h>
const int FONT_ID_BODY = 0;
const int FONT_ID_BUTTON = 1;
Clay_Color COLOR_WHITE = { 255, 255, 255, 255 };
Clay_Color COLOR_BLACK = { 0, 0, 0, 255 };
void RenderHeaderButton(Clay_String text) {
CLAY({
.layout = { .padding = { 8, 8, 4, 4 } },
.backgroundColor = COLOR_BLACK,
.cornerRadius = CLAY_CORNER_RADIUS(4)
}) {
CLAY_TEXT(
text,
CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BUTTON, .textColor = COLOR_WHITE })
);
}
}
typedef struct {
Clay_String title;
Clay_String contents;
} Document;
typedef struct {
Document *documents;
uint32_t length;
} DocumentArray;
#define MAX_DOCUMENTS 3
Document documentsRaw[MAX_DOCUMENTS];
DocumentArray documents = { .length = MAX_DOCUMENTS, .documents = documentsRaw };
void ClayVideoDemo_Initialize(void) {
documents.documents[0] = (Document){
.title = CLAY_STRING("Squirrels"),
.contents = CLAY_STRING(
"The Secret Life of Squirrels: Nature's Clever Acrobats\n"
"Squirrels are often overlooked creatures, dismissed as mere park "
"inhabitants or backyard nuisances. Yet, beneath their fluffy tails "
"and twitching noses lies an intricate world of cunning, agility, "
"and survival tactics that are nothing short of fascinating. As one "
"of the most common mammals in North America, squirrels have adapted "
"to a wide range of environments from bustling urban centers to "
"tranquil forests and have developed a variety of unique behaviors "
"that continue to intrigue scientists and nature enthusiasts alike.\n"
"\n"
"Master Tree Climbers\n"
"At the heart of a squirrel's skill set is its impressive ability to "
"navigate trees with ease. Whether they're darting from branch to "
"branch or leaping across wide gaps, squirrels possess an innate "
"talent for acrobatics. Their powerful hind legs, which are longer "
"than their front legs, give them remarkable jumping power. With a "
"tail that acts as a counterbalance, squirrels can leap distances of "
"up to ten times the length of their body, making them some of the "
"best aerial acrobats in the animal kingdom.\n"
"But it's not just their agility that makes them exceptional "
"climbers. Squirrels' sharp, curved claws allow them to grip tree "
"bark with precision, while the soft pads on their feet provide "
"traction on slippery surfaces. Their ability to run at high speeds "
"and scale vertical trunks with ease is a testament to the "
"evolutionary adaptations that have made them so successful in their "
"arboreal habitats.\n"
"\n"
"Food Hoarders Extraordinaire\n"
"Squirrels are often seen frantically gathering nuts, seeds, and "
"even fungi in preparation for winter. While this behavior may seem "
"like instinctual hoarding, it is actually a survival strategy that "
"has been honed over millions of years. Known as \"scatter "
"hoarding,\" squirrels store their food in a variety of hidden "
"locations, often burying it deep in the soil or stashing it in "
"hollowed-out tree trunks.\n"
"Interestingly, squirrels have an incredible memory for the "
"locations of their caches. Research has shown that they can "
"remember thousands of hiding spots, often returning to them months "
"later when food is scarce. However, they don't always recover every "
"stash some forgotten caches eventually sprout into new trees, "
"contributing to forest regeneration. This unintentional role as "
"forest gardeners highlights the ecological importance of squirrels "
"in their ecosystems.\n"
"\n"
"The Great Squirrel Debate: Urban vs. Wild\n"
"While squirrels are most commonly associated with rural or wooded "
"areas, their adaptability has allowed them to thrive in urban "
"environments as well. In cities, squirrels have become adept at "
"finding food sources in places like parks, streets, and even "
"garbage cans. However, their urban counterparts face unique "
"challenges, including traffic, predators, and the lack of natural "
"shelters. Despite these obstacles, squirrels in urban areas are "
"often observed using human infrastructure such as buildings, "
"bridges, and power lines as highways for their acrobatic "
"escapades.\n"
"There is, however, a growing concern regarding the impact of urban "
"life on squirrel populations. Pollution, deforestation, and the "
"loss of natural habitats are making it more difficult for squirrels "
"to find adequate food and shelter. As a result, conservationists "
"are focusing on creating squirrel-friendly spaces within cities, "
"with the goal of ensuring these resourceful creatures continue to "
"thrive in both rural and urban landscapes.\n"
"\n"
"A Symbol of Resilience\n"
"In many cultures, squirrels are symbols of resourcefulness, "
"adaptability, and preparation. Their ability to thrive in a variety "
"of environments while navigating challenges with agility and grace "
"serves as a reminder of the resilience inherent in nature. Whether "
"you encounter them in a quiet forest, a city park, or your own "
"backyard, squirrels are creatures that never fail to amaze with "
"their endless energy and ingenuity.\n"
"In the end, squirrels may be small, but they are mighty in their "
"ability to survive and thrive in a world that is constantly "
"changing. So next time you spot one hopping across a branch or "
"darting across your lawn, take a moment to appreciate the "
"remarkable acrobat at work a true marvel of the natural world.\n"
)
};
documents.documents[1] = (Document){
.title = CLAY_STRING("Lorem Ipsum"),
.contents = CLAY_STRING(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim "
"ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
"aliquip ex ea commodo consequat. Duis aute irure dolor in "
"reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
"pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
"culpa qui officia deserunt mollit anim id est laborum."
)
};
documents.documents[2] = (Document){
.title = CLAY_STRING("Vacuum Instructions"),
.contents = CLAY_STRING(
"Chapter 3: Getting Started - Unpacking and Setup\n"
"\n"
"Congratulations on your new SuperClean Pro 5000 vacuum cleaner! In "
"this section, we will guide you through the simple steps to get "
"your vacuum up and running. Before you begin, please ensure that "
"you have all the components listed in the \"Package Contents\" "
"section on page 2.\n"
"\n"
"1. Unboxing Your Vacuum\n"
"Carefully remove the vacuum cleaner from the box. Avoid using sharp "
"objects that could damage the product. Once removed, place the unit "
"on a flat, stable surface to proceed with the setup. Inside the "
"box, you should find:\n"
"\n"
" The main vacuum unit\n"
" A telescoping extension wand\n"
" A set of specialized cleaning tools (crevice tool, upholstery "
"brush, etc.)\n"
" A reusable dust bag (if applicable)\n"
" A power cord with a 3-prong plug\n"
" A set of quick-start instructions\n"
"\n"
"2. Assembling Your Vacuum\n"
"Begin by attaching the extension wand to the main body of the "
"vacuum cleaner. Line up the connectors and twist the wand into "
"place until you hear a click. Next, select the desired cleaning "
"tool and firmly attach it to the wand's end, ensuring it is "
"securely locked in.\n"
"\n"
"For models that require a dust bag, slide the bag into the "
"compartment at the back of the vacuum, making sure it is properly "
"aligned with the internal mechanism. If your vacuum uses a bagless "
"system, ensure the dust container is correctly seated and locked in "
"place before use.\n"
"\n"
"3. Powering On\n"
"To start the vacuum, plug the power cord into a grounded electrical "
"outlet. Once plugged in, locate the power switch, usually "
"positioned on the side of the handle or body of the unit, depending "
"on your model. Press the switch to the \"On\" position, and you "
"should hear the motor begin to hum. If the vacuum does not power "
"on, check that the power cord is securely plugged in, and ensure "
"there are no blockages in the power switch.\n"
"\n"
"Note: Before first use, ensure that the vacuum filter (if your "
"model has one) is properly installed. If unsure, refer to \"Section "
"5: Maintenance\" for filter installation instructions."
)
};
}
Clay_RenderCommandArray ClayVideoDemo_CreateLayout(int selectedDocumentIndex) {
Clay_BeginLayout();
Clay_Sizing layoutExpand = {
.width = CLAY_SIZING_GROW(0),
.height = CLAY_SIZING_GROW(0)
};
Clay_BorderElementConfig contentBorders = {
.color = COLOR_BLACK,
.width = { .top = 1, .left = 1, .right = 1, .bottom = 1 }
};
// Build UI here
CLAY({
.id = CLAY_ID("OuterContainer"),
.backgroundColor = COLOR_WHITE,
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.sizing = layoutExpand,
.padding = CLAY_PADDING_ALL(8),
.childGap = 4
}
}) {
// Child elements go inside braces
CLAY({
.id = CLAY_ID("HeaderBar"),
.layout = {
.sizing = {
.height = CLAY_SIZING_FIXED(30),
.width = CLAY_SIZING_GROW(0)
},
.childGap = 8,
.childAlignment = { .y = CLAY_ALIGN_Y_CENTER }
},
}) {
// Header buttons go here
CLAY({
.id = CLAY_ID("FileButton"),
.layout = {
.padding = { 8, 8, 4, 4 }
},
.backgroundColor = COLOR_BLACK,
.cornerRadius = CLAY_CORNER_RADIUS(4)
}) {
CLAY_TEXT(
CLAY_STRING("File"),
CLAY_TEXT_CONFIG({
.fontId = FONT_ID_BUTTON,
.textColor = COLOR_WHITE
})
);
}
RenderHeaderButton(CLAY_STRING("Edit"));
CLAY({ .layout = { .sizing = { CLAY_SIZING_GROW(0) } } }) {}
RenderHeaderButton(CLAY_STRING("Upload"));
RenderHeaderButton(CLAY_STRING("Media"));
RenderHeaderButton(CLAY_STRING("Support"));
}
CLAY({
.id = CLAY_ID("LowerContent"),
.layout = { .sizing = layoutExpand, .childGap = 8 },
}) {
CLAY({
.id = CLAY_ID("Sidebar"),
.border = contentBorders,
.cornerRadius = CLAY_CORNER_RADIUS(4),
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.padding = CLAY_PADDING_ALL(8),
.childGap = 4,
.sizing = {
.width = CLAY_SIZING_FIXED(125),
.height = CLAY_SIZING_GROW(0)
}
}
}) {
for (int i = 0; i < documents.length; i++) {
Document document = documents.documents[i];
Clay_LayoutConfig sidebarButtonLayout = {
.sizing = { .width = CLAY_SIZING_GROW(0) },
.padding = CLAY_PADDING_ALL(8)
};
if (i == selectedDocumentIndex) {
CLAY({
.layout = sidebarButtonLayout,
.backgroundColor = COLOR_BLACK,
.cornerRadius = CLAY_CORNER_RADIUS(4)
}) {
CLAY_TEXT(
document.title,
CLAY_TEXT_CONFIG({
.fontId = FONT_ID_BUTTON,
.textColor = COLOR_WHITE
})
);
}
} else {
CLAY({
.layout = sidebarButtonLayout,
.backgroundColor = (Clay_Color){ 0, 0, 0, Clay_Hovered() ? 120 : 0 },
.cornerRadius = CLAY_CORNER_RADIUS(4),
.border = contentBorders
}) {
CLAY_TEXT(
document.title,
CLAY_TEXT_CONFIG({
.fontId = FONT_ID_BUTTON,
.textColor = COLOR_BLACK,
})
);
}
}
}
}
CLAY({
.id = CLAY_ID("MainContent"),
.border = contentBorders,
.cornerRadius = CLAY_CORNER_RADIUS(4),
.clip = { .vertical = true, .childOffset = Clay_GetScrollOffset() },
.layout = {
.layoutDirection = CLAY_TOP_TO_BOTTOM,
.childGap = 8,
.padding = CLAY_PADDING_ALL(8),
.sizing = layoutExpand
}
}) {
Document selectedDocument = documents.documents[selectedDocumentIndex];
CLAY_TEXT(
selectedDocument.title,
CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY, .textColor = COLOR_BLACK })
);
CLAY_TEXT(
selectedDocument.contents,
CLAY_TEXT_CONFIG({ .fontId = FONT_ID_BODY, .textColor = COLOR_BLACK })
);
}
}
}
Clay_RenderCommandArray renderCommands = Clay_EndLayout();
for (int32_t i = 0; i < renderCommands.length; i++) {
Clay_RenderCommandArray_Get(&renderCommands, i);
}
return renderCommands;
}