diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d04792f2..7147ff4e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ libui uses K&R C formatting rules for overall code structure: spaces after keywo Use hard tabs, NOT spaces, for indentation. I use a proportional-width font and my text editor doesn't set tabs to a multiple of the space width, so I *will* be able to tell. If you use a fixed-width font, I suggest setting a tab width of 4 spaces per tab, but don't put diagrams in comments with hard tabs, because not everyone does this. -Expressions should have a spce around binary operators, and use parentheses where it would help humans gather the meaning of an expression, regardless of whether a computer could tell what is correct. +Expressions should have a space around binary operators, and use parentheses where it would help humans gather the meaning of an expression, regardless of whether a computer could tell what is correct. When breaking expressions into multiple lines, always break *after* an operator, such as `,` or `&&`. @@ -40,6 +40,10 @@ Acronyms should **NOT** be mixed-case. `http` for the first word in a camel-case (TODO I am writing an API documentation tool; once that becomes stable enough I can talk about documenting libui properly. You'll see vestiges of it throughout ui.h, though.) +### Other commenting + +(TODO write this part) + ### Compatibility libui takes backward compatibility seriously. Your code should not break the current compatibility requirements. All platforms provide a series of macros, defined in the various `uipriv_*.h` files (or `winapi.hpp` on Windows), that specify the minimum required version. If you find yourself needing to remove these or ignore resultant warnings or errors, you're probably breaking compatibility. diff --git a/README.md b/README.md index ca2c5ac0..443c3bb2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ This README is being written.
## Announcements * **TODO** - * Introduced an all-new formatted text API that allows you to process formatted text in ways that the old API wouldn't allow. You can read on the whole API [here](TODO). + * Introduced an all-new formatted text API that allows you to process formatted text in ways that the old API wouldn't allow. You can read on the whole API [here](TODO). There are also two new examples for this new api: `drawtext` (which shows the whole API at a glance) and `opentype` (which focuses on OpenType features). * Also introduced a formal set of contribution guidelines, see `CONTRIBUTING.md` for details. * **27 November 2016** diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index e011db23..f2289d21 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -42,9 +42,17 @@ _add_example(drawtext target_include_directories(drawtext PRIVATE drawtext) +_add_example(opentype + opentype/main.c + ${_EXAMPLE_RESOURCES_RC} +) +target_include_directories(opentype + PRIVATE opentype) + add_custom_target(examples DEPENDS controlgallery histogram cpp-multithread - drawtext) + drawtext + opentype) diff --git a/examples/opentype/main.c b/examples/opentype/main.c new file mode 100644 index 00000000..00c3f451 --- /dev/null +++ b/examples/opentype/main.c @@ -0,0 +1,173 @@ +// 10 june 2017 +#include +#include +#include +#include +#include "../../ui.h" + +uiWindow *mainwin; +uiFontButton *fontButton; +uiEntry *textEntry; +uiCheckbox *nullFeatures; +uiArea *area; + +uiAttributedString *attrstr = NULL; + +static void remakeAttrStr(void) +{ + char *text; + uiOpenTypeFeatures *otf; + uiAttributeSpec spec; + + if (attrstr != NULL) + uiFreeAttributedString(attrstr); + + text = uiEntryText(textEntry); + attrstr = uiNewAttributedString(text); + uiFreeText(text); + + if (!uiCheckboxChecked(nullFeatures)) { + otf = uiNewOpenTypeFeatures(); + // TODO + spec.Type = uiAttributeFeatures; + spec.Features = otf; + uiAttributedStringSetAttribute(attrstr, &spec, + 0, uiAttributedStringLen(attrstr)); + // and uiAttributedString copied otf + uiFreeOpenTypeFeatures(otf); + } + + uiAreaQueueRedrawAll(area); +} + +// TODO make a variable of main()? in all programs? +static uiAreaHandler handler; + +static void handlerDraw(uiAreaHandler *a, uiArea *area, uiAreaDrawParams *p) +{ + uiDrawTextLayout *layout; + uiDrawTextLayoutParams lp; + uiDrawFontDescriptor desc; + + memset(&lp, 0, sizeof (uiDrawTextLayoutParams)); + lp.String = attrstr; + uiFontButtonFont(fontButton, &desc); + lp.DefaultFont = &desc; + lp.Width = p->AreaWidth; + lp.Align = uiDrawTextAlignLeft; + layout = uiDrawNewTextLayout(&lp); + uiDrawText(p->Context, layout, 0, 0); + uiDrawFreeTextLayout(layout); +} + +static void handlerMouseEvent(uiAreaHandler *a, uiArea *area, uiAreaMouseEvent *e) +{ + // do nothing +} + +static void handlerMouseCrossed(uiAreaHandler *ah, uiArea *a, int left) +{ + // do nothing +} + +static void handlerDragBroken(uiAreaHandler *ah, uiArea *a) +{ + // do nothing +} + +static int handlerKeyEvent(uiAreaHandler *ah, uiArea *a, uiAreaKeyEvent *e) +{ + // reject all keys + return 0; +} + +static int onClosing(uiWindow *w, void *data) +{ + // TODO change the others to be like this? (the others destroy here rather than later) + // TODO move this below uiQuit()? + uiControlHide(uiControl(w)); + uiQuit(); + return 0; +} + +static int shouldQuit(void *data) +{ + uiControlDestroy(uiControl(mainwin)); + return 1; +} + +int main(void) +{ + uiInitOptions o; + const char *err; + uiGrid *grid; + uiBox *vbox; + + handler.Draw = handlerDraw; + handler.MouseEvent = handlerMouseEvent; + handler.MouseCrossed = handlerMouseCrossed; + handler.DragBroken = handlerDragBroken; + handler.KeyEvent = handlerKeyEvent; + + memset(&o, 0, sizeof (uiInitOptions)); + err = uiInit(&o); + if (err != NULL) { + fprintf(stderr, "error initializing ui: %s\n", err); + uiFreeInitError(err); + return 1; + } + + uiOnShouldQuit(shouldQuit, NULL); + + // TODO 800x600? the size of the GTK+ example? + mainwin = uiNewWindow("libui OpenType Features Example", 640, 480, 1); + uiWindowSetMargined(mainwin, 1); + uiWindowOnClosing(mainwin, onClosing, NULL); + + grid = uiNewGrid(); + uiGridSetPadded(grid, 1); + uiWindowSetChild(mainwin, uiControl(grid)); + + fontButton = uiNewFontButton(); + uiGridAppend(grid, uiControl(fontButton), + 0, 0, 1, 1, + // TODO are these Y values correct? + 0, uiAlignFill, 0, uiAlignCenter); + + textEntry = uiNewEntry(); + uiEntrySetText(textEntry, "afford afire aflight"); + uiGridAppend(grid, uiControl(textEntry), + 1, 0, 1, 1, + // TODO are these Y values correct too? + // TODO add a baseline align? or a form align? + 1, uiAlignFill, 0, uiAlignCenter); + + vbox = uiNewVerticalBox(); + uiBoxSetPadded(vbox, 1); + uiGridAppend(grid, uiControl(vbox), + 0, 1, 1, 1, + 0, uiAlignFill, 1, uiAlignFill); + + nullFeatures = uiNewCheckbox("NULL uiOpenTypeFeatures"); + uiBoxAppend(vbox, uiControl(nullFeatures), 0); + + // TODO separator (if other stuff isn't a tab) + + // TODO other stuff + + area = uiNewArea(&handler); + uiGridAppend(grid, uiControl(area), + 1, 1, 1, 1, + 1, uiAlignFill, 1, uiAlignFill); + + // and set up the initial draw + remakeAttrStr(); + + uiControlShow(uiControl(mainwin)); + uiMain(); + + uiControlDestroy(uiControl(mainwin)); + uiFreeAttributedString(attrstr); + uiUninit(); + return 0; +}