Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #305 from steinbergmedia/develop
Prepare 4.13.0 Release
- Loading branch information
Showing
121 changed files
with
8,825 additions
and
3,958 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// This file is part of VSTGUI. It is subject to the license terms | ||
// in the LICENSE file found in the top-level directory of this | ||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE | ||
|
||
#pragma once | ||
|
||
#include "../lib/iexternalview.h" | ||
#include <functional> | ||
#include <memory> | ||
|
||
//------------------------------------------------------------------------ | ||
namespace VSTGUI { | ||
namespace ExternalView { | ||
|
||
//------------------------------------------------------------------------ | ||
class DatePicker : public ViewAdapter | ||
{ | ||
public: | ||
DatePicker (); | ||
~DatePicker () noexcept; | ||
|
||
struct Date | ||
{ | ||
int32_t day {0}; | ||
int32_t month {0}; | ||
int32_t year {0}; | ||
}; | ||
void setDate (Date date); | ||
|
||
using ChangeCallback = std::function<void (Date)>; | ||
void setChangeCallback (const ChangeCallback& callback); | ||
|
||
private: | ||
bool platformViewTypeSupported (PlatformViewType type) override; | ||
bool attach (void* parent, PlatformViewType parentViewType) override; | ||
bool remove () override; | ||
|
||
void setViewSize (IntRect frame, IntRect visible) override; | ||
void setContentScaleFactor (double scaleFactor) override; | ||
|
||
void setMouseEnabled (bool state) override; | ||
|
||
void takeFocus () override; | ||
void looseFocus () override; | ||
|
||
void setTookFocusCallback (const TookFocusCallback& callback) override; | ||
|
||
struct Impl; | ||
std::unique_ptr<Impl> impl; | ||
}; | ||
|
||
//------------------------------------------------------------------------ | ||
} // ExternalView | ||
} // VSTGUI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
// This file is part of VSTGUI. It is subject to the license terms | ||
// in the LICENSE file found in the top-level directory of this | ||
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE | ||
|
||
#import "datepicker.h" | ||
#import "externalview_nsview.h" | ||
|
||
//------------------------------------------------------------------------ | ||
namespace VSTGUI { | ||
namespace ExternalView { | ||
|
||
//------------------------------------------------------------------------ | ||
struct DatePickerDelegate : RuntimeObjCClass<DatePickerDelegate> | ||
{ | ||
using DoneCallback = std::function<void ()>; | ||
using ValidateCallback = std::function<void (NSDate**, NSTimeInterval*)>; | ||
|
||
static constexpr const auto DoneCallbackVarName = "DoneCallback"; | ||
static constexpr const auto ValidateCallbackVarName = "ValidateCallback"; | ||
|
||
static id allocAndInit (DoneCallback&& doneCallback, ValidateCallback&& callback) | ||
{ | ||
id obj = Base::alloc (); | ||
initWithCallbacks (obj, std::move (doneCallback), std::move (callback)); | ||
return obj; | ||
} | ||
|
||
static Class CreateClass () | ||
{ | ||
return ObjCClassBuilder () | ||
.init ("DatePickerDelegate", [NSObject class]) | ||
.addProtocol ("NSDatePickerCellDelegate") | ||
.addMethod (@selector (datePickerCell:validateProposedDateValue:timeInterval:), | ||
validate) | ||
.addMethod (@selector (complete:), complete) | ||
.addIvar<ValidateCallback> (ValidateCallbackVarName) | ||
.addIvar<DoneCallback> (DoneCallbackVarName) | ||
.finalize (); | ||
} | ||
|
||
static id initWithCallbacks (id self, DoneCallback&& doneCallback, ValidateCallback&& callback) | ||
{ | ||
if ((self = makeInstance (self).callSuper<id (), id> (@selector (init)))) | ||
{ | ||
auto instance = makeInstance (self); | ||
if (auto var = instance.getVariable<DoneCallback> (DoneCallbackVarName)) | ||
var->set (doneCallback); | ||
if (auto var = instance.getVariable<ValidateCallback> (ValidateCallbackVarName)) | ||
var->set (callback); | ||
} | ||
return self; | ||
} | ||
|
||
static void complete (id self, SEL cmd, id sender) | ||
{ | ||
if (auto var = makeInstance (self).getVariable<DoneCallback> (DoneCallbackVarName)) | ||
{ | ||
const auto& callback = var->get (); | ||
if (callback) | ||
callback (); | ||
} | ||
} | ||
|
||
static void validate (id self, SEL cmd, NSDatePickerCell* datePickerCell, | ||
NSDate* _Nonnull* _Nonnull proposedDateValue, | ||
NSTimeInterval* _Nullable proposedTimeInterval) | ||
{ | ||
if (auto var = makeInstance (self).getVariable<ValidateCallback> (ValidateCallbackVarName)) | ||
{ | ||
const auto& callback = var->get (); | ||
if (callback) | ||
callback (proposedDateValue, proposedTimeInterval); | ||
} | ||
} | ||
}; | ||
|
||
//------------------------------------------------------------------------ | ||
struct DatePicker::Impl : ExternalNSViewBase<NSDatePicker> | ||
{ | ||
using Base::Base; | ||
|
||
id delegate {nil}; | ||
ChangeCallback changeCallback; | ||
|
||
#if !__has_feature(objc_arc) | ||
~Impl () noexcept | ||
{ | ||
if (delegate) | ||
[delegate release]; | ||
} | ||
#endif | ||
}; | ||
|
||
//------------------------------------------------------------------------ | ||
DatePicker::DatePicker () | ||
{ | ||
impl = std::make_unique<Impl> ([[NSDatePicker alloc] initWithFrame: {0., 0., 10., 10.}]); | ||
impl->view.datePickerStyle = NSDatePickerStyleTextField; | ||
impl->view.datePickerMode = NSDatePickerModeSingle; | ||
impl->view.datePickerElements = NSDatePickerElementFlagYearMonthDay; | ||
if (@available (macOS 10.15.4, *)) | ||
impl->view.presentsCalendarOverlay = YES; | ||
impl->view.dateValue = [NSDate date]; | ||
impl->view.calendar = [NSCalendar currentCalendar]; | ||
[impl->container addSubview:impl->view]; | ||
|
||
impl->delegate = DatePickerDelegate::allocAndInit ( | ||
[impl = impl.get ()] () { | ||
if (impl->changeCallback) | ||
{ | ||
auto dateValue = impl->view.dateValue; | ||
auto calendar = impl->view.calendar; | ||
auto components = [calendar | ||
components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | ||
fromDate:dateValue]; | ||
Date date; | ||
date.day = static_cast<int32_t> (components.day); | ||
date.month = static_cast<int32_t> (components.month); | ||
date.year = static_cast<int32_t> (components.year); | ||
impl->changeCallback (date); | ||
} | ||
}, | ||
[] (NSDate** date, NSTimeInterval* time) { | ||
// TODO: add validation mechanism | ||
}); | ||
impl->view.delegate = impl->delegate; | ||
impl->view.target = impl->delegate; | ||
impl->view.action = @selector (complete:); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
DatePicker::~DatePicker () noexcept {} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setDate (Date date) | ||
{ | ||
auto calendar = impl->view.calendar; | ||
auto dateComponents = [NSDateComponents new]; | ||
dateComponents.calendar = calendar; | ||
dateComponents.day = date.day; | ||
dateComponents.month = date.month; | ||
dateComponents.year = date.year; | ||
impl->view.dateValue = [calendar dateFromComponents:dateComponents]; | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setChangeCallback (const ChangeCallback& callback) | ||
{ | ||
impl->changeCallback = callback; | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
bool DatePicker::platformViewTypeSupported (PlatformViewType type) | ||
{ | ||
return impl->platformViewTypeSupported (type); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
bool DatePicker::attach (void* parent, PlatformViewType parentViewType) | ||
{ | ||
return impl->attach (parent, parentViewType); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
bool DatePicker::remove () { return impl->remove (); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setViewSize (IntRect frame, IntRect visible) | ||
{ | ||
impl->setViewSize (frame, visible); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setContentScaleFactor (double scaleFactor) | ||
{ | ||
impl->setContentScaleFactor (scaleFactor); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setMouseEnabled (bool state) { impl->setMouseEnabled (state); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::takeFocus () { impl->takeFocus (); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::looseFocus () { impl->looseFocus (); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setTookFocusCallback (const TookFocusCallback& callback) | ||
{ | ||
impl->setTookFocusCallback (callback); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
} // ExternalView | ||
} // VSTGUI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
|
||
#include "datepicker.h" | ||
#include "externalview_hwnd.h" | ||
#include "vstgui/lib/platform/win32/win32factory.h" | ||
|
||
#include <CommCtrl.h> | ||
|
||
//------------------------------------------------------------------------ | ||
namespace VSTGUI { | ||
namespace ExternalView { | ||
|
||
//------------------------------------------------------------------------ | ||
struct DatePicker::Impl : ExternalHWNDBase | ||
{ | ||
using Base::Base; | ||
|
||
~Impl () noexcept | ||
{ | ||
if (font) | ||
DeleteObject (font); | ||
} | ||
|
||
ChangeCallback changeCallback; | ||
HFONT font {nullptr}; | ||
}; | ||
|
||
//------------------------------------------------------------------------ | ||
DatePicker::DatePicker () | ||
{ | ||
auto hInstance = getPlatformFactory ().asWin32Factory ()->getInstance (); | ||
impl = std::make_unique<Impl> (hInstance); | ||
impl->child = CreateWindowExW (0, DATETIMEPICK_CLASS, TEXT ("DateTime"), | ||
WS_BORDER | WS_CHILD | WS_VISIBLE | DTS_SHORTDATEFORMAT, 0, 0, | ||
80, 20, impl->container.getHWND (), NULL, hInstance, NULL); | ||
impl->container.setWindowProc ([this] (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { | ||
switch (message) | ||
{ | ||
case WM_NOTIFY: | ||
{ | ||
LPNMHDR hdr = reinterpret_cast<LPNMHDR> (lParam); | ||
switch (hdr->code) | ||
{ | ||
case DTN_DATETIMECHANGE: | ||
{ | ||
LPNMDATETIMECHANGE lpChange = reinterpret_cast<LPNMDATETIMECHANGE> (lParam); | ||
if (impl->changeCallback) | ||
{ | ||
Date date; | ||
date.day = lpChange->st.wDay; | ||
date.month = lpChange->st.wMonth; | ||
date.year = lpChange->st.wYear; | ||
impl->changeCallback (date); | ||
} | ||
break; | ||
} | ||
} | ||
break; | ||
} | ||
} | ||
return DefWindowProc (hwnd, message, wParam, lParam); | ||
}); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
DatePicker::~DatePicker () noexcept {} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setDate (Date date) | ||
{ | ||
SYSTEMTIME st = {}; | ||
st.wDay = date.day; | ||
st.wMonth = date.month; | ||
st.wYear = date.year; | ||
DateTime_SetSystemtime (impl->child, GDT_VALID, &st); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setChangeCallback (const ChangeCallback& callback) | ||
{ | ||
impl->changeCallback = callback; | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
bool DatePicker::platformViewTypeSupported (PlatformViewType type) | ||
{ | ||
return impl->platformViewTypeSupported (type); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
bool DatePicker::attach (void* parent, PlatformViewType parentViewType) | ||
{ | ||
return impl->attach (parent, parentViewType); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
bool DatePicker::remove () { return impl->remove (); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setViewSize (IntRect frame, IntRect visible) | ||
{ | ||
impl->setViewSize (frame, visible); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setContentScaleFactor (double scaleFactor) | ||
{ | ||
if (impl->font) | ||
DeleteObject (impl->font); | ||
auto logFont = NonClientMetrics::get ().lfCaptionFont; | ||
logFont.lfHeight = static_cast<LONG> (std::round (logFont.lfHeight * scaleFactor)); | ||
impl->font = CreateFontIndirect (&logFont); | ||
if (impl->font) | ||
SendMessage (impl->child, WM_SETFONT, (WPARAM)impl->font, 0); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::setMouseEnabled (bool state) { impl->setMouseEnabled (state); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::takeFocus () { impl->takeFocus (); } | ||
|
||
//------------------------------------------------------------------------ | ||
void DatePicker::looseFocus () { impl->looseFocus (); } | ||
|
||
void DatePicker::setTookFocusCallback (const TookFocusCallback& callback) | ||
{ | ||
impl->setTookFocusCallback (callback); | ||
} | ||
|
||
//------------------------------------------------------------------------ | ||
} // ExternalView | ||
} // VSTGUI |
Oops, something went wrong.