Merge pull request #1153 from redtide/hidpi
HiDPI: handle system scale factor in LV2, custom zoom
This commit is contained in:
commit
289d6efc25
7 changed files with 156 additions and 12 deletions
|
|
@ -440,6 +440,22 @@ widget_class mainView {open
|
|||
xywh {435 220 80 25} labelsize 14 textsize 14
|
||||
class ValueMenu
|
||||
}
|
||||
Fl_Box {} {
|
||||
label Zoom
|
||||
xywh {555 195 95 25} labelsize 12 align 20
|
||||
class Label
|
||||
}
|
||||
Fl_Spinner zoomMenu_ {
|
||||
comment {tag=kTagZoomMenu}
|
||||
xywh {680 195 100 25} labelsize 12 textsize 12
|
||||
class OptionMenu
|
||||
}
|
||||
Fl_Button defaultZoomButton_ {
|
||||
label {Set Default}
|
||||
comment {tag=kTagSetDefaultZoom}
|
||||
xywh {680 220 100 25} labelsize 12
|
||||
class ValueButton
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Box piano_ {
|
||||
|
|
|
|||
|
|
@ -38,5 +38,7 @@ EditRange EditRange::get(EditId id)
|
|||
return { 0, 0, 1 };
|
||||
case EditId::UIActivePanel:
|
||||
return { 0, 0, 255 };
|
||||
case EditId::UIZoom:
|
||||
return { 100, 100, 300 };
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ enum class EditId : int {
|
|||
UINumPreloadedSamples,
|
||||
UINumActiveVoices,
|
||||
UIActivePanel,
|
||||
UIZoom,
|
||||
//
|
||||
BackgroundImage,
|
||||
//
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "BitArray.h"
|
||||
#include "Theme.h"
|
||||
#include "plugin/MessageUtils.h"
|
||||
#include "plugin/SfizzSettings.h"
|
||||
#include <absl/strings/string_view.h>
|
||||
#include <absl/strings/match.h>
|
||||
#include <absl/strings/ascii.h>
|
||||
|
|
@ -29,6 +30,7 @@
|
|||
#include <unordered_map>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
#include <type_traits>
|
||||
#include <system_error>
|
||||
#include <fstream>
|
||||
|
|
@ -62,6 +64,8 @@ struct Editor::Impl : EditorController::Receiver,
|
|||
std::string fallbackFilesDir_;
|
||||
bool multi_ { false };
|
||||
|
||||
float zoom_ = 1.0f;
|
||||
|
||||
int currentKeyswitch_ = -1;
|
||||
std::unordered_map<unsigned, std::string> keyswitchNames_;
|
||||
|
||||
|
|
@ -106,6 +110,8 @@ struct Editor::Impl : EditorController::Receiver,
|
|||
kTagChooseUserFilesDir,
|
||||
kTagAbout,
|
||||
kTagThemeMenu,
|
||||
kTagZoomMenu,
|
||||
kTagSetDefaultZoom,
|
||||
kTagFirstChangePanel,
|
||||
kTagLastChangePanel = kTagFirstChangePanel + kNumPanels - 1,
|
||||
};
|
||||
|
|
@ -140,6 +146,8 @@ struct Editor::Impl : EditorController::Receiver,
|
|||
CTextLabel* keyswitchBadge_ = nullptr;
|
||||
CTextLabel* lblHover_ = nullptr;
|
||||
COptionMenu* themeMenu_ = nullptr;
|
||||
COptionMenu* zoomMenu_ = nullptr;
|
||||
STextButton* defaultZoomButton_ = nullptr;
|
||||
std::unique_ptr<Theme> theme_;
|
||||
|
||||
STitleContainer* userFilesGroup_ = nullptr;
|
||||
|
|
@ -272,6 +280,9 @@ struct Editor::Impl : EditorController::Receiver,
|
|||
void onThemeChanged() override;
|
||||
std::vector<std::function<void()>> OnThemeChanged;
|
||||
|
||||
// Zoom
|
||||
void setZoom(int zoom);
|
||||
|
||||
// Misc
|
||||
static std::string getUnicodeNoteName(unsigned key)
|
||||
{
|
||||
|
|
@ -315,8 +326,14 @@ void Editor::open(CFrame& frame)
|
|||
getResourceBasePath().u8string().c_str());
|
||||
|
||||
impl.frame_ = &frame;
|
||||
|
||||
frame.addView(impl.mainView_.get());
|
||||
|
||||
SfizzSettings settings;
|
||||
int zoom = atoi(settings.load_or("default_zoom", "100").c_str());
|
||||
impl.setZoom(zoom);
|
||||
fprintf(stderr, "[sfizz] zoom factor: %f\n", impl.frame_->getZoom());
|
||||
|
||||
impl.frameDisabler_ = makeOwned<SFrameDisabler>(&frame);
|
||||
|
||||
impl.memQueryTimer_ = makeOwned<CVSTGUITimer>([this](CVSTGUITimer*) {
|
||||
|
|
@ -1167,6 +1184,7 @@ void Editor::Impl::createFrameContents()
|
|||
adjustMinMaxToEditRange(freewheelingSampleQualitySlider_, EditId::FreewheelingSampleQuality);
|
||||
adjustMinMaxToEditRange(freewheelingOscillatorQualitySlider_, EditId::FreewheelingOscillatorQuality);
|
||||
adjustMinMaxToEditRange(sustainCancelsReleaseCheckbox_, EditId::SustainCancelsRelease);
|
||||
adjustMinMaxToEditRange(zoomMenu_, EditId::UIZoom);
|
||||
|
||||
for (int value : {1, 2, 4, 8, 16, 32, 64, 96, 128, 160, 192, 224, 256})
|
||||
numVoicesSlider_->addEntry(std::to_string(value), value);
|
||||
|
|
@ -1175,6 +1193,7 @@ void Editor::Impl::createFrameContents()
|
|||
int value = 1 << log2value;
|
||||
oversamplingSlider_->addEntry(std::to_string(value) + "x", log2value);
|
||||
}
|
||||
|
||||
oversamplingSlider_->setValueToStringFunction2(
|
||||
[](float value, std::string& result, CParamDisplay*) -> bool
|
||||
{
|
||||
|
|
@ -1182,6 +1201,17 @@ void Editor::Impl::createFrameContents()
|
|||
return true;
|
||||
});
|
||||
|
||||
for (int value : { 100, 125, 150, 175, 200, 225, 250, 275, 300 }) {
|
||||
zoomMenu_->addEntry(std::to_string(value) + "%", value);
|
||||
}
|
||||
|
||||
zoomMenu_->setValueToStringFunction2(
|
||||
[](float value, std::string& result, CParamDisplay*) -> bool
|
||||
{
|
||||
result = std::to_string(static_cast<int>(value) * 100) + "%";
|
||||
return true;
|
||||
});
|
||||
|
||||
for (int log2value = 10; log2value <= 16; ++log2value) {
|
||||
int value = 1 << log2value;
|
||||
char text[256];
|
||||
|
|
@ -1978,6 +2008,29 @@ void Editor::Impl::setActivePanel(unsigned panelId)
|
|||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::setZoom(int zoom)
|
||||
{
|
||||
if (!zoomMenu_)
|
||||
return;
|
||||
|
||||
float zoomFactor = static_cast<float>(zoom) / 100;
|
||||
|
||||
std::vector<int> values =
|
||||
{ 100, 125, 150, 175, 200, 225, 250, 275, 300 };
|
||||
|
||||
size_t pos = std::distance(values.cbegin(),
|
||||
find(values.cbegin(), values.cend(), zoom));
|
||||
|
||||
if (pos < values.size()) {
|
||||
zoom_ = zoomFactor;
|
||||
zoomMenu_->setCurrent(pos);
|
||||
frame_->setZoom(zoom_);
|
||||
} else {
|
||||
zoom_ = 1.0f;
|
||||
zoomMenu_->setCurrent(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::Impl::formatLabel(CTextLabel* label, const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
|
@ -2159,6 +2212,26 @@ void Editor::Impl::valueChanged(CControl* ctl)
|
|||
}
|
||||
break;
|
||||
|
||||
case kTagZoomMenu: {
|
||||
std::vector<float> values =
|
||||
{ 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0 };
|
||||
|
||||
auto zoom = values.at(value);
|
||||
zoom_ = zoom;
|
||||
#if 0
|
||||
fprintf(stderr, "[sfizz] valueChanged: %f\n", zoom_);
|
||||
// TODO: Recreate frame with the new size
|
||||
frame_->setZoom(zoom_);
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case kTagSetDefaultZoom: {
|
||||
SfizzSettings settings;
|
||||
char zoom[64];
|
||||
sprintf(zoom, "%i", static_cast<int>(zoom_ * 100));
|
||||
zoom[sizeof(zoom) - 1] = '\0';
|
||||
settings.store("default_zoom", zoom);
|
||||
} break;
|
||||
default:
|
||||
if (tag >= kTagFirstChangePanel && tag <= kTagLastChangePanel) {
|
||||
int panelId = tag - kTagFirstChangePanel;
|
||||
|
|
|
|||
|
|
@ -228,16 +228,24 @@ view__49->addView(view__87);
|
|||
auto* const view__88 = createValueMenu(CRect(430, 110, 510, 135), kTagSetFreewheelingOscillatorQuality, "", kCenterText, 14);
|
||||
freewheelingOscillatorQualitySlider_ = view__88;
|
||||
view__49->addView(view__88);
|
||||
auto* const view__89 = createPiano(CRect(0, 410, 800, 480), -1, "", kCenterText, 16);
|
||||
piano_ = view__89;
|
||||
view__0->addView(view__89);
|
||||
auto* const view__90 = createLogicalGroup(CRect(5, 110, 795, 410), -1, "", kCenterText, 14);
|
||||
subPanels_[kPanelGeneral] = view__90;
|
||||
view__0->addView(view__90);
|
||||
view__90->setVisible(false);
|
||||
auto* const view__89 = createLabel(CRect(550, 85, 645, 110), -1, "Zoom", kLeftText, 12);
|
||||
view__49->addView(view__89);
|
||||
auto* const view__90 = createOptionMenu(CRect(675, 85, 775, 110), kTagZoomMenu, "", kCenterText, 12);
|
||||
zoomMenu_ = view__90;
|
||||
view__49->addView(view__90);
|
||||
auto* const view__91 = createValueButton(CRect(675, 110, 775, 135), kTagSetDefaultZoom, "Set Default", kCenterText, 12);
|
||||
defaultZoomButton_ = view__91;
|
||||
view__49->addView(view__91);
|
||||
auto* const view__92 = createPiano(CRect(0, 410, 800, 480), -1, "", kCenterText, 16);
|
||||
piano_ = view__92;
|
||||
view__0->addView(view__92);
|
||||
auto* const view__93 = createLogicalGroup(CRect(5, 110, 795, 410), -1, "", kCenterText, 14);
|
||||
subPanels_[kPanelGeneral] = view__93;
|
||||
view__0->addView(view__93);
|
||||
view__93->setVisible(false);
|
||||
enterPalette(invertedPalette);
|
||||
auto* const view__91 = createHoverBox(CRect(5, 105, 175, 130), -1, "", kCenterText, 14);
|
||||
lblHover_ = view__91;
|
||||
view__0->addView(view__91);
|
||||
view__91->setVisible(false);
|
||||
auto* const view__94 = createHoverBox(CRect(5, 105, 175, 130), -1, "", kCenterText, 14);
|
||||
lblHover_ = view__94;
|
||||
view__0->addView(view__94);
|
||||
view__94->setVisible(false);
|
||||
enterPalette(defaultPalette);
|
||||
|
|
|
|||
|
|
@ -46,6 +46,11 @@
|
|||
#include <lv2/patch/patch.h>
|
||||
#include <lv2/urid/urid.h>
|
||||
#include <lv2/instance-access/instance-access.h>
|
||||
|
||||
#ifndef LV2_UI__scaleFactor
|
||||
#define LV2_UI__scaleFactor LV2_UI_PREFIX "scaleFactor"
|
||||
#endif
|
||||
|
||||
#include <ghc/fs_std.hpp>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
|
@ -113,6 +118,10 @@ struct sfizz_ui_t : EditorController, VSTGUIEditorInterface {
|
|||
LV2_URID patch_set_uri;
|
||||
LV2_URID patch_property_uri;
|
||||
LV2_URID patch_value_uri;
|
||||
#if !defined(__APPLE__)
|
||||
LV2_URID opt_scalefactor_uri;
|
||||
float scale_factor = 0.0f;
|
||||
#endif
|
||||
LV2_URID sfizz_sfz_file_uri;
|
||||
LV2_URID sfizz_scala_file_uri;
|
||||
LV2_URID sfizz_osc_blob_uri;
|
||||
|
|
@ -180,6 +189,7 @@ instantiate(const LV2UI_Descriptor *descriptor,
|
|||
|
||||
LV2_URID_Map *map = nullptr;
|
||||
LV2_URID_Unmap *unmap = nullptr;
|
||||
const LV2_Options_Option* options = nullptr;
|
||||
|
||||
for (const LV2_Feature *const *f = features; *f; f++)
|
||||
{
|
||||
|
|
@ -195,6 +205,8 @@ instantiate(const LV2UI_Descriptor *descriptor,
|
|||
parentWindowId = (**f).data;
|
||||
else if (!strcmp((**f).URI, LV2_INSTANCE_ACCESS_URI))
|
||||
self->plugin = (sfizz_plugin_t *)(**f).data;
|
||||
else if (!strcmp((**f).URI, LV2_OPTIONS__options))
|
||||
options = (const LV2_Options_Option*)(**f).data; // scaleFactor only ATM
|
||||
}
|
||||
|
||||
// The map feature is required
|
||||
|
|
@ -213,6 +225,9 @@ instantiate(const LV2UI_Descriptor *descriptor,
|
|||
self->atom_path_uri = map->map(map->handle, LV2_ATOM__Path);
|
||||
self->atom_urid_uri = map->map(map->handle, LV2_ATOM__URID);
|
||||
self->midi_event_uri = map->map(map->handle, LV2_MIDI__MidiEvent);
|
||||
#if !defined(__APPLE__)
|
||||
self->opt_scalefactor_uri = map->map(map->handle, LV2_UI__scaleFactor);
|
||||
#endif
|
||||
self->patch_get_uri = map->map(map->handle, LV2_PATCH__Get);
|
||||
self->patch_set_uri = map->map(map->handle, LV2_PATCH__Set);
|
||||
self->patch_property_uri = map->map(map->handle, LV2_PATCH__property);
|
||||
|
|
@ -224,6 +239,22 @@ instantiate(const LV2UI_Descriptor *descriptor,
|
|||
self->sfizz_audio_level_uri = map->map(map->handle, SFIZZ__AudioLevel);
|
||||
self->ccmap.reset(sfizz_lv2_ccmap_create(map));
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
if (options != nullptr) {
|
||||
for (int i=0; options[i].key != 0; ++i)
|
||||
{
|
||||
if (options[i].key == self->opt_scalefactor_uri) {
|
||||
if (options[i].type == self->atom_float_uri) {
|
||||
self->scale_factor = *(const float*)options[i].value;
|
||||
fprintf(stderr, "[sfizz] scale factor: %f\n", self->scale_factor);
|
||||
} else {
|
||||
fprintf(stderr, "[sfizz] Host provides UI scale factor but has wrong value type\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// set up the resource path
|
||||
// * on Linux, this is determined by going 2 folders back from the SO path
|
||||
// name, and appending "Contents/Resources" (not overridable)
|
||||
|
|
@ -281,8 +312,19 @@ instantiate(const LV2UI_Descriptor *descriptor,
|
|||
|
||||
*widget = reinterpret_cast<LV2UI_Widget>(uiFrame->getPlatformFrame()->getPlatformRepresentation());
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
float scaleFactor = uiFrame->getZoom() * self->scale_factor;
|
||||
uiFrame->setZoom(scaleFactor);
|
||||
fprintf(stderr, "[sfizz] zoom factor: %f\n", scaleFactor);
|
||||
|
||||
int width = Editor::viewWidth * scaleFactor;
|
||||
int height = Editor::viewHeight * scaleFactor;
|
||||
#else
|
||||
int width = Editor::viewWidth;
|
||||
int height = Editor::viewHeight;
|
||||
#endif
|
||||
if (self->resize)
|
||||
self->resize->ui_resize(self->resize->handle, Editor::viewWidth, Editor::viewHeight);
|
||||
self->resize->ui_resize(self->resize->handle, width, height);
|
||||
|
||||
// send a request to receive all parameters
|
||||
uint8_t buffer[256];
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
@prefix lv2: <http://lv2plug.in/ns/lv2core#> .
|
||||
@prefix opts: <http://lv2plug.in/ns/ext/options#> .
|
||||
@prefix ui: <http://lv2plug.in/ns/extensions/ui#> .
|
||||
@prefix urid: <http://lv2plug.in/ns/ext/urid#> .
|
||||
|
||||
|
|
@ -10,6 +11,7 @@
|
|||
lv2:optionalFeature ui:resize ;
|
||||
lv2:optionalFeature ui:parent ;
|
||||
lv2:optionalFeature ui:touch ;
|
||||
opts:supportedOption ui:scaleFactor ;
|
||||
lv2:requiredFeature urid:map ;
|
||||
lv2:requiredFeature urid:unmap ;
|
||||
lv2:requiredFeature <http://lv2plug.in/ns/ext/instance-access> .
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue