Skip to content

Add fixed positioning, and the ability to set and get a component size #332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 26 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/controlsigs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#define uiDateTimePickerSignature 0x44545069
#define uiEditableComboboxSignature 0x45644362
#define uiEntrySignature 0x456E7472
#define uiFixedSignature 0x46697864
#define uiFontButtonSignature 0x466F6E42
#define uiFormSignature 0x466F726D
#define uiGridSignature 0x47726964
Expand Down
1 change: 1 addition & 0 deletions darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ list(APPEND _LIBUI_SOURCES
darwin/drawtext.m
darwin/editablecombo.m
darwin/entry.m
darwin/fixed.m
darwin/fontbutton.m
darwin/fontmatch.m
darwin/fonttraits.m
Expand Down
248 changes: 248 additions & 0 deletions darwin/fixed.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
// 19 may 2018
#import "uipriv_darwin.h"

@interface uiprivFixedChild : NSObject
@property uiControl *c;
@property int x;
@property int y;
- (NSView *)view;
@end

@interface uiprivFixedView : NSView {
uiFixed *b;
NSMutableArray *children;
}
- (id)initFixed:(uiFixed *)bb;
- (void)onDestroy;
- (void)syncEnableStates:(int)enabled;
- (void)append:(uiControl *)c x:(int)x y:(int)y;
- (void)move:(uiControl *)c x:(int)x y:(int)y;
- (void)reloadPositions;
- (void)size:(uiControl *)c width:(int *)width height:(int *)height;
- (void)setSize:(uiControl *)c width:(int)width height:(int)height;
@end

struct uiFixed {
uiDarwinControl c;
uiprivFixedView *view;
};

@implementation uiprivFixedChild

- (NSView *)view
{
return (NSView *) uiControlHandle(self.c);
}

@end

@implementation uiprivFixedView

- (id)initFixed:(uiFixed *)bb
{
self = [super initWithFrame:NSZeroRect];
if (self != nil) {
self->b = bb;
self->children = [NSMutableArray new];
}

return self;
}

- (BOOL)isFlipped
{
return YES;
}

- (void)onDestroy
{
uiprivFixedChild *bc;

for (bc in self->children) {
uiControlSetParent(bc.c, NULL);
uiDarwinControlSetSuperview(uiDarwinControl(bc.c), nil);
uiControlDestroy(bc.c);
}
[self->children release];
}

- (void)syncEnableStates:(int)enabled
{
uiprivFixedChild *bc;

for (bc in self->children)
uiDarwinControlSyncEnableState(uiDarwinControl(bc.c), enabled);
}

- (void)append:(uiControl *)c x:(int)x y:(int)y
{
uiprivFixedChild *bc;

bc = [uiprivFixedChild new];
bc.c = c;
bc.x = x;
bc.y = y;

uiControlSetParent(bc.c, uiControl(self->b));
uiDarwinControlSetSuperview(uiDarwinControl(bc.c), self);
uiDarwinControlSyncEnableState(uiDarwinControl(bc.c), uiControlEnabledToUser(uiControl(self->b)));

[self->children addObject:bc];

[self reloadPositions];

[bc release]; // we don't need the initial reference now
}

- (void)move:(uiControl *)c x:(int)x y:(int)y
{
uiprivFixedChild *fc;

for (fc in self->children) {
if (fc.c == c) {
fc.x = x;
fc.y = y;
[self reloadPositions];
return;
}
}
}

- (void)reloadPositions
{
uiprivFixedChild *fc;
CGPoint pos;
NSView *view;

for (fc in self->children) {
if (!uiControlVisible(fc.c))
continue;
pos = CGPointMake(fc.x, fc.y);
view = [fc view];
[view setFrame:(CGRect){.origin = pos, .size=view.frame.size}];
}
}

- (void)size:(uiControl *)c width:(int *)width height:(int *)height
{
uiprivFixedChild *fc;
NSView *view;

for (fc in self->children) {
if (!uiControlVisible(fc.c))
continue;
if (fc.c == c) {
view = [fc view];
*width = view.frame.size.width;
*height = view.frame.size.height;
}
}
}

- (void)setSize:(uiControl *)c width:(int)width height:(int)height
{
uiprivFixedChild *fc;
NSView *view;

for (fc in self->children) {
if (!uiControlVisible(fc.c))
continue;
if (fc.c == c) {
view = [fc view];

CGRect bounds = view.bounds;
bounds.size.width = width;
bounds.size.height = height;
view.bounds = bounds;

CGRect frame = view.frame;
frame.size.width = width;
frame.size.height = height;
view.frame = frame;
}
}
}

@end

static void uiFixedDestroy(uiControl *c)
{
uiFixed *b = uiFixed(c);

[b->view onDestroy];
[b->view release];
uiFreeControl(uiControl(b));
}

uiDarwinControlDefaultHandle(uiFixed, view)
uiDarwinControlDefaultParent(uiFixed, view)
uiDarwinControlDefaultSetParent(uiFixed, view)
uiDarwinControlDefaultToplevel(uiFixed, view)
uiDarwinControlDefaultVisible(uiFixed, view)
uiDarwinControlDefaultShow(uiFixed, view)
uiDarwinControlDefaultHide(uiFixed, view)
uiDarwinControlDefaultEnabled(uiFixed, view)
uiDarwinControlDefaultEnable(uiFixed, view)
uiDarwinControlDefaultDisable(uiFixed, view)

static void uiFixedSyncEnableState(uiDarwinControl *c, int enabled)
{
uiFixed *b = uiFixed(c);

if (uiDarwinShouldStopSyncEnableState(uiDarwinControl(b), enabled))
return;
[b->view syncEnableStates:enabled];
}

uiDarwinControlDefaultSetSuperview(uiFixed, view)

uiDarwinControlDefaultHuggingPriority(uiFixed, view)
uiDarwinControlDefaultSetHuggingPriority(uiFixed, view)
uiDarwinControlDefaultHugsTrailingEdge(uiFixed, view)
uiDarwinControlDefaultHugsBottom(uiFixed, view)
uiDarwinControlDefaultChildEdgeHuggingChanged(uiFixed, view)

static void uiFixedChildVisibilityChanged(uiDarwinControl *c)
{
uiFixed *b = uiFixed(c);

[b->view reloadPositions];
}

void uiFixedAppend(uiFixed *b, uiControl *c, int x, int y)
{
// LONGTERM on other platforms
// or at leat allow this and implicitly turn it into a spacer
if (c == NULL)
uiprivUserBug("You cannot add NULL to a uiFixed.");
[b->view append:c x:x y:y];
}

void uiFixedMove(uiFixed *b, uiControl *c, int x, int y)
{
// LONGTERM on other platforms
// or at leat allow this and implicitly turn it into a spacer
if (c == NULL)
uiprivUserBug("You cannot move NULL to a uiFixed.");
[b->view move:c x:x y:y];
}

void uiFixedSize(uiFixed *b, uiControl *c, int *width, int *height)
{
[b->view size:c width:width height:height];
}

void uiFixedSetSize(uiFixed *b, uiControl *c, int width, int height)
{
[b->view setSize:c width:width height:height];
}

uiFixed *uiNewFixed(void)
{
uiFixed *f;
uiDarwinNewControl(uiFixed, f);

f->view = [[uiprivFixedView alloc] initFixed:f];

return f;
}
11 changes: 11 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ _add_example(controlgallery
${_EXAMPLE_RESOURCES_RC}
)

_add_example(layout-test
layout-test/main.c
${_EXAMPLE_RESOURCES_RC}
)

set_target_properties(layout-test PROPERTIES
OUTPUT_NAME layout-test
WIN32_EXECUTABLE FALSE
)

_add_example(histogram
histogram/main.c
${_EXAMPLE_RESOURCES_RC}
Expand Down Expand Up @@ -57,6 +67,7 @@ add_custom_target(examples
controlgallery
histogram
cpp-multithread
layout-test
drawtext
timer
datetime)
46 changes: 46 additions & 0 deletions examples/layout-test/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <stdio.h>
#include <string.h>
#include "../../ui.h"

int main(void)
{
uiInitOptions options;
const char *err;

memset(&options, 0, sizeof (uiInitOptions));
err = uiInit(&options);
if (err != NULL) {
fprintf(stderr, "error initializing libui: %s", err);
uiFreeInitError(err);
return 1;
}

uiWindow *mainwin = uiNewWindow("Layout test", 640, 480, 1);

uiFixed *fixed = uiNewFixed();

uiWindowSetChild(mainwin, uiControl(fixed));

uiLabel *label = uiNewLabel("Hello");

uiFixedAppend(fixed, uiControl(label), 150, 200);

uiButton *button = uiNewButton("Button");

uiFixedAppend(fixed, uiControl(button), 50, 50);

uiControlShow(uiControl(mainwin));


int width, height;

uiFixedMove(fixed, uiControl(button), 0, 100);

uiFixedSize(fixed, uiControl(button), &width, &height);
printf("Width: %d, Height: %d\n", width, height);

//uiFixedSetSize(fixed, uiControl(button), 50, 50);

uiMain();
return 0;
}
8 changes: 8 additions & 0 deletions ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,14 @@ _UI_EXTERN int uiGridPadded(uiGrid *g);
_UI_EXTERN void uiGridSetPadded(uiGrid *g, int padded);
_UI_EXTERN uiGrid *uiNewGrid(void);

typedef struct uiFixed uiFixed;
#define uiFixed(this) ((uiFixed *) (this))
_UI_EXTERN void uiFixedAppend(uiFixed *g, uiControl *c, int x, int y);
_UI_EXTERN void uiFixedMove(uiFixed *g, uiControl *c, int x, int y);
_UI_EXTERN void uiFixedSize(uiFixed *b, uiControl *control, int *width, int *height);
_UI_EXTERN void uiFixedSetSize(uiFixed *b, uiControl *control, int width, int height);
_UI_EXTERN uiFixed *uiNewFixed(void);

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 2 additions & 0 deletions ui_unix.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ typedef struct uiUnixControl uiUnixControl;
struct uiUnixControl {
uiControl c;
uiControl *parent;
int width;
int height;
gboolean addedBefore;
gboolean explicitlyHidden;
void (*SetContainer)(uiUnixControl *, GtkContainer *, gboolean);
Expand Down
3 changes: 3 additions & 0 deletions ui_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ _UI_EXTERN int uiWindowsWindowTextWidth(HWND hwnd);
// TODO point out this should only be used in a resize cycle
_UI_EXTERN void uiWindowsEnsureMoveWindowDuringResize(HWND hwnd, int x, int y, int width, int height);

_UI_EXTERN void uiWindowsResizeWindow(HWND hwnd, int width, int height);
_UI_EXTERN void uiWindowsMoveWindow(HWND hwnd, int x, int y);

// TODO document
_UI_EXTERN void uiWindowsRegisterWM_COMMANDHandler(HWND hwnd, BOOL (*handler)(uiControl *, HWND, WORD, LRESULT *), uiControl *c);
_UI_EXTERN void uiWindowsUnregisterWM_COMMANDHandler(HWND hwnd);
Expand Down
1 change: 1 addition & 0 deletions unix/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ list(APPEND _LIBUI_SOURCES
unix/drawtext.c
unix/editablecombo.c
unix/entry.c
unix/fixed.c
unix/fontbutton.c
unix/fontmatch.c
unix/form.c
Expand Down
Loading