Skip to content

Commit

Permalink
Working zoom / scale in the AU host
Browse files Browse the repository at this point in the history
  • Loading branch information
baconpaul committed Dec 14, 2018
1 parent 3aeaee8 commit 4dec747
Show file tree
Hide file tree
Showing 6 changed files with 410 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/au/aulayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class SurgeGUIEditor;
class SurgeSynthesizer;
typedef SurgeSynthesizer plugin;

#define GENERATE_AU_LOG
struct AULOG
{
#ifdef GENERATE_AU_LOG
Expand Down
25 changes: 24 additions & 1 deletion src/au/aulayer_cocoaui.mm
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ @interface SurgeNSView : NSView
{
SurgeGUIEditor *editController;
CFRunLoopTimerRef idleTimer;
float lastScale;
}

- (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size;
Expand Down Expand Up @@ -92,8 +93,10 @@ @implementation SurgeNSView
- (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size
{
self = [super initWithFrame: NSMakeRect (0, 0, size.width / 2, size.height / 2)];

idleTimer = nil;
editController = cont;
lastScale = cont->getZoomFactor() / 100.0;
if (self)
{
AULOG::log( "Opening new editor view\n" );
Expand All @@ -105,7 +108,27 @@ - (id) initWithSurge: (SurgeGUIEditor *) cont preferredSize: (NSSize) size
NSRect newSize = NSMakeRect (0, 0, vr->right - vr->left, vr->bottom - vr->top);
[self setFrame:newSize];
}


cont->setZoomCallback( [cont,self]() {
AULOG::log( "In the Zoom Callback back in Cocoa to %d\n", cont->getZoomFactor() );
ERect *vr;
float zf = cont->getZoomFactor() / 100.0;
if (cont->getRect(&vr))
{
NSRect newSize = NSMakeRect (0, 0,
(int)( (vr->right - vr->left) * zf ),
(int)( (vr->bottom - vr->top) * zf ) );
AULOG::log( "Scalining display and unit square by %lf\n", zf );
[self scaleUnitSquareToSize:NSMakeSize( zf / lastScale, zf / lastScale )];
lastScale = zf;

AULOG::log( "Resetting window size\n" );
[self setFrame:newSize];
}

}
);

CFTimeInterval TIMER_INTERVAL = .05; // In SurgeGUISynthesizer.h it uses 50 ms
CFRunLoopTimerContext TimerContext = {0, self, NULL, NULL, NULL};
CFAbsoluteTime FireTime = CFAbsoluteTimeGetCurrent() + TIMER_INTERVAL;
Expand Down
327 changes: 327 additions & 0 deletions src/common/gui/#COscillatorDisplay.cpp#
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
//-------------------------------------------------------------------------------------------------------
// Copyright 2005 Claes Johanson & Vember Audio
//-------------------------------------------------------------------------------------------------------
#include "COscillatorDisplay.h"
#include "Oscillator.h"
#include <time.h>
#include "unitconversion.h"

const float disp_pitch = 90.15f - 48.f;
const int wtbheight = 12;

extern CFontRef surge_minifont;

void COscillatorDisplay::draw(CDrawContext* dc)
{
pdata tp[n_scene_params];
tp[oscdata->pitch.param_id_in_scene].f = 0;
for (int i = 0; i < n_osc_params; i++)
tp[oscdata->p[i].param_id_in_scene].i = oscdata->p[i].val.i;
Oscillator* osc = spawn_osc(oscdata->type.val.i, storage, oscdata, tp);

cdisurf->begin();
cdisurf->clear(0xffffffff);

int w = cdisurf->getWidth();
int h2 = cdisurf->getHeight();
int h = h2;
assert(h < 512);
if (uses_wavetabledata(oscdata->type.val.i))
h -= wtbheight;

unsigned int column[512];
int column_d[512];
float lastval = 0;
int midline = h >> 1;
int topline = midline - 0.4f * h;
int bottomline = midline + 0.4f * h;
const int aa_bs = 4;
const int aa_samples = 1 << aa_bs;
int last_imax = -1, last_imin = -1;
if (osc)
{
// srand(2);
float disp_pitch_rs = disp_pitch + 12.0 * log2(dsamplerate / 44100.0);
bool use_display = osc->allow_display();
if (use_display)
osc->init(disp_pitch_rs, true);
int block_pos = block_size_os;
for (int y = 0; y < h2; y++)
column_d[y] = 0;

for (int x = 0; x < getWidth(); x++)
{
for (int y = 0; y < h2; y++)
column[y] = 0;
for (int s = 0; s < aa_samples; s++)
{
if (use_display && (block_pos >= block_size_os))
{
if (uses_wavetabledata(oscdata->type.val.i))
{
storage->CS_WaveTableData.enter();
osc->process_block(disp_pitch_rs);
block_pos = 0;
storage->CS_WaveTableData.leave();
}
else
{
osc->process_block(disp_pitch_rs);
block_pos = 0;
}
}

float val = 0.f;
if (use_display)
val = -osc->output[block_pos];

val = (float)((0.5f + 0.4f * val) * h);
lastval = val;
float v_min = val;
float v_max = val;

v_min = val - 0.5f;
v_max = val + 0.5f;
int imin = (int)v_min;
int imax = (int)v_max;
float imax_frac = (v_max - imax);
float imin_frac = 1 - (v_min - imin);

if (imax == imin)
imax++;

if (imin < 0)
imin = 0;
int dimax = imax, dimin = imin;

if ((x > 0) || (s > 0))
{
if (dimin > last_imax)
dimin = last_imax;
else if (dimax < last_imin)
dimax = last_imin;
}
dimin = limit_range(dimin, 0, h);
dimax = limit_range(dimax, 0, h);

// int yp = (int)((float)(size.height() * (-osc->output[block_pos]*0.5+0.5)));
// yp = limit_range(yp,0,h-1);

column[dimin] += ((int)((float)imin_frac * 255.f));
column[dimax + 1] += ((int)((float)imax_frac * 255.f));
for (int b = (dimin + 1); b < (dimax + 1); b++)
{
column_d[b & 511] = aa_samples;
}
last_imax = imax;
last_imin = imin;
block_pos++;
for (int y = 0; y < h; y++)
{
if (column_d[y] > 0)
column[y] += 256;
column_d[y]--;
}
}
column[midline] = max((unsigned int)64 << aa_bs, column[midline]);
column[topline] = max((unsigned int)32 << aa_bs, column[topline]);
column[bottomline] = max((unsigned int)32 << aa_bs, column[bottomline]);
for (int y = 0; y < h2; y++)
{
cdisurf->setPixel(x, y, coltable[min((unsigned int)255, (column[y] >> aa_bs))]);
}
}
_aligned_free(osc);
// srand( (unsigned)time( NULL ) );
}
cdisurf->commit();
auto size = getViewSize();
cdisurf->draw(dc, size);

if (uses_wavetabledata(oscdata->type.val.i))
{
CRect wtlbl(size);
wtlbl.right -= 1;
wtlbl.top = wtlbl.bottom - wtbheight;
rmenu = wtlbl;
rmenu.inset(12, 0);
char wttxt[256];

storage->CS_WaveTableData.enter();

int wtid = oscdata->wt.current_id;
if ((wtid >= 0) && (wtid < storage->wt_list.size()))
{
strcpy(wttxt, storage->wt_list.at(wtid).name.c_str());
}
else if (oscdata->wt.flags & wtf_is_sample)
{
strcpy(wttxt, "(Patch Sample)");
}
else
{
strcpy(wttxt, "(Patch Wavetable)");
}

storage->CS_WaveTableData.leave();

char* r = strrchr(wttxt, '.');
if (r)
*r = 0;
// VSTGUI::CColor fgcol = cdisurf->int_to_ccol(coltable[255]);
VSTGUI::CColor fgcol = {0xff, 0xA0, 0x10, 0xff};
dc->setFillColor(fgcol);
dc->drawRect(rmenu, kDrawFilled);
dc->setFontColor(kBlackCColor);
dc->setFont(surge_minifont);
// strupr(wttxt);
dc->drawString(wttxt, rmenu, kCenterText, false);

/*CRect wtlbl_status(size);
wtlbl_status.bottom = wtlbl_status.top + wtbheight;
dc->setFontColor(kBlackCColor);
if(oscdata->wt.flags & wtf_is_sample) dc->drawString("IS
SAMPLE",wtlbl_status,false,kRightText);*/

rnext = wtlbl;
rnext.left = rmenu.right; //+ 1;
rprev = wtlbl;
rprev.right = rmenu.left; //- 1;
dc->setFillColor(fgcol);
dc->drawRect(rprev, kDrawFilled);
dc->drawRect(rnext, kDrawFilled);
dc->setFrameColor(kBlackCColor);
for (int a = 0; a < 4; a++)
{
CPoint p1(rprev.left + 4 + a, rprev.top + (rprev.getHeight() * 0.5) - a);
CPoint p2 = p1;
p2.y += (a << 1) + 1;
dc->drawLine(p1, p2);

CPoint p3(rnext.right - 4 - a, rnext.top + (rnext.getHeight() * 0.5) - a);
CPoint p4 = p3;
p4.y += (a << 1) + 1;
dc->drawLine(p3, p4);
}
}

setDirty(false);
}

bool COscillatorDisplay::onDrop(IDataPackage* drag, const CPoint& where)
{
/*long size,type;
char *filename = (char*)drag->first(size,type);
//while(filename)
if(filename)
{
if(type == CDragContainer::kFile)
{
strncpy(oscdata->wt.queue_filename, filename, 255);
}
// filename = (char*)drag->next(size,type);
}*/
return true;
}

CMouseEventResult COscillatorDisplay::onMouseDown(CPoint& where, const CButtonState& button)
{
if (!(button & kLButton))
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;

assert(oscdata);

if (!uses_wavetabledata(oscdata->type.val.i) || (where.y < rmenu.top))
{
controlstate = 1;
lastpos.x = where.x;
return kMouseEventHandled;
}
else if (uses_wavetabledata(oscdata->type.val.i))
{
int diff = 0;
if (rprev.pointInside(where))
{
diff = -1;
}
else if (rnext.pointInside(where))
{
diff = 1;
}
if (diff)
{
oscdata->wt.queue_id =
(oscdata->wt.current_id + diff + storage->wt_list.size()) % storage->wt_list.size();
}
else if (rmenu.pointInside(where))
{
CRect menurect(0, 0, 0, 0);
menurect.offset(where.x, where.y);
COptionMenu* contextMenu = new COptionMenu(menurect, 0, 0, 0, 0, kNoDrawStyle);

for (int c = 0; c < storage->wt_category.size(); c++)
{
char name[namechars];
COptionMenu* subMenu = new COptionMenu(getViewSize(), 0, c, 0, 0, kNoDrawStyle);
subMenu->setNbItemsPerColumn(32);
int sub = 0;
int p;
for (p = 0; p < storage->wt_list.size(); p++)
{
if (storage->wt_list[p].category == c)
{
sprintf(name, "%s", storage->wt_list[p].name.c_str());
auto actionItem = new CCommandMenuItem(name);
auto action = [this, p](CCommandMenuItem* item) { this->loadWavetable(p); };

actionItem->setActions(action, nullptr);
subMenu->addEntry(actionItem);

sub++;
}
}
strncpy(name, storage->wt_category[c].name.c_str(), namechars);
contextMenu->addEntry(subMenu, name);

subMenu->forget(); // viktigt, så att refcounter blir rätt
}

getFrame()->addView(contextMenu); // add to frame
contextMenu->setDirty();
-contextMenu->popup();
contextMenu->onMouseDown(where, kLButton); // <-- modal menu loop is here
// getFrame()->looseFocus(pContext);

getFrame()->removeView(contextMenu, true); // remove from frame and forget
}
}
return kMouseDownEventHandledButDontNeedMovedOrUpEvents;
}

void COscillatorDisplay::loadWavetable(int id)
{
if (id >= 0 && (id < storage->wt_list.size()))
{
oscdata->wt.queue_id = id;
}
}

CMouseEventResult COscillatorDisplay::onMouseUp(CPoint& where, const CButtonState& buttons)
{
if (controlstate)
{
controlstate = 0;
}
return kMouseEventHandled;
}
CMouseEventResult COscillatorDisplay::onMouseMoved(CPoint& where, const CButtonState& buttons)
{
if (controlstate)
{
/*oscdata->startphase.val.f -= 0.005f * (where.x - lastpos.x);
oscdata->startphase.val.f = limit_range(oscdata->startphase.val.f,0.f,1.f);
lastpos.x = where.x;
invalid();*/
}
return kMouseEventHandled;
}
1 change: 1 addition & 0 deletions src/common/gui/.#COscillatorDisplay.cpp
Loading

0 comments on commit 4dec747

Please sign in to comment.