Browse Source

tags/2021-05-28
jules 17 years ago
parent
commit
5572be0248
15 changed files with 8255 additions and 8255 deletions
  1. +3
    -3
      src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp
  2. +1
    -1
      src/juce_appframework/events/juce_Message.h
  3. +433
    -433
      src/juce_appframework/gui/components/controls/juce_Label.cpp
  4. +2
    -2
      src/juce_appframework/gui/components/controls/juce_Label.h
  5. +1368
    -1368
      src/juce_appframework/gui/components/controls/juce_Slider.cpp
  6. +2647
    -2647
      src/juce_appframework/gui/components/controls/juce_TextEditor.cpp
  7. +707
    -707
      src/juce_appframework/gui/components/controls/juce_TextEditor.h
  8. +1
    -1
      src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp
  9. +25
    -25
      src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp
  10. +442
    -442
      src/juce_appframework/gui/components/properties/juce_PropertyPanel.cpp
  11. +18
    -18
      src/juce_appframework/gui/components/special/juce_AudioDeviceSelectorComponent.cpp
  12. +1
    -1
      src/juce_appframework/gui/components/special/juce_AudioDeviceSelectorComponent.h
  13. +2228
    -2228
      src/juce_appframework/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
  14. +378
    -378
      src/juce_appframework/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp
  15. +1
    -1
      src/juce_core/containers/juce_ArrayAllocationBase.h

+ 3
- 3
src/juce_appframework/audio/devices/juce_AudioDeviceManager.cpp View File

@@ -161,7 +161,7 @@ const String AudioDeviceManager::initialise (const int numInputChannelsNeeded,
if (e->getStringAttribute (T("audioDeviceName")).isNotEmpty())
{
setup.inputDeviceName = setup.outputDeviceName
setup.inputDeviceName = setup.outputDeviceName
= e->getStringAttribute (T("audioDeviceName"));
}
else
@@ -425,7 +425,7 @@ const String AudioDeviceManager::setAudioDeviceSetup (const AudioDeviceSetup& ne
error = currentAudioDevice->open (inputChannels,
outputChannels,
currentSetup.sampleRate,
currentSetup.sampleRate,
currentSetup.bufferSize);
if (error.isEmpty())
@@ -511,7 +511,7 @@ void AudioDeviceManager::restartLastAudioDevice()
{
if (currentAudioDevice == 0)
{
if (currentSetup.inputDeviceName.isEmpty()
if (currentSetup.inputDeviceName.isEmpty()
&& currentSetup.outputDeviceName.isEmpty())
{
// This method will only reload the last device that was running


+ 1
- 1
src/juce_appframework/events/juce_Message.h View File

@@ -33,7 +33,7 @@
#define __JUCE_MESSAGE_JUCEHEADER__
class MessageListener;
class MessageManager;
//==============================================================================
/** The base class for objects that can be delivered to a MessageListener.


+ 433
- 433
src/juce_appframework/gui/components/controls/juce_Label.cpp View File

@@ -1,433 +1,433 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_Label.h"
#include "../LookAndFeel/juce_LookAndFeel.h"
//==============================================================================
Label::Label (const String& componentName,
const String& labelText)
: Component (componentName),
text (labelText),
font (15.0f),
justification (Justification::centredLeft),
editor (0),
listeners (2),
ownerComponent (0),
deletionWatcher (0),
horizontalBorderSize (3),
verticalBorderSize (1),
minimumHorizontalScale (0.7f),
editSingleClick (false),
editDoubleClick (false),
lossOfFocusDiscardsChanges (false)
{
setColour (TextEditor::textColourId, Colours::black);
setColour (TextEditor::backgroundColourId, Colours::transparentBlack);
setColour (TextEditor::outlineColourId, Colours::transparentBlack);
}
Label::~Label()
{
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
ownerComponent->removeComponentListener (this);
deleteAndZero (deletionWatcher);
if (editor != 0)
delete editor;
}
//==============================================================================
void Label::setText (const String& newText,
const bool broadcastChangeMessage)
{
hideEditor (true);
if (text != newText)
{
text = newText;
if (broadcastChangeMessage)
triggerAsyncUpdate();
repaint();
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
componentMovedOrResized (*ownerComponent, true, true);
}
}
const String Label::getText (const bool returnActiveEditorContents) const throw()
{
return (returnActiveEditorContents && isBeingEdited())
? editor->getText()
: text;
}
void Label::setFont (const Font& newFont) throw()
{
font = newFont;
repaint();
}
const Font& Label::getFont() const throw()
{
return font;
}
void Label::setEditable (const bool editOnSingleClick,
const bool editOnDoubleClick,
const bool lossOfFocusDiscardsChanges_) throw()
{
editSingleClick = editOnSingleClick;
editDoubleClick = editOnDoubleClick;
lossOfFocusDiscardsChanges = lossOfFocusDiscardsChanges_;
setWantsKeyboardFocus (editOnSingleClick || editOnDoubleClick);
setFocusContainer (editOnSingleClick || editOnDoubleClick);
}
void Label::setJustificationType (const Justification& justification_) throw()
{
justification = justification_;
repaint();
}
void Label::setBorderSize (int h, int v)
{
horizontalBorderSize = h;
verticalBorderSize = v;
repaint();
}
//==============================================================================
void Label::attachToComponent (Component* owner,
const bool onLeft)
{
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
ownerComponent->removeComponentListener (this);
deleteAndZero (deletionWatcher);
ownerComponent = owner;
leftOfOwnerComp = onLeft;
if (ownerComponent != 0)
{
deletionWatcher = new ComponentDeletionWatcher (owner);
setVisible (owner->isVisible());
ownerComponent->addComponentListener (this);
componentParentHierarchyChanged (*ownerComponent);
componentMovedOrResized (*ownerComponent, true, true);
}
}
void Label::componentMovedOrResized (Component& component,
bool /*wasMoved*/,
bool /*wasResized*/)
{
if (leftOfOwnerComp)
{
setSize (jmin (getFont().getStringWidth (text) + 8, component.getX()),
component.getHeight());
setTopRightPosition (component.getX(), component.getY());
}
else
{
setSize (component.getWidth(),
8 + roundFloatToInt (getFont().getHeight()));
setTopLeftPosition (component.getX(), component.getY() - getHeight());
}
}
void Label::componentParentHierarchyChanged (Component& component)
{
if (component.getParentComponent() != 0)
component.getParentComponent()->addChildComponent (this);
}
void Label::componentVisibilityChanged (Component& component)
{
setVisible (component.isVisible());
}
//==============================================================================
void Label::textWasEdited()
{
}
void Label::showEditor()
{
if (editor == 0)
{
addAndMakeVisible (editor = createEditorComponent());
editor->setText (getText());
editor->addListener (this);
editor->grabKeyboardFocus();
editor->setHighlightedRegion (0, text.length());
editor->addListener (this);
resized();
repaint();
enterModalState();
editor->grabKeyboardFocus();
}
}
bool Label::updateFromTextEditorContents()
{
jassert (editor != 0);
const String newText (editor->getText());
if (text != newText)
{
text = newText;
triggerAsyncUpdate();
repaint();
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
componentMovedOrResized (*ownerComponent, true, true);
return true;
}
return false;
}
void Label::hideEditor (const bool discardCurrentEditorContents)
{
if (editor != 0)
{
const bool changed = (! discardCurrentEditorContents)
&& updateFromTextEditorContents();
deleteAndZero (editor);
repaint();
if (changed)
textWasEdited();
exitModalState (0);
}
}
void Label::inputAttemptWhenModal()
{
if (editor != 0)
{
if (lossOfFocusDiscardsChanges)
textEditorEscapeKeyPressed (*editor);
else
textEditorReturnKeyPressed (*editor);
}
}
bool Label::isBeingEdited() const throw()
{
return editor != 0;
}
TextEditor* Label::createEditorComponent()
{
TextEditor* const ed = new TextEditor (getName());
ed->setFont (font);
// copy these colours from our own settings..
const int cols[] = { TextEditor::backgroundColourId,
TextEditor::textColourId,
TextEditor::highlightColourId,
TextEditor::highlightedTextColourId,
TextEditor::caretColourId,
TextEditor::outlineColourId,
TextEditor::focusedOutlineColourId,
TextEditor::shadowColourId };
for (int i = 0; i < numElementsInArray (cols); ++i)
ed->setColour (cols[i], findColour (cols[i]));
return ed;
}
//==============================================================================
void Label::paint (Graphics& g)
{
getLookAndFeel().drawLabel (g, *this);
}
void Label::mouseUp (const MouseEvent& e)
{
if (editSingleClick
&& e.mouseWasClicked()
&& contains (e.x, e.y)
&& ! e.mods.isPopupMenu())
{
showEditor();
}
}
void Label::mouseDoubleClick (const MouseEvent& e)
{
if (editDoubleClick && ! e.mods.isPopupMenu())
showEditor();
}
void Label::resized()
{
if (editor != 0)
editor->setBoundsInset (BorderSize (0));
}
void Label::focusGained (FocusChangeType cause)
{
if (editSingleClick && cause == focusChangedByTabKey)
showEditor();
}
void Label::enablementChanged()
{
repaint();
}
void Label::colourChanged()
{
repaint();
}
//==============================================================================
// We'll use a custom focus traverser here to make sure focus goes from the
// text editor to another component rather than back to the label itself.
class LabelKeyboardFocusTraverser : public KeyboardFocusTraverser
{
public:
LabelKeyboardFocusTraverser() {}
Component* getNextComponent (Component* current)
{
return KeyboardFocusTraverser::getNextComponent (dynamic_cast <TextEditor*> (current) != 0
? current->getParentComponent() : current);
}
Component* getPreviousComponent (Component* current)
{
return KeyboardFocusTraverser::getPreviousComponent (dynamic_cast <TextEditor*> (current) != 0
? current->getParentComponent() : current);
}
};
KeyboardFocusTraverser* Label::createFocusTraverser()
{
return new LabelKeyboardFocusTraverser();
}
//==============================================================================
void Label::addListener (LabelListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
}
void Label::removeListener (LabelListener* const listener) throw()
{
listeners.removeValue (listener);
}
void Label::handleAsyncUpdate()
{
for (int i = listeners.size(); --i >= 0;)
{
((LabelListener*) listeners.getUnchecked (i))->labelTextChanged (this);
i = jmin (i, listeners.size());
}
}
//==============================================================================
void Label::textEditorTextChanged (TextEditor& ed)
{
if (editor != 0)
{
jassert (&ed == editor);
if (! (hasKeyboardFocus (true) || isCurrentlyBlockedByAnotherModalComponent()))
{
if (lossOfFocusDiscardsChanges)
textEditorEscapeKeyPressed (ed);
else
textEditorReturnKeyPressed (ed);
}
}
}
void Label::textEditorReturnKeyPressed (TextEditor& ed)
{
if (editor != 0)
{
jassert (&ed == editor);
(void) ed;
const bool changed = updateFromTextEditorContents();
hideEditor (true);
if (changed)
textWasEdited();
}
}
void Label::textEditorEscapeKeyPressed (TextEditor& ed)
{
if (editor != 0)
{
jassert (&ed == editor);
(void) ed;
editor->setText (text, false);
hideEditor (true);
}
}
void Label::textEditorFocusLost (TextEditor& ed)
{
textEditorTextChanged (ed);
}
END_JUCE_NAMESPACE
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_Label.h"
#include "../LookAndFeel/juce_LookAndFeel.h"
//==============================================================================
Label::Label (const String& componentName,
const String& labelText)
: Component (componentName),
text (labelText),
font (15.0f),
justification (Justification::centredLeft),
editor (0),
listeners (2),
ownerComponent (0),
deletionWatcher (0),
horizontalBorderSize (3),
verticalBorderSize (1),
minimumHorizontalScale (0.7f),
editSingleClick (false),
editDoubleClick (false),
lossOfFocusDiscardsChanges (false)
{
setColour (TextEditor::textColourId, Colours::black);
setColour (TextEditor::backgroundColourId, Colours::transparentBlack);
setColour (TextEditor::outlineColourId, Colours::transparentBlack);
}
Label::~Label()
{
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
ownerComponent->removeComponentListener (this);
deleteAndZero (deletionWatcher);
if (editor != 0)
delete editor;
}
//==============================================================================
void Label::setText (const String& newText,
const bool broadcastChangeMessage)
{
hideEditor (true);
if (text != newText)
{
text = newText;
if (broadcastChangeMessage)
triggerAsyncUpdate();
repaint();
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
componentMovedOrResized (*ownerComponent, true, true);
}
}
const String Label::getText (const bool returnActiveEditorContents) const throw()
{
return (returnActiveEditorContents && isBeingEdited())
? editor->getText()
: text;
}
void Label::setFont (const Font& newFont) throw()
{
font = newFont;
repaint();
}
const Font& Label::getFont() const throw()
{
return font;
}
void Label::setEditable (const bool editOnSingleClick,
const bool editOnDoubleClick,
const bool lossOfFocusDiscardsChanges_) throw()
{
editSingleClick = editOnSingleClick;
editDoubleClick = editOnDoubleClick;
lossOfFocusDiscardsChanges = lossOfFocusDiscardsChanges_;
setWantsKeyboardFocus (editOnSingleClick || editOnDoubleClick);
setFocusContainer (editOnSingleClick || editOnDoubleClick);
}
void Label::setJustificationType (const Justification& justification_) throw()
{
justification = justification_;
repaint();
}
void Label::setBorderSize (int h, int v)
{
horizontalBorderSize = h;
verticalBorderSize = v;
repaint();
}
//==============================================================================
void Label::attachToComponent (Component* owner,
const bool onLeft)
{
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
ownerComponent->removeComponentListener (this);
deleteAndZero (deletionWatcher);
ownerComponent = owner;
leftOfOwnerComp = onLeft;
if (ownerComponent != 0)
{
deletionWatcher = new ComponentDeletionWatcher (owner);
setVisible (owner->isVisible());
ownerComponent->addComponentListener (this);
componentParentHierarchyChanged (*ownerComponent);
componentMovedOrResized (*ownerComponent, true, true);
}
}
void Label::componentMovedOrResized (Component& component,
bool /*wasMoved*/,
bool /*wasResized*/)
{
if (leftOfOwnerComp)
{
setSize (jmin (getFont().getStringWidth (text) + 8, component.getX()),
component.getHeight());
setTopRightPosition (component.getX(), component.getY());
}
else
{
setSize (component.getWidth(),
8 + roundFloatToInt (getFont().getHeight()));
setTopLeftPosition (component.getX(), component.getY() - getHeight());
}
}
void Label::componentParentHierarchyChanged (Component& component)
{
if (component.getParentComponent() != 0)
component.getParentComponent()->addChildComponent (this);
}
void Label::componentVisibilityChanged (Component& component)
{
setVisible (component.isVisible());
}
//==============================================================================
void Label::textWasEdited()
{
}
void Label::showEditor()
{
if (editor == 0)
{
addAndMakeVisible (editor = createEditorComponent());
editor->setText (getText());
editor->addListener (this);
editor->grabKeyboardFocus();
editor->setHighlightedRegion (0, text.length());
editor->addListener (this);
resized();
repaint();
enterModalState();
editor->grabKeyboardFocus();
}
}
bool Label::updateFromTextEditorContents()
{
jassert (editor != 0);
const String newText (editor->getText());
if (text != newText)
{
text = newText;
triggerAsyncUpdate();
repaint();
if (ownerComponent != 0 && ! deletionWatcher->hasBeenDeleted())
componentMovedOrResized (*ownerComponent, true, true);
return true;
}
return false;
}
void Label::hideEditor (const bool discardCurrentEditorContents)
{
if (editor != 0)
{
const bool changed = (! discardCurrentEditorContents)
&& updateFromTextEditorContents();
deleteAndZero (editor);
repaint();
if (changed)
textWasEdited();
exitModalState (0);
}
}
void Label::inputAttemptWhenModal()
{
if (editor != 0)
{
if (lossOfFocusDiscardsChanges)
textEditorEscapeKeyPressed (*editor);
else
textEditorReturnKeyPressed (*editor);
}
}
bool Label::isBeingEdited() const throw()
{
return editor != 0;
}
TextEditor* Label::createEditorComponent()
{
TextEditor* const ed = new TextEditor (getName());
ed->setFont (font);
// copy these colours from our own settings..
const int cols[] = { TextEditor::backgroundColourId,
TextEditor::textColourId,
TextEditor::highlightColourId,
TextEditor::highlightedTextColourId,
TextEditor::caretColourId,
TextEditor::outlineColourId,
TextEditor::focusedOutlineColourId,
TextEditor::shadowColourId };
for (int i = 0; i < numElementsInArray (cols); ++i)
ed->setColour (cols[i], findColour (cols[i]));
return ed;
}
//==============================================================================
void Label::paint (Graphics& g)
{
getLookAndFeel().drawLabel (g, *this);
}
void Label::mouseUp (const MouseEvent& e)
{
if (editSingleClick
&& e.mouseWasClicked()
&& contains (e.x, e.y)
&& ! e.mods.isPopupMenu())
{
showEditor();
}
}
void Label::mouseDoubleClick (const MouseEvent& e)
{
if (editDoubleClick && ! e.mods.isPopupMenu())
showEditor();
}
void Label::resized()
{
if (editor != 0)
editor->setBoundsInset (BorderSize (0));
}
void Label::focusGained (FocusChangeType cause)
{
if (editSingleClick && cause == focusChangedByTabKey)
showEditor();
}
void Label::enablementChanged()
{
repaint();
}
void Label::colourChanged()
{
repaint();
}
//==============================================================================
// We'll use a custom focus traverser here to make sure focus goes from the
// text editor to another component rather than back to the label itself.
class LabelKeyboardFocusTraverser : public KeyboardFocusTraverser
{
public:
LabelKeyboardFocusTraverser() {}
Component* getNextComponent (Component* current)
{
return KeyboardFocusTraverser::getNextComponent (dynamic_cast <TextEditor*> (current) != 0
? current->getParentComponent() : current);
}
Component* getPreviousComponent (Component* current)
{
return KeyboardFocusTraverser::getPreviousComponent (dynamic_cast <TextEditor*> (current) != 0
? current->getParentComponent() : current);
}
};
KeyboardFocusTraverser* Label::createFocusTraverser()
{
return new LabelKeyboardFocusTraverser();
}
//==============================================================================
void Label::addListener (LabelListener* const listener) throw()
{
jassert (listener != 0);
if (listener != 0)
listeners.add (listener);
}
void Label::removeListener (LabelListener* const listener) throw()
{
listeners.removeValue (listener);
}
void Label::handleAsyncUpdate()
{
for (int i = listeners.size(); --i >= 0;)
{
((LabelListener*) listeners.getUnchecked (i))->labelTextChanged (this);
i = jmin (i, listeners.size());
}
}
//==============================================================================
void Label::textEditorTextChanged (TextEditor& ed)
{
if (editor != 0)
{
jassert (&ed == editor);
if (! (hasKeyboardFocus (true) || isCurrentlyBlockedByAnotherModalComponent()))
{
if (lossOfFocusDiscardsChanges)
textEditorEscapeKeyPressed (ed);
else
textEditorReturnKeyPressed (ed);
}
}
}
void Label::textEditorReturnKeyPressed (TextEditor& ed)
{
if (editor != 0)
{
jassert (&ed == editor);
(void) ed;
const bool changed = updateFromTextEditorContents();
hideEditor (true);
if (changed)
textWasEdited();
}
}
void Label::textEditorEscapeKeyPressed (TextEditor& ed)
{
if (editor != 0)
{
jassert (&ed == editor);
(void) ed;
editor->setText (text, false);
hideEditor (true);
}
}
void Label::textEditorFocusLost (TextEditor& ed)
{
textEditorTextChanged (ed);
}
END_JUCE_NAMESPACE

+ 2
- 2
src/juce_appframework/gui/components/controls/juce_Label.h View File

@@ -154,11 +154,11 @@ public:
*/
void setBorderSize (int horizontalBorder, int verticalBorder);
/**
/** Returns the size of the horizontal gap being left around the text.
*/
int getHorizontalBorderSize() const throw() { return horizontalBorderSize; }
/**
/** Returns the size of the vertical gap being left around the text.
*/
int getVerticalBorderSize() const throw() { return verticalBorderSize; }


+ 1368
- 1368
src/juce_appframework/gui/components/controls/juce_Slider.cpp
File diff suppressed because it is too large
View File


+ 2647
- 2647
src/juce_appframework/gui/components/controls/juce_TextEditor.cpp
File diff suppressed because it is too large
View File


+ 707
- 707
src/juce_appframework/gui/components/controls/juce_TextEditor.h
File diff suppressed because it is too large
View File


+ 1
- 1
src/juce_appframework/gui/components/filebrowser/juce_FileListComponent.cpp View File

@@ -44,7 +44,7 @@ Image* juce_createIconForFile (const File& file);
//==============================================================================
FileListComponent::FileListComponent (DirectoryContentsList& listToShow)
: ListBox (String::empty, 0),
DirectoryContentsDisplayComponent (listToShow)
DirectoryContentsDisplayComponent (listToShow)
{
setModel (this);
fileList.addChangeListener (this);


+ 25
- 25
src/juce_appframework/gui/components/lookandfeel/juce_LookAndFeel.cpp View File

@@ -1200,31 +1200,31 @@ void LookAndFeel::positionComboBoxText (ComboBox& box, Label& label)
//==============================================================================
void LookAndFeel::drawLabel (Graphics& g, Label& label)
{
g.fillAll (label.findColour (Label::backgroundColourId));
if (! label.isBeingEdited())
{
const float alpha = label.isEnabled() ? 1.0f : 0.5f;
g.setColour (label.findColour (Label::textColourId).withMultipliedAlpha (alpha));
g.setFont (label.getFont());
g.drawFittedText (label.getText(),
label.getHorizontalBorderSize(),
label.getVerticalBorderSize(),
label.getWidth() - 2 * label.getHorizontalBorderSize(),
label.getHeight() - 2 * label.getVerticalBorderSize(),
label.getJustificationType(),
jmax (1, (int) (label.getHeight() / label.getFont().getHeight())),
label.getMinimumHorizontalScale());
g.setColour (label.findColour (Label::outlineColourId).withMultipliedAlpha (alpha));
g.drawRect (0, 0, label.getWidth(), label.getHeight());
}
else if (label.isEnabled())
{
g.setColour (label.findColour (Label::outlineColourId));
g.drawRect (0, 0, label.getWidth(), label.getHeight());
}
g.fillAll (label.findColour (Label::backgroundColourId));
if (! label.isBeingEdited())
{
const float alpha = label.isEnabled() ? 1.0f : 0.5f;
g.setColour (label.findColour (Label::textColourId).withMultipliedAlpha (alpha));
g.setFont (label.getFont());
g.drawFittedText (label.getText(),
label.getHorizontalBorderSize(),
label.getVerticalBorderSize(),
label.getWidth() - 2 * label.getHorizontalBorderSize(),
label.getHeight() - 2 * label.getVerticalBorderSize(),
label.getJustificationType(),
jmax (1, (int) (label.getHeight() / label.getFont().getHeight())),
label.getMinimumHorizontalScale());
g.setColour (label.findColour (Label::outlineColourId).withMultipliedAlpha (alpha));
g.drawRect (0, 0, label.getWidth(), label.getHeight());
}
else if (label.isEnabled())
{
g.setColour (label.findColour (Label::outlineColourId));
g.drawRect (0, 0, label.getWidth(), label.getHeight());
}
}
//==============================================================================


+ 442
- 442
src/juce_appframework/gui/components/properties/juce_PropertyPanel.cpp View File

@@ -1,442 +1,442 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_PropertyPanel.h"
#include "../lookandfeel/juce_LookAndFeel.h"
#include "../../../../juce_core/text/juce_LocalisedStrings.h"
//==============================================================================
class PropertyHolderComponent : public Component
{
public:
PropertyHolderComponent()
{
}
~PropertyHolderComponent()
{
deleteAllChildren();
}
void paint (Graphics&)
{
}
void updateLayout (const int width);
void refreshAll() const;
};
//==============================================================================
class PropertySectionComponent : public Component
{
public:
PropertySectionComponent (const String& sectionTitle,
const Array <PropertyComponent*>& newProperties,
const bool open)
: Component (sectionTitle),
titleHeight (sectionTitle.isNotEmpty() ? 22 : 0),
isOpen_ (open)
{
for (int i = newProperties.size(); --i >= 0;)
{
addAndMakeVisible (newProperties.getUnchecked(i));
newProperties.getUnchecked(i)->refresh();
}
}
~PropertySectionComponent()
{
deleteAllChildren();
}
void paint (Graphics& g)
{
if (titleHeight > 0)
getLookAndFeel().drawPropertyPanelSectionHeader (g, getName(), isOpen(), getWidth(), titleHeight);
}
void resized()
{
int y = titleHeight;
for (int i = getNumChildComponents(); --i >= 0;)
{
PropertyComponent* const pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
{
const int prefH = pec->getPreferredHeight();
pec->setBounds (1, y, getWidth() - 2, prefH);
y += prefH;
}
}
}
int getPreferredHeight() const
{
int y = titleHeight;
if (isOpen())
{
for (int i = 0; i < getNumChildComponents(); ++i)
{
PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
y += pec->getPreferredHeight();
}
}
return y;
}
void setOpen (const bool open)
{
if (isOpen_ != open)
{
isOpen_ = open;
for (int i = 0; i < getNumChildComponents(); ++i)
{
PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
pec->setVisible (open);
}
// (unable to use the syntax findParentComponentOfClass <DragAndDropContainer> () because of a VC6 compiler bug)
PropertyPanel* const pp = findParentComponentOfClass ((PropertyPanel*) 0);
if (pp != 0)
pp->resized();
}
}
bool isOpen() const throw()
{
return isOpen_;
}
void refreshAll() const
{
for (int i = 0; i < getNumChildComponents(); ++i)
{
PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
pec->refresh();
}
}
void mouseDown (const MouseEvent&)
{
}
void mouseUp (const MouseEvent& e)
{
if (e.getMouseDownX() < titleHeight
&& e.x < titleHeight
&& e.y < titleHeight
&& e.getNumberOfClicks() != 2)
{
setOpen (! isOpen());
}
}
void mouseDoubleClick (const MouseEvent& e)
{
if (e.y < titleHeight)
setOpen (! isOpen());
}
private:
int titleHeight;
bool isOpen_;
};
void PropertyHolderComponent::updateLayout (const int width)
{
int y = 0;
for (int i = getNumChildComponents(); --i >= 0;)
{
PropertySectionComponent* const section
= dynamic_cast <PropertySectionComponent*> (getChildComponent (i));
if (section != 0)
{
const int prefH = section->getPreferredHeight();
section->setBounds (0, y, width, prefH);
y += prefH;
}
}
setSize (width, y);
repaint();
}
void PropertyHolderComponent::refreshAll() const
{
for (int i = getNumChildComponents(); --i >= 0;)
{
PropertySectionComponent* const section
= dynamic_cast <PropertySectionComponent*> (getChildComponent (i));
if (section != 0)
section->refreshAll();
}
}
//==============================================================================
PropertyPanel::PropertyPanel()
{
messageWhenEmpty = TRANS("(nothing selected)");
addAndMakeVisible (viewport = new Viewport());
viewport->setViewedComponent (propertyHolderComponent = new PropertyHolderComponent());
viewport->setFocusContainer (true);
}
PropertyPanel::~PropertyPanel()
{
clear();
deleteAllChildren();
}
//==============================================================================
void PropertyPanel::paint (Graphics& g)
{
if (propertyHolderComponent->getNumChildComponents() == 0)
{
g.setColour (Colours::black.withAlpha (0.5f));
g.setFont (14.0f);
g.drawText (messageWhenEmpty, 0, 0, getWidth(), 30,
Justification::centred, true);
}
}
void PropertyPanel::resized()
{
viewport->setBounds (0, 0, getWidth(), getHeight());
updatePropHolderLayout();
}
//==============================================================================
void PropertyPanel::clear()
{
if (propertyHolderComponent->getNumChildComponents() > 0)
{
propertyHolderComponent->deleteAllChildren();
repaint();
}
}
void PropertyPanel::addProperties (const Array <PropertyComponent*>& newProperties)
{
if (propertyHolderComponent->getNumChildComponents() == 0)
repaint();
propertyHolderComponent->addAndMakeVisible (new PropertySectionComponent (String::empty,
newProperties,
true), 0);
updatePropHolderLayout();
}
void PropertyPanel::addSection (const String& sectionTitle,
const Array <PropertyComponent*>& newProperties,
const bool shouldBeOpen)
{
jassert (sectionTitle.isNotEmpty());
if (propertyHolderComponent->getNumChildComponents() == 0)
repaint();
propertyHolderComponent->addAndMakeVisible (new PropertySectionComponent (sectionTitle,
newProperties,
shouldBeOpen), 0);
updatePropHolderLayout();
}
void PropertyPanel::updatePropHolderLayout() const
{
const int maxWidth = viewport->getMaximumVisibleWidth();
((PropertyHolderComponent*) propertyHolderComponent)->updateLayout (maxWidth);
const int newMaxWidth = viewport->getMaximumVisibleWidth();
if (maxWidth != newMaxWidth)
{
// need to do this twice because of scrollbars changing the size, etc.
((PropertyHolderComponent*) propertyHolderComponent)->updateLayout (newMaxWidth);
}
}
void PropertyPanel::refreshAll() const
{
((PropertyHolderComponent*) propertyHolderComponent)->refreshAll();
}
//==============================================================================
const StringArray PropertyPanel::getSectionNames() const
{
StringArray s;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
s.add (section->getName());
}
return s;
}
bool PropertyPanel::isSectionOpen (const int sectionIndex) const
{
int index = 0;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
{
if (index == sectionIndex)
return section->isOpen();
++index;
}
}
return false;
}
void PropertyPanel::setSectionOpen (const int sectionIndex, const bool shouldBeOpen)
{
int index = 0;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
{
if (index == sectionIndex)
{
section->setOpen (shouldBeOpen);
break;
}
++index;
}
}
}
void PropertyPanel::setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled)
{
int index = 0;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
{
if (index == sectionIndex)
{
section->setEnabled (shouldBeEnabled);
break;
}
++index;
}
}
}
//==============================================================================
XmlElement* PropertyPanel::getOpennessState() const
{
XmlElement* const xml = new XmlElement (T("PROPERTYPANELSTATE"));
const StringArray sections (getSectionNames());
for (int i = 0; i < sections.size(); ++i)
{
if (sections[i].isNotEmpty())
{
XmlElement* const e = new XmlElement (T("SECTION"));
e->setAttribute (T("name"), sections[i]);
e->setAttribute (T("open"), isSectionOpen (i) ? 1 : 0);
xml->addChildElement (e);
}
}
return xml;
}
void PropertyPanel::restoreOpennessState (const XmlElement& xml)
{
if (xml.hasTagName (T("PROPERTYPANELSTATE")))
{
const StringArray sections (getSectionNames());
forEachXmlChildElementWithTagName (xml, e, T("SECTION"))
{
setSectionOpen (sections.indexOf (e->getStringAttribute (T("name"))),
e->getBoolAttribute (T("open")));
}
}
}
//==============================================================================
void PropertyPanel::setMessageWhenEmpty (const String& newMessage)
{
if (messageWhenEmpty != newMessage)
{
messageWhenEmpty = newMessage;
repaint();
}
}
const String& PropertyPanel::getMessageWhenEmpty() const throw()
{
return messageWhenEmpty;
}
END_JUCE_NAMESPACE
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../../juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "juce_PropertyPanel.h"
#include "../lookandfeel/juce_LookAndFeel.h"
#include "../../../../juce_core/text/juce_LocalisedStrings.h"
//==============================================================================
class PropertyHolderComponent : public Component
{
public:
PropertyHolderComponent()
{
}
~PropertyHolderComponent()
{
deleteAllChildren();
}
void paint (Graphics&)
{
}
void updateLayout (const int width);
void refreshAll() const;
};
//==============================================================================
class PropertySectionComponent : public Component
{
public:
PropertySectionComponent (const String& sectionTitle,
const Array <PropertyComponent*>& newProperties,
const bool open)
: Component (sectionTitle),
titleHeight (sectionTitle.isNotEmpty() ? 22 : 0),
isOpen_ (open)
{
for (int i = newProperties.size(); --i >= 0;)
{
addAndMakeVisible (newProperties.getUnchecked(i));
newProperties.getUnchecked(i)->refresh();
}
}
~PropertySectionComponent()
{
deleteAllChildren();
}
void paint (Graphics& g)
{
if (titleHeight > 0)
getLookAndFeel().drawPropertyPanelSectionHeader (g, getName(), isOpen(), getWidth(), titleHeight);
}
void resized()
{
int y = titleHeight;
for (int i = getNumChildComponents(); --i >= 0;)
{
PropertyComponent* const pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
{
const int prefH = pec->getPreferredHeight();
pec->setBounds (1, y, getWidth() - 2, prefH);
y += prefH;
}
}
}
int getPreferredHeight() const
{
int y = titleHeight;
if (isOpen())
{
for (int i = 0; i < getNumChildComponents(); ++i)
{
PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
y += pec->getPreferredHeight();
}
}
return y;
}
void setOpen (const bool open)
{
if (isOpen_ != open)
{
isOpen_ = open;
for (int i = 0; i < getNumChildComponents(); ++i)
{
PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
pec->setVisible (open);
}
// (unable to use the syntax findParentComponentOfClass <DragAndDropContainer> () because of a VC6 compiler bug)
PropertyPanel* const pp = findParentComponentOfClass ((PropertyPanel*) 0);
if (pp != 0)
pp->resized();
}
}
bool isOpen() const throw()
{
return isOpen_;
}
void refreshAll() const
{
for (int i = 0; i < getNumChildComponents(); ++i)
{
PropertyComponent* pec = dynamic_cast <PropertyComponent*> (getChildComponent (i));
if (pec != 0)
pec->refresh();
}
}
void mouseDown (const MouseEvent&)
{
}
void mouseUp (const MouseEvent& e)
{
if (e.getMouseDownX() < titleHeight
&& e.x < titleHeight
&& e.y < titleHeight
&& e.getNumberOfClicks() != 2)
{
setOpen (! isOpen());
}
}
void mouseDoubleClick (const MouseEvent& e)
{
if (e.y < titleHeight)
setOpen (! isOpen());
}
private:
int titleHeight;
bool isOpen_;
};
void PropertyHolderComponent::updateLayout (const int width)
{
int y = 0;
for (int i = getNumChildComponents(); --i >= 0;)
{
PropertySectionComponent* const section
= dynamic_cast <PropertySectionComponent*> (getChildComponent (i));
if (section != 0)
{
const int prefH = section->getPreferredHeight();
section->setBounds (0, y, width, prefH);
y += prefH;
}
}
setSize (width, y);
repaint();
}
void PropertyHolderComponent::refreshAll() const
{
for (int i = getNumChildComponents(); --i >= 0;)
{
PropertySectionComponent* const section
= dynamic_cast <PropertySectionComponent*> (getChildComponent (i));
if (section != 0)
section->refreshAll();
}
}
//==============================================================================
PropertyPanel::PropertyPanel()
{
messageWhenEmpty = TRANS("(nothing selected)");
addAndMakeVisible (viewport = new Viewport());
viewport->setViewedComponent (propertyHolderComponent = new PropertyHolderComponent());
viewport->setFocusContainer (true);
}
PropertyPanel::~PropertyPanel()
{
clear();
deleteAllChildren();
}
//==============================================================================
void PropertyPanel::paint (Graphics& g)
{
if (propertyHolderComponent->getNumChildComponents() == 0)
{
g.setColour (Colours::black.withAlpha (0.5f));
g.setFont (14.0f);
g.drawText (messageWhenEmpty, 0, 0, getWidth(), 30,
Justification::centred, true);
}
}
void PropertyPanel::resized()
{
viewport->setBounds (0, 0, getWidth(), getHeight());
updatePropHolderLayout();
}
//==============================================================================
void PropertyPanel::clear()
{
if (propertyHolderComponent->getNumChildComponents() > 0)
{
propertyHolderComponent->deleteAllChildren();
repaint();
}
}
void PropertyPanel::addProperties (const Array <PropertyComponent*>& newProperties)
{
if (propertyHolderComponent->getNumChildComponents() == 0)
repaint();
propertyHolderComponent->addAndMakeVisible (new PropertySectionComponent (String::empty,
newProperties,
true), 0);
updatePropHolderLayout();
}
void PropertyPanel::addSection (const String& sectionTitle,
const Array <PropertyComponent*>& newProperties,
const bool shouldBeOpen)
{
jassert (sectionTitle.isNotEmpty());
if (propertyHolderComponent->getNumChildComponents() == 0)
repaint();
propertyHolderComponent->addAndMakeVisible (new PropertySectionComponent (sectionTitle,
newProperties,
shouldBeOpen), 0);
updatePropHolderLayout();
}
void PropertyPanel::updatePropHolderLayout() const
{
const int maxWidth = viewport->getMaximumVisibleWidth();
((PropertyHolderComponent*) propertyHolderComponent)->updateLayout (maxWidth);
const int newMaxWidth = viewport->getMaximumVisibleWidth();
if (maxWidth != newMaxWidth)
{
// need to do this twice because of scrollbars changing the size, etc.
((PropertyHolderComponent*) propertyHolderComponent)->updateLayout (newMaxWidth);
}
}
void PropertyPanel::refreshAll() const
{
((PropertyHolderComponent*) propertyHolderComponent)->refreshAll();
}
//==============================================================================
const StringArray PropertyPanel::getSectionNames() const
{
StringArray s;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
s.add (section->getName());
}
return s;
}
bool PropertyPanel::isSectionOpen (const int sectionIndex) const
{
int index = 0;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
{
if (index == sectionIndex)
return section->isOpen();
++index;
}
}
return false;
}
void PropertyPanel::setSectionOpen (const int sectionIndex, const bool shouldBeOpen)
{
int index = 0;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
{
if (index == sectionIndex)
{
section->setOpen (shouldBeOpen);
break;
}
++index;
}
}
}
void PropertyPanel::setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled)
{
int index = 0;
for (int i = 0; i < propertyHolderComponent->getNumChildComponents(); ++i)
{
PropertySectionComponent* const section = dynamic_cast <PropertySectionComponent*> (propertyHolderComponent->getChildComponent (i));
if (section != 0 && section->getName().isNotEmpty())
{
if (index == sectionIndex)
{
section->setEnabled (shouldBeEnabled);
break;
}
++index;
}
}
}
//==============================================================================
XmlElement* PropertyPanel::getOpennessState() const
{
XmlElement* const xml = new XmlElement (T("PROPERTYPANELSTATE"));
const StringArray sections (getSectionNames());
for (int i = 0; i < sections.size(); ++i)
{
if (sections[i].isNotEmpty())
{
XmlElement* const e = new XmlElement (T("SECTION"));
e->setAttribute (T("name"), sections[i]);
e->setAttribute (T("open"), isSectionOpen (i) ? 1 : 0);
xml->addChildElement (e);
}
}
return xml;
}
void PropertyPanel::restoreOpennessState (const XmlElement& xml)
{
if (xml.hasTagName (T("PROPERTYPANELSTATE")))
{
const StringArray sections (getSectionNames());
forEachXmlChildElementWithTagName (xml, e, T("SECTION"))
{
setSectionOpen (sections.indexOf (e->getStringAttribute (T("name"))),
e->getBoolAttribute (T("open")));
}
}
}
//==============================================================================
void PropertyPanel::setMessageWhenEmpty (const String& newMessage)
{
if (messageWhenEmpty != newMessage)
{
messageWhenEmpty = newMessage;
repaint();
}
}
const String& PropertyPanel::getMessageWhenEmpty() const throw()
{
return messageWhenEmpty;
}
END_JUCE_NAMESPACE

+ 18
- 18
src/juce_appframework/gui/components/special/juce_AudioDeviceSelectorComponent.cpp View File

@@ -42,7 +42,7 @@ BEGIN_JUCE_NAMESPACE
//==============================================================================
class SimpleDeviceManagerInputLevelMeter : public Component,
class SimpleDeviceManagerInputLevelMeter : public Component,
public Timer
{
public:
@@ -214,7 +214,7 @@ class AudioDeviceSettingsPanel : public Component,
public ButtonListener
{
public:
AudioDeviceSettingsPanel (AudioIODeviceType* type_,
AudioDeviceSettingsPanel (AudioIODeviceType* type_,
AudioIODeviceType::DeviceSetupDetails& setup_,
const bool hideAdvancedOptionsWithButton)
: type (type_),
@@ -279,7 +279,7 @@ public:
outputDeviceDropDown->setBounds (lx, y, w, h);
if (testButton != 0)
testButton->setBounds (proportionOfWidth (0.77f),
testButton->setBounds (proportionOfWidth (0.77f),
outputDeviceDropDown->getY(),
proportionOfWidth (0.18f),
h);
@@ -290,7 +290,7 @@ public:
{
inputDeviceDropDown->setBounds (lx, y, w, h);
inputLevelMeter->setBounds (proportionOfWidth (0.77f),
inputLevelMeter->setBounds (proportionOfWidth (0.77f),
inputDeviceDropDown->getY(),
proportionOfWidth (0.18f),
h);
@@ -323,7 +323,7 @@ public:
if (sampleRateDropDown != 0)
{
sampleRateDropDown->setVisible (showAdvancedSettingsButton == 0
sampleRateDropDown->setVisible (showAdvancedSettingsButton == 0
|| ! showAdvancedSettingsButton->isVisible());
sampleRateDropDown->setBounds (lx, y, w, h);
@@ -360,11 +360,11 @@ public:
|| comboBoxThatHasChanged == inputDeviceDropDown)
{
if (outputDeviceDropDown != 0)
config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String::empty
config.outputDeviceName = outputDeviceDropDown->getSelectedId() < 0 ? String::empty
: outputDeviceDropDown->getText();
if (inputDeviceDropDown != 0)
config.inputDeviceName = inputDeviceDropDown->getSelectedId() < 0 ? String::empty
config.inputDeviceName = inputDeviceDropDown->getSelectedId() < 0 ? String::empty
: inputDeviceDropDown->getText();
if (! type->hasSeparateInputsAndOutputs())
@@ -460,7 +460,7 @@ public:
outputDeviceDropDown->addListener (this);
addAndMakeVisible (outputDeviceDropDown);
outputDeviceLabel = new Label (String::empty,
outputDeviceLabel = new Label (String::empty,
type->hasSeparateInputsAndOutputs() ? TRANS ("output:")
: TRANS ("device:"));
outputDeviceLabel->attachToComponent (outputDeviceDropDown, true);
@@ -486,7 +486,7 @@ public:
inputDeviceLabel = new Label (String::empty, TRANS ("input:"));
inputDeviceLabel->attachToComponent (inputDeviceDropDown, true);
addAndMakeVisible (inputLevelMeter
addAndMakeVisible (inputLevelMeter
= new SimpleDeviceManagerInputLevelMeter (setup.manager));
}
@@ -499,13 +499,13 @@ public:
if (currentDevice != 0)
{
if (setup.maxNumOutputChannels > 0
if (setup.maxNumOutputChannels > 0
&& setup.minNumOutputChannels < setup.manager->getCurrentAudioDevice()->getOutputChannelNames().size())
{
if (outputChanList == 0)
{
addAndMakeVisible (outputChanList
= new ChannelSelectorListBox (setup, ChannelSelectorListBox::audioOutputType,
addAndMakeVisible (outputChanList
= new ChannelSelectorListBox (setup, ChannelSelectorListBox::audioOutputType,
TRANS ("(no audio output channels found)")));
outputChanLabel = new Label (String::empty, TRANS ("active output channels:"));
outputChanLabel->attachToComponent (outputChanList, true);
@@ -525,7 +525,7 @@ public:
if (inputChanList == 0)
{
addAndMakeVisible (inputChanList
= new ChannelSelectorListBox (setup, ChannelSelectorListBox::audioInputType,
= new ChannelSelectorListBox (setup, ChannelSelectorListBox::audioInputType,
TRANS ("(no audio input channels found)")));
inputChanLabel = new Label (String::empty, TRANS ("active input channels:"));
inputChanLabel->attachToComponent (inputChanList, true);
@@ -832,7 +832,7 @@ private:
int getBestHeight (int maxHeight)
{
return getRowHeight() * jlimit (2, jmax (2, maxHeight / getRowHeight()),
return getRowHeight() * jlimit (2, jmax (2, maxHeight / getRowHeight()),
getNumRows())
+ getOutlineThickness() * 2;
}
@@ -974,7 +974,7 @@ AudioDeviceSelectorComponent::AudioDeviceSelectorComponent (AudioDeviceManager&
for (int i = 0; i < deviceManager_.getAvailableDeviceTypes().size(); ++i)
{
deviceTypeDropDown
->addItem (deviceManager_.getAvailableDeviceTypes().getUnchecked(i)->getTypeName(),
->addItem (deviceManager_.getAvailableDeviceTypes().getUnchecked(i)->getTypeName(),
i + 1);
}
@@ -1100,15 +1100,15 @@ void AudioDeviceSelectorComponent::changeListenerCallback (void*)
deviceTypeDropDown->setText (deviceManager.getCurrentAudioDeviceType(), false);
}
if (audioDeviceSettingsComp == 0
if (audioDeviceSettingsComp == 0
|| audioDeviceSettingsCompType != deviceManager.getCurrentAudioDeviceType())
{
audioDeviceSettingsCompType = deviceManager.getCurrentAudioDeviceType();
deleteAndZero (audioDeviceSettingsComp);
AudioIODeviceType* const type
= deviceManager.getAvailableDeviceTypes() [deviceTypeDropDown == 0
AudioIODeviceType* const type
= deviceManager.getAvailableDeviceTypes() [deviceTypeDropDown == 0
? 0 : deviceTypeDropDown->getSelectedId() - 1];
if (type != 0)


+ 1
- 1
src/juce_appframework/gui/components/special/juce_AudioDeviceSelectorComponent.h View File

@@ -66,7 +66,7 @@ public:
@param maxAudioOutputChannels the maximum number of audio output channels that the application needs
@param showMidiInputOptions if true, the component will allow the user to select which midi inputs are enabled
@param showMidiOutputSelector if true, the component will let the user choose a default midi output device
@param showChannelsAsStereoPairs if true, channels will be treated as pairs; if false, channels will be
@param showChannelsAsStereoPairs if true, channels will be treated as pairs; if false, channels will be
treated as a set of separate mono channels.
@param hideAdvancedOptionsWithButton if true, only the minimum amount of UI components
are shown, with an "advanced" button that shows the rest of them


+ 2228
- 2228
src/juce_appframework/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp
File diff suppressed because it is too large
View File


+ 378
- 378
src/juce_appframework/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp View File

@@ -1,378 +1,378 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../../../juce_core/basics/juce_StandardHeader.h"
#if JUCE_MSVC
#pragma warning (push)
#endif
namespace jpeglibNamespace
{
extern "C"
{
#define JPEG_INTERNALS
#undef FAR
#include "jpglib/jpeglib.h"
#include "jpglib/jcapimin.c"
#include "jpglib/jcapistd.c"
#include "jpglib/jccoefct.c"
#include "jpglib/jccolor.c"
#undef FIX
#include "jpglib/jcdctmgr.c"
#undef CONST_BITS
#include "jpglib/jchuff.c"
#undef emit_byte
#include "jpglib/jcinit.c"
#include "jpglib/jcmainct.c"
#include "jpglib/jcmarker.c"
#include "jpglib/jcmaster.c"
#include "jpglib/jcomapi.c"
#include "jpglib/jcparam.c"
#include "jpglib/jcphuff.c"
#include "jpglib/jcprepct.c"
#include "jpglib/jcsample.c"
#include "jpglib/jctrans.c"
#include "jpglib/jdapistd.c"
#include "jpglib/jdapimin.c"
#include "jpglib/jdatasrc.c"
#include "jpglib/jdcoefct.c"
#undef FIX
#include "jpglib/jdcolor.c"
#undef FIX
#include "jpglib/jddctmgr.c"
#undef CONST_BITS
#undef ASSIGN_STATE
#include "jpglib/jdhuff.c"
#include "jpglib/jdinput.c"
#include "jpglib/jdmainct.c"
#include "jpglib/jdmarker.c"
#include "jpglib/jdmaster.c"
#undef FIX
#include "jpglib/jdmerge.c"
#undef ASSIGN_STATE
#include "jpglib/jdphuff.c"
#include "jpglib/jdpostct.c"
#undef FIX
#include "jpglib/jdsample.c"
#include "jpglib/jdtrans.c"
#include "jpglib/jfdctflt.c"
#include "jpglib/jfdctint.c"
#undef CONST_BITS
#undef MULTIPLY
#undef FIX_0_541196100
#include "jpglib/jfdctfst.c"
#undef FIX_0_541196100
#include "jpglib/jidctflt.c"
#undef CONST_BITS
#undef FIX_1_847759065
#undef MULTIPLY
#undef DEQUANTIZE
#undef DESCALE
#include "jpglib/jidctfst.c"
#undef CONST_BITS
#undef FIX_1_847759065
#undef MULTIPLY
#undef DEQUANTIZE
#include "jpglib/jidctint.c"
#include "jpglib/jidctred.c"
#include "jpglib/jmemmgr.c"
#include "jpglib/jmemnobs.c"
#include "jpglib/jquant1.c"
#include "jpglib/jquant2.c"
#include "jpglib/jutils.c"
#include "jpglib/transupp.c"
}
}
#if JUCE_MSVC
#pragma warning (pop)
#endif
BEGIN_JUCE_NAMESPACE
#include "../juce_Image.h"
#include "../../../../../juce_core/io/juce_InputStream.h"
#include "../../../../../juce_core/io/juce_OutputStream.h"
#include "../../colour/juce_PixelFormats.h"
using namespace jpeglibNamespace;
//==============================================================================
struct JPEGDecodingFailure {};
static void fatalErrorHandler (j_common_ptr)
{
throw JPEGDecodingFailure();
}
static void silentErrorCallback1 (j_common_ptr) {}
static void silentErrorCallback2 (j_common_ptr, int) {}
static void silentErrorCallback3 (j_common_ptr, char*) {}
static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
{
zerostruct (err);
err.error_exit = fatalErrorHandler;
err.emit_message = silentErrorCallback2;
err.output_message = silentErrorCallback1;
err.format_message = silentErrorCallback3;
err.reset_error_mgr = silentErrorCallback1;
}
//==============================================================================
static void dummyCallback1 (j_decompress_ptr) throw()
{
}
static void jpegSkip (j_decompress_ptr decompStruct, long num) throw()
{
decompStruct->src->next_input_byte += num;
num = jmin (num, (int) decompStruct->src->bytes_in_buffer);
decompStruct->src->bytes_in_buffer -= num;
}
static boolean jpegFill (j_decompress_ptr) throw()
{
return 0;
}
//==============================================================================
Image* juce_loadJPEGImageFromStream (InputStream& in) throw()
{
MemoryBlock mb;
in.readIntoMemoryBlock (mb);
Image* image = 0;
if (mb.getSize() > 16)
{
struct jpeg_decompress_struct jpegDecompStruct;
struct jpeg_error_mgr jerr;
setupSilentErrorHandler (jerr);
jpegDecompStruct.err = &jerr;
jpeg_create_decompress (&jpegDecompStruct);
jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));
jpegDecompStruct.src->init_source = dummyCallback1;
jpegDecompStruct.src->fill_input_buffer = jpegFill;
jpegDecompStruct.src->skip_input_data = jpegSkip;
jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
jpegDecompStruct.src->term_source = dummyCallback1;
jpegDecompStruct.src->next_input_byte = (const unsigned char*) mb.getData();
jpegDecompStruct.src->bytes_in_buffer = mb.getSize();
try
{
jpeg_read_header (&jpegDecompStruct, TRUE);
jpeg_calc_output_dimensions (&jpegDecompStruct);
const int width = jpegDecompStruct.output_width;
const int height = jpegDecompStruct.output_height;
jpegDecompStruct.out_color_space = JCS_RGB;
JSAMPARRAY buffer
= (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
JPOOL_IMAGE,
width * 3, 1);
if (jpeg_start_decompress (&jpegDecompStruct))
{
image = new Image (Image::RGB, width, height, false);
for (int y = 0; y < height; ++y)
{
jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);
int stride, pixelStride;
uint8* pixels = image->lockPixelDataReadWrite (0, y, width, 1, stride, pixelStride);
const uint8* src = *buffer;
uint8* dest = pixels;
for (int i = width; --i >= 0;)
{
((PixelRGB*) dest)->setARGB (0, src[0], src[1], src[2]);
dest += pixelStride;
src += 3;
}
image->releasePixelDataReadWrite (pixels);
}
jpeg_finish_decompress (&jpegDecompStruct);
}
jpeg_destroy_decompress (&jpegDecompStruct);
}
catch (...)
{}
in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
}
return image;
}
//==============================================================================
static const int bufferSize = 512;
struct JuceJpegDest : public jpeg_destination_mgr
{
OutputStream* output;
char* buffer;
};
static void jpegWriteInit (j_compress_ptr) throw()
{
}
static void jpegWriteTerminate (j_compress_ptr cinfo) throw()
{
JuceJpegDest* const dest = (JuceJpegDest*) cinfo->dest;
const int numToWrite = bufferSize - dest->free_in_buffer;
dest->output->write (dest->buffer, numToWrite);
}
static boolean jpegWriteFlush (j_compress_ptr cinfo) throw()
{
JuceJpegDest* const dest = (JuceJpegDest*) cinfo->dest;
const int numToWrite = bufferSize;
dest->next_output_byte = (JOCTET*) dest->buffer;
dest->free_in_buffer = bufferSize;
return dest->output->write (dest->buffer, numToWrite);
}
//==============================================================================
bool juce_writeJPEGImageToStream (const Image& image,
OutputStream& out,
float quality) throw()
{
if (image.hasAlphaChannel())
{
// this method could fill the background in white and still save the image..
jassertfalse
return true;
}
struct jpeg_compress_struct jpegCompStruct;
struct jpeg_error_mgr jerr;
setupSilentErrorHandler (jerr);
jpegCompStruct.err = &jerr;
jpeg_create_compress (&jpegCompStruct);
JuceJpegDest dest;
jpegCompStruct.dest = &dest;
dest.output = &out;
dest.buffer = (char*) juce_malloc (bufferSize);
dest.next_output_byte = (JOCTET*) dest.buffer;
dest.free_in_buffer = bufferSize;
dest.init_destination = jpegWriteInit;
dest.empty_output_buffer = jpegWriteFlush;
dest.term_destination = jpegWriteTerminate;
jpegCompStruct.image_width = image.getWidth();
jpegCompStruct.image_height = image.getHeight();
jpegCompStruct.input_components = 3;
jpegCompStruct.in_color_space = JCS_RGB;
jpegCompStruct.write_JFIF_header = 1;
jpegCompStruct.X_density = 72;
jpegCompStruct.Y_density = 72;
jpeg_set_defaults (&jpegCompStruct);
jpegCompStruct.dct_method = JDCT_FLOAT;
jpegCompStruct.optimize_coding = 1;
// jpegCompStruct.smoothing_factor = 10;
if (quality < 0.0f)
quality = 0.85f;
jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundFloatToInt (quality * 100.0f)), TRUE);
jpeg_start_compress (&jpegCompStruct, TRUE);
const int strideBytes = jpegCompStruct.image_width * jpegCompStruct.input_components;
JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
JPOOL_IMAGE,
strideBytes, 1);
while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
{
int stride, pixelStride;
const uint8* pixels = image.lockPixelDataReadOnly (0, jpegCompStruct.next_scanline, jpegCompStruct.image_width, 1, stride, pixelStride);
const uint8* src = pixels;
uint8* dst = *buffer;
for (int i = jpegCompStruct.image_width; --i >= 0;)
{
*dst++ = ((const PixelRGB*) src)->getRed();
*dst++ = ((const PixelRGB*) src)->getGreen();
*dst++ = ((const PixelRGB*) src)->getBlue();
src += pixelStride;
}
jpeg_write_scanlines (&jpegCompStruct, buffer, 1);
image.releasePixelDataReadOnly (pixels);
}
jpeg_finish_compress (&jpegCompStruct);
jpeg_destroy_compress (&jpegCompStruct);
juce_free (dest.buffer);
out.flush();
return true;
}
END_JUCE_NAMESPACE
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified under the terms of the
GNU General Public License, as published by the Free Software Foundation;
either version 2 of the License, or (at your option) any later version.
JUCE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../../../juce_core/basics/juce_StandardHeader.h"
#if JUCE_MSVC
#pragma warning (push)
#endif
namespace jpeglibNamespace
{
extern "C"
{
#define JPEG_INTERNALS
#undef FAR
#include "jpglib/jpeglib.h"
#include "jpglib/jcapimin.c"
#include "jpglib/jcapistd.c"
#include "jpglib/jccoefct.c"
#include "jpglib/jccolor.c"
#undef FIX
#include "jpglib/jcdctmgr.c"
#undef CONST_BITS
#include "jpglib/jchuff.c"
#undef emit_byte
#include "jpglib/jcinit.c"
#include "jpglib/jcmainct.c"
#include "jpglib/jcmarker.c"
#include "jpglib/jcmaster.c"
#include "jpglib/jcomapi.c"
#include "jpglib/jcparam.c"
#include "jpglib/jcphuff.c"
#include "jpglib/jcprepct.c"
#include "jpglib/jcsample.c"
#include "jpglib/jctrans.c"
#include "jpglib/jdapistd.c"
#include "jpglib/jdapimin.c"
#include "jpglib/jdatasrc.c"
#include "jpglib/jdcoefct.c"
#undef FIX
#include "jpglib/jdcolor.c"
#undef FIX
#include "jpglib/jddctmgr.c"
#undef CONST_BITS
#undef ASSIGN_STATE
#include "jpglib/jdhuff.c"
#include "jpglib/jdinput.c"
#include "jpglib/jdmainct.c"
#include "jpglib/jdmarker.c"
#include "jpglib/jdmaster.c"
#undef FIX
#include "jpglib/jdmerge.c"
#undef ASSIGN_STATE
#include "jpglib/jdphuff.c"
#include "jpglib/jdpostct.c"
#undef FIX
#include "jpglib/jdsample.c"
#include "jpglib/jdtrans.c"
#include "jpglib/jfdctflt.c"
#include "jpglib/jfdctint.c"
#undef CONST_BITS
#undef MULTIPLY
#undef FIX_0_541196100
#include "jpglib/jfdctfst.c"
#undef FIX_0_541196100
#include "jpglib/jidctflt.c"
#undef CONST_BITS
#undef FIX_1_847759065
#undef MULTIPLY
#undef DEQUANTIZE
#undef DESCALE
#include "jpglib/jidctfst.c"
#undef CONST_BITS
#undef FIX_1_847759065
#undef MULTIPLY
#undef DEQUANTIZE
#include "jpglib/jidctint.c"
#include "jpglib/jidctred.c"
#include "jpglib/jmemmgr.c"
#include "jpglib/jmemnobs.c"
#include "jpglib/jquant1.c"
#include "jpglib/jquant2.c"
#include "jpglib/jutils.c"
#include "jpglib/transupp.c"
}
}
#if JUCE_MSVC
#pragma warning (pop)
#endif
BEGIN_JUCE_NAMESPACE
#include "../juce_Image.h"
#include "../../../../../juce_core/io/juce_InputStream.h"
#include "../../../../../juce_core/io/juce_OutputStream.h"
#include "../../colour/juce_PixelFormats.h"
using namespace jpeglibNamespace;
//==============================================================================
struct JPEGDecodingFailure {};
static void fatalErrorHandler (j_common_ptr)
{
throw JPEGDecodingFailure();
}
static void silentErrorCallback1 (j_common_ptr) {}
static void silentErrorCallback2 (j_common_ptr, int) {}
static void silentErrorCallback3 (j_common_ptr, char*) {}
static void setupSilentErrorHandler (struct jpeg_error_mgr& err)
{
zerostruct (err);
err.error_exit = fatalErrorHandler;
err.emit_message = silentErrorCallback2;
err.output_message = silentErrorCallback1;
err.format_message = silentErrorCallback3;
err.reset_error_mgr = silentErrorCallback1;
}
//==============================================================================
static void dummyCallback1 (j_decompress_ptr) throw()
{
}
static void jpegSkip (j_decompress_ptr decompStruct, long num) throw()
{
decompStruct->src->next_input_byte += num;
num = jmin (num, (int) decompStruct->src->bytes_in_buffer);
decompStruct->src->bytes_in_buffer -= num;
}
static boolean jpegFill (j_decompress_ptr) throw()
{
return 0;
}
//==============================================================================
Image* juce_loadJPEGImageFromStream (InputStream& in) throw()
{
MemoryBlock mb;
in.readIntoMemoryBlock (mb);
Image* image = 0;
if (mb.getSize() > 16)
{
struct jpeg_decompress_struct jpegDecompStruct;
struct jpeg_error_mgr jerr;
setupSilentErrorHandler (jerr);
jpegDecompStruct.err = &jerr;
jpeg_create_decompress (&jpegDecompStruct);
jpegDecompStruct.src = (jpeg_source_mgr*)(jpegDecompStruct.mem->alloc_small)
((j_common_ptr)(&jpegDecompStruct), JPOOL_PERMANENT, sizeof (jpeg_source_mgr));
jpegDecompStruct.src->init_source = dummyCallback1;
jpegDecompStruct.src->fill_input_buffer = jpegFill;
jpegDecompStruct.src->skip_input_data = jpegSkip;
jpegDecompStruct.src->resync_to_restart = jpeg_resync_to_restart;
jpegDecompStruct.src->term_source = dummyCallback1;
jpegDecompStruct.src->next_input_byte = (const unsigned char*) mb.getData();
jpegDecompStruct.src->bytes_in_buffer = mb.getSize();
try
{
jpeg_read_header (&jpegDecompStruct, TRUE);
jpeg_calc_output_dimensions (&jpegDecompStruct);
const int width = jpegDecompStruct.output_width;
const int height = jpegDecompStruct.output_height;
jpegDecompStruct.out_color_space = JCS_RGB;
JSAMPARRAY buffer
= (*jpegDecompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegDecompStruct,
JPOOL_IMAGE,
width * 3, 1);
if (jpeg_start_decompress (&jpegDecompStruct))
{
image = new Image (Image::RGB, width, height, false);
for (int y = 0; y < height; ++y)
{
jpeg_read_scanlines (&jpegDecompStruct, buffer, 1);
int stride, pixelStride;
uint8* pixels = image->lockPixelDataReadWrite (0, y, width, 1, stride, pixelStride);
const uint8* src = *buffer;
uint8* dest = pixels;
for (int i = width; --i >= 0;)
{
((PixelRGB*) dest)->setARGB (0, src[0], src[1], src[2]);
dest += pixelStride;
src += 3;
}
image->releasePixelDataReadWrite (pixels);
}
jpeg_finish_decompress (&jpegDecompStruct);
}
jpeg_destroy_decompress (&jpegDecompStruct);
}
catch (...)
{}
in.setPosition (((char*) jpegDecompStruct.src->next_input_byte) - (char*) mb.getData());
}
return image;
}
//==============================================================================
static const int bufferSize = 512;
struct JuceJpegDest : public jpeg_destination_mgr
{
OutputStream* output;
char* buffer;
};
static void jpegWriteInit (j_compress_ptr) throw()
{
}
static void jpegWriteTerminate (j_compress_ptr cinfo) throw()
{
JuceJpegDest* const dest = (JuceJpegDest*) cinfo->dest;
const int numToWrite = bufferSize - dest->free_in_buffer;
dest->output->write (dest->buffer, numToWrite);
}
static boolean jpegWriteFlush (j_compress_ptr cinfo) throw()
{
JuceJpegDest* const dest = (JuceJpegDest*) cinfo->dest;
const int numToWrite = bufferSize;
dest->next_output_byte = (JOCTET*) dest->buffer;
dest->free_in_buffer = bufferSize;
return dest->output->write (dest->buffer, numToWrite);
}
//==============================================================================
bool juce_writeJPEGImageToStream (const Image& image,
OutputStream& out,
float quality) throw()
{
if (image.hasAlphaChannel())
{
// this method could fill the background in white and still save the image..
jassertfalse
return true;
}
struct jpeg_compress_struct jpegCompStruct;
struct jpeg_error_mgr jerr;
setupSilentErrorHandler (jerr);
jpegCompStruct.err = &jerr;
jpeg_create_compress (&jpegCompStruct);
JuceJpegDest dest;
jpegCompStruct.dest = &dest;
dest.output = &out;
dest.buffer = (char*) juce_malloc (bufferSize);
dest.next_output_byte = (JOCTET*) dest.buffer;
dest.free_in_buffer = bufferSize;
dest.init_destination = jpegWriteInit;
dest.empty_output_buffer = jpegWriteFlush;
dest.term_destination = jpegWriteTerminate;
jpegCompStruct.image_width = image.getWidth();
jpegCompStruct.image_height = image.getHeight();
jpegCompStruct.input_components = 3;
jpegCompStruct.in_color_space = JCS_RGB;
jpegCompStruct.write_JFIF_header = 1;
jpegCompStruct.X_density = 72;
jpegCompStruct.Y_density = 72;
jpeg_set_defaults (&jpegCompStruct);
jpegCompStruct.dct_method = JDCT_FLOAT;
jpegCompStruct.optimize_coding = 1;
// jpegCompStruct.smoothing_factor = 10;
if (quality < 0.0f)
quality = 0.85f;
jpeg_set_quality (&jpegCompStruct, jlimit (0, 100, roundFloatToInt (quality * 100.0f)), TRUE);
jpeg_start_compress (&jpegCompStruct, TRUE);
const int strideBytes = jpegCompStruct.image_width * jpegCompStruct.input_components;
JSAMPARRAY buffer = (*jpegCompStruct.mem->alloc_sarray) ((j_common_ptr) &jpegCompStruct,
JPOOL_IMAGE,
strideBytes, 1);
while (jpegCompStruct.next_scanline < jpegCompStruct.image_height)
{
int stride, pixelStride;
const uint8* pixels = image.lockPixelDataReadOnly (0, jpegCompStruct.next_scanline, jpegCompStruct.image_width, 1, stride, pixelStride);
const uint8* src = pixels;
uint8* dst = *buffer;
for (int i = jpegCompStruct.image_width; --i >= 0;)
{
*dst++ = ((const PixelRGB*) src)->getRed();
*dst++ = ((const PixelRGB*) src)->getGreen();
*dst++ = ((const PixelRGB*) src)->getBlue();
src += pixelStride;
}
jpeg_write_scanlines (&jpegCompStruct, buffer, 1);
image.releasePixelDataReadOnly (pixels);
}
jpeg_finish_compress (&jpegCompStruct);
jpeg_destroy_compress (&jpegCompStruct);
juce_free (dest.buffer);
out.flush();
return true;
}
END_JUCE_NAMESPACE

+ 1
- 1
src/juce_core/containers/juce_ArrayAllocationBase.h View File

@@ -104,7 +104,7 @@ protected:
elements = 0;
}
numAllocated = numElements;
numAllocated = numElements;
}
}


Loading…
Cancel
Save