Version 1.41

Ok, this one’s been a long time coming, but I’ve finally got a new version out!

Changes are:

* The FLAC and Ogg-Vorbis libraries are now embedded and integrated into the juce build. Previously these could only be used if you linked to their library files, which needed building separately, but now it all just works without any external dependencies.
* Jucer: a very useful change allows each co-ordinate of a component to now be made relative to another component instead of the parent, allowing some complex layout behaviour.
* Handy new macro: numElementsInArray()
* Improved menu highlighting of custom menu components
* Win32 windowing changes to avoid problems with plugins messing up their host's keyboard accelerators
* New class: ApplicationProperties - this is a handy singleton for managing PropertyFile objects when you need both user-specific settings and settings that are common to all users of a machine
* Extra options for PopupMenu to allow more control over the width and number of columns used. Note that there's a small change to the prototype of LookAndFeel::getIdealPopupMenuItemSize, in case you've overridden this in your code
* For consistency, changed the ComboBox to use a normal menu as its popup component, instead of the slightly-different component it had been using. This also involved ditching a load of LookAndFeel methods that were for drawing the old popup.
* Tweaked the AudioDeviceSelectorComponent to give more flexible control over which channels are enabled in a multi-channel soundcard
* Linux + Mac: added a sockets-based HTTP stream class, so that linux now has this functionality. On the Mac, this replaces the old version which used deprecated OS functions (and which kept randomly crashing deep inside Apple's HTTP code)
* Altered the AudioFormat::createWriterFor method to take an OutputStream rather than a FileOutputStream - if you've written a custom AudioFormat you'll have to tweak your method prototypes
* More efficient zip file parsing
* Renamed MemoryBlock::to64BitEncoding and MemoryBlock::from64BitEncoding because they're a misnomer, and I must have been a bit muddled when I wrote those. They're now called toBase64Encoding and fromBase64Encoding.
* New methods: String::indexOfAnyOf and lastIndexOfAnyOf
* Changes to the prototype of File::findChildFiles, DirectoryIterator, and a couple of other related methods, so that you can use an enum to specify whether to search for files, directories, or both.
* Added some methods to ListBox and TableListBox to return the position of rows and cells
* Added a method to allow easy drag-and-dropping of treeview items
* Added support for the numeric keypad in KeyPress
* Added methods to create custom buttons in TabbedComponents, and to save/restore the scroll position of a ListBox
* Fixed whitespace display in a password textbox
* Linux: added support for dealing with drag-and-dropped files (thanks to kraken for the code behind that one!)
* Lots of other miscellaneous changes and fixes that have come up on the forum recently, but which I forgot to write down here.

I’ve also put up a new version of the plugin framework with some tweaks, and have updated binarybuilder to work with the latest version.

Enjoy!

sweet… can wait to try it out

here is a feature request, for AsyncUpdater there should be a function to set the minimum time between callbacks.

Ok, that’s an interesting request. Not sure exactly how you’d implement it, but I’ll note it down.

actually this kind of thing doesn’t take care of proxies… i need to use the Url class behind it, any chanches to have a check for getenv(“http_proxy”) / getenv (“ftp_proxy”), if they are defined, then a proxy request will be made (linux) ? (my old version that i posted here handled this case :)).
whatabout a “withProxy (const String& proxyUrl)” function to the Url class ?

EDIT: ah, also localhost have to be converted to 127.0.0.1 but that is a minor issue

for the rest… we waited a long time, but worth the patience !

feature request (don’t kick me) SVN again :slight_smile: i’ll try that with every new version :slight_smile:

apart from that amazing as usual :slight_smile:

actually this kind of thing doesn’t take care of proxies… i need to use the Url class behind it, any chanches to have a check for getenv(“http_proxy”) / getenv (“ftp_proxy”), if they are defined, then a proxy request will be made (linux) ? (my old version that i posted here handled this case :)).

for the rest… we waited a long time, but worth the patience ![/quote]

you handled proxies? I didn’t notice that, sorry - maybe you could email me the code again and I’ll take a look.

[quote]
feature request (don’t kick me) SVN again Smile i’ll try that with every new version Smile [/quote]

Yeah, I know. I opened an account for it on sourceforge more than a year ago, just haven’t made the leap yet…

Just a small bug. I can’t remove an item from the toolbar (the Modal “customize” dialog beeps, when I try to do so)

Thanks Jules.

thanks jules :slight_smile: just in time - i’m just about to install VC++e on my spandly new computer, so it’s right in time to play!

Although i think i may do some tutorial work before i do any real coding.

[quote=“X-Ryl669”]Just a small bug. I can’t remove an item from the toolbar (the Modal “customize” dialog beeps, when I try to do so)

Thanks Jules.[/quote]

drat! That’s a pretty subtle one - needs a couple of tweaks to juce_win32_Windowing.cpp:

                    if (LOWORD (wParam) == WA_CLICKACTIVE
                         && component->isCurrentlyBlockedByAnotherModalComponent())
                    {
                        int mx, my;
                        component->getMouseXYRelative (mx, my);
                        Component* const underMouse = component->getComponentAt (mx, my);

                        if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent())
                            Component::getCurrentlyModalComponent()->inputAttemptWhenModal();

                        return 0;
                    }[/code]

..and also juce_Component.cpp, line 3059:

[code]            cm->getTopLevelComponent()->toFront (false);

Wish I’d spotted that before I did the new release!

I’m doing it kinda like this:

void handleAsyncUpdate()
{
  if (!isTimerRunning())
  {
    uint32 now = Time::getMillisecondCounter();

    if (now - lastUpdate > 250)
    {
      lastUpdate = now;
      handleAsyncUpdateEx();
    }
    else
    {
      startTimer(250 - (now - lastUpdate));
    }
  }
}

void ExternalControllerManager::timerCallback()
{
  stopTimer();

  lastUpdate = Time::getMillisecondCounter();
  handleAsyncUpdateEx();
}

yep, very basically but the idea is there (i’m sure you could do something more clean when looking at the code)…
basically the code is like this (linux)

URLStream::open ()
{
    ...

    char* http_proxy = getenv("http_proxy");
    if (http_proxy != NULL) {
        if (strncmp(http_proxy, "http://", 8)) {
            // all is working well, and we using a proxy for http requests
    }
    }

    char* http_proxy = getenv("http_proxy");
    if (ftp_proxy != NULL) {
        if (strncmp(ftp_proxy, "ftp://", 8)) {
            // all is working well, and we using a proxy for ftp requests
    }
    }

then you should decompose the proxy url and open the socket to that (instead of the original url) selecting one of the 2 proxy urls if you are opening http or ftp.

then you should generate a slightly different header.
instead of doing:

        header << hostPath << T(" HTTP/1.1\r\nHost: ")

               << hostName << ":" << hostPort

               << T("\r\nUser-Agent: JUCE/")

               << JUCE_MAJOR_VERSION << T('.') << JUCE_MINOR_VERSION

               << T("\r\nConnection: Close\r\n");

you should issue a command with original request instead of the hostPath
document location:

        header << " http://www.original.request.com:8080/document.php  HTTP/1.1\r\nHost: " << proxyName << ":" << proxyPort

eventually you could check getenv (“http_proxy_auth”) and add after " HTTP/1.1\r\nHost: proxyip:proxyport" this:

        "\r\nProxy-Authorization: Basic " << Base64Encode (userString +":" + pwdString) << "\r\n\r\n"

then continue with referrer and user-agent and such…

setColour(ComboBox::popupTextColourId , Colours::yellow);
setColour(ComboBox::popupBackgroundColourId, Colours::blue);
setColour(ComboBox::popupHighlightBackgroundColourId, Colours::green);
setColour(ComboBox::popupHighlightedTextColourId, Colours::red);

Is there way to do this still?

Is this supposed to work with the KeyMappingEditorComponent?

I receive the numpad+# message, which is immediately followed by the # message

Thanks kraken, I’ll have a go at that. Though my network doesn’t use a proxy, so I might send you some code to test if that’s ok.

[quote=“G-Mon”] setColour(ComboBox::popupTextColourId , Colours::yellow); setColour(ComboBox::popupBackgroundColourId, Colours::blue); setColour(ComboBox::popupHighlightBackgroundColourId, Colours::green); setColour(ComboBox::popupHighlightedTextColourId, Colours::red);

Is there way to do this still?[/quote]

I changed the combo box to use a normal popup menu for its list, so you can change its colours by using the colour constants from the PopupMenu class. Rather than setting the colours with the combo box setColour method, you’d have to set them in the combo’s look and feel, which the popup menu will use (I should add a comment to explain this).

[quote]Is this supposed to work with the KeyMappingEditorComponent?

I receive the numpad+# message, which is immediately followed by the # message[/quote]

good question - I added it to the KeyPress class, but never actually tried it with key mappings… Will do.

just would like to also lend my voice to this call. perhaps it seems like a small thing to many, easily put off in favour of new actual features to the core, but personally i would prefer to see subversion (or whatever VCS) support before the next new version is released. it is more important to me than any of those new features.

but of course nice work as always. definitely appreciated. :slight_smile:

Here is another idea. It would be good if drop targets could handle their own drawing. It seemed pretty easy to do. Here are the diffs.

[code]> bool isDrawn;
78c79,80
< hasCheckedForExternalDrag (0)

      hasCheckedForExternalDrag (0),
    isDrawn (true)

136,137c138,142
< g.setOpacity (1.0f);
< g.drawImageAt (image, 0, 0);

  if (isDrawn)
  {
  	g.setOpacity (1.0f);
  	g.drawImageAt (image, 0, 0);
  }

242a248,254

  	bool isDrawn_ = !ddt || !ddt->itemHandlesDrawing(dragDesc);
  	if (isDrawn_ != isDrawn)
  	{
  		isDrawn = isDrawn_;
  		repaint();
  	}

[/code]

It is useful for when the drop target wants to give a preview of how dropping an object will affect the drop target.

So basically it’s an option to not draw the dragging image sometimes? ok, sounds like a fair request.

Has it been so difficult to add all numpad keys to the new JUCE release but not just the numerical ones? Julian, can you add the rest of numpad keys to the next release of JUCE? I mean numpad-Divide, numpad-Multiply, numpad-Plus, numpad-Minus, numpad-Dot, numpad-Enter.

Julian, sorry, but I couldn’t find a way to supply my own buttons to the TabbedComponent. Any example?

Is there a way to highlight a treeview item when draging over it? I mean, when drag source is hovering over some droptarget treeview item.

There’s probably a better way of doing it, but if you make your treeview items into custom components (TreeViewItem::createItemComponent ()) you could handle drop target highlighting for each node in that way as you would for any component.

I’ve expected the answer like that.