diff --git a/common/general.h b/common/general.h new file mode 100644 index 00000000..c9253267 --- /dev/null +++ b/common/general.h @@ -0,0 +1,9 @@ +#ifndef H_COMMON_GENERAL +#define H_COMMON_GENERAL + +int max(int first, int second) +{ + return (first < second) ? second : first; +} + +#endif diff --git a/darwin/button.m b/darwin/button.m index c3a6e075..1813e1f7 100644 --- a/darwin/button.m +++ b/darwin/button.m @@ -1,5 +1,36 @@ // 13 august 2015 #import "uipriv_darwin.h" +#import "../common/general.h" + +@interface libui_NSButton : NSButton +@property int minWidth; +@property int minHeight; +- (id)initWithFrame:(NSRect)frameRect; +@end + +@implementation libui_NSButton + +- (id)initWithFrame:(NSRect)frameRect +{ + self = [super initWithFrame: frameRect]; + if (self) { + self.minHeight = -1; + self.minWidth = -1; + } + return self; +} + +- (NSSize)intrinsicContentSize +{ + NSSize s; + + s = [super intrinsicContentSize]; + s.width = max(self.minWidth, s.width); + s.height = max(self.minHeight, s.height); + return s; +} + +@end struct uiButton { uiDarwinControl c; @@ -78,6 +109,20 @@ void uiButtonSetText(uiButton *b, const char *text) [b->button setTitle:uiprivToNSString(text)]; } +void uiButtonSetMinSize(uiButton *b, int width, int height) +{ + libui_NSButton *libui_btn = (libui_NSButton *)b->button; + libui_btn.minWidth = width; + libui_btn.minHeight = height; +} + +void uiButtonPreferredSize(uiButton *b, int *width, int *height) +{ + NSSize s = b->button.intrinsicContentSize; + *width = s.width; + *height = s.height; +} + void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data) { b->onClicked = f; @@ -95,7 +140,7 @@ uiButton *uiNewButton(const char *text) uiDarwinNewControl(uiButton, b); - b->button = [[NSButton alloc] initWithFrame:NSZeroRect]; + b->button = [[libui_NSButton alloc] initWithFrame:NSZeroRect]; [b->button setTitle:uiprivToNSString(text)]; [b->button setButtonType:NSMomentaryPushInButton]; [b->button setBordered:YES]; diff --git a/examples/controlgallery/main.c b/examples/controlgallery/main.c index c0d536c1..4ba5cc8a 100644 --- a/examples/controlgallery/main.c +++ b/examples/controlgallery/main.c @@ -37,6 +37,11 @@ static uiControl *makeBasicControlsPage(void) uiBoxAppend(hbox, uiControl(uiNewCheckbox("Checkbox")), 0); + uiButton *btn = uiNewButton("Wide"); + uiButtonSetMinSize(btn, 150, -1); + uiBoxAppend(hbox, + uiControl(btn), + 0); uiBoxAppend(vbox, uiControl(uiNewLabel("This is a label. Right now, labels can only span one line.")), diff --git a/ui.h b/ui.h index e73e35b6..9ce47d34 100644 --- a/ui.h +++ b/ui.h @@ -144,6 +144,8 @@ _UI_EXTERN char *uiButtonText(uiButton *b); _UI_EXTERN void uiButtonSetText(uiButton *b, const char *text); _UI_EXTERN void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *b, void *data), void *data); _UI_EXTERN uiButton *uiNewButton(const char *text); +_UI_EXTERN void uiButtonSetMinSize(uiButton *b, int width, int height); +_UI_EXTERN void uiButtonPreferredSize(uiButton *b, int *width, int *height); typedef struct uiBox uiBox; #define uiBox(this) ((uiBox *) (this)) diff --git a/unix/button.c b/unix/button.c index 00a87f49..6c23dbb5 100644 --- a/unix/button.c +++ b/unix/button.c @@ -33,6 +33,18 @@ void uiButtonSetText(uiButton *b, const char *text) gtk_button_set_label(b->button, text); } +void uiButtonSetMinSize(uiButton *b, int width, int height) +{ + gtk_widget_set_size_request(b->widget, width, height); +} + +void uiButtonPreferredSize(uiButton *b, int *width, int *height) +{ + gtk_widget_show(b->widget); + gtk_widget_get_preferred_height(b->widget, NULL, height); + gtk_widget_get_preferred_width(b->widget, NULL, width); +} + void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data) { b->onClicked = f; diff --git a/windows/button.cpp b/windows/button.cpp index d8913ec7..3acaaa67 100644 --- a/windows/button.cpp +++ b/windows/button.cpp @@ -1,11 +1,14 @@ // 7 april 2015 #include "uipriv_windows.hpp" +#include "../common/general.h" struct uiButton { uiWindowsControl c; HWND hwnd; void (*onClicked)(uiButton *, void *); void *onClickedData; + int minHeight; + int minWidth; }; static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) @@ -44,8 +47,8 @@ static void uiButtonMinimumSize(uiWindowsControl *c, int *width, int *height) size.cx = 0; // explicitly ask for ideal size size.cy = 0; if (SendMessageW(b->hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) { - *width = size.cx; - *height = size.cy; + *width = max(size.cx, (LONG)(b->minWidth)); + *height = max(size.cy, (LONG)(b->minHeight)); return; } @@ -57,6 +60,9 @@ static void uiButtonMinimumSize(uiWindowsControl *c, int *width, int *height) uiWindowsGetSizing(b->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); *height = y; + + *width = max(*width, b->minWidth); + *height = max(y, b->minHeight); } static void defaultOnClicked(uiButton *b, void *data) @@ -76,6 +82,18 @@ void uiButtonSetText(uiButton *b, const char *text) uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); } +void uiButtonSetMinSize(uiButton *b, int width, int height) +{ + b->minHeight = height; + b->minWidth = width; + uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); +} + +void uiButtonPreferredSize(uiButton *b, int *width, int *height) +{ + uiButtonMinimumSize(uiWindowsControl(b), width, height); +} + void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data) { b->onClicked = f; @@ -88,6 +106,8 @@ uiButton *uiNewButton(const char *text) WCHAR *wtext; uiWindowsNewControl(uiButton, b); + b->minHeight = -1; + b->minWidth = -1; wtext = toUTF16(text); b->hwnd = uiWindowsEnsureCreateControlHWND(0, diff --git a/windows/uipriv_windows.hpp b/windows/uipriv_windows.hpp index 52d74c51..9f487eb9 100644 --- a/windows/uipriv_windows.hpp +++ b/windows/uipriv_windows.hpp @@ -1,4 +1,5 @@ // 21 april 2016 +#define NOMINMAX #include "winapi.hpp" #include "../ui.h" #include "../ui_windows.h"