Browse Source

tags/2021-05-28
jules 16 years ago
parent
commit
74058ac5f1
16 changed files with 6538 additions and 6407 deletions
  1. +1
    -1
      build/win32/platform_specific_code/juce_win32_ASIO.cpp
  2. +520
    -501
      src/juce_appframework/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp
  3. +0
    -1
      src/juce_appframework/audio/midi/juce_MidiMessage.cpp
  4. +3
    -3
      src/juce_appframework/audio/midi/juce_MidiMessageCollector.cpp
  5. +456
    -444
      src/juce_appframework/gui/components/controls/juce_Label.cpp
  6. +7
    -1
      src/juce_appframework/gui/components/controls/juce_Label.h
  7. +1368
    -1366
      src/juce_appframework/gui/components/controls/juce_Slider.cpp
  8. +2647
    -2597
      src/juce_appframework/gui/components/controls/juce_TextEditor.cpp
  9. +707
    -684
      src/juce_appframework/gui/components/controls/juce_TextEditor.h
  10. +442
    -421
      src/juce_appframework/gui/components/properties/juce_PropertyPanel.cpp
  11. +6
    -0
      src/juce_appframework/gui/components/properties/juce_PropertyPanel.h
  12. +378
    -376
      src/juce_appframework/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp
  13. +1
    -0
      src/juce_core/basics/juce_StandardHeader.h
  14. +1
    -1
      src/juce_core/containers/juce_BitArray.cpp
  15. +0
    -6
      src/juce_core/io/files/juce_File.cpp
  16. +1
    -5
      src/juce_core/text/juce_String.cpp

+ 1
- 1
build/win32/platform_specific_code/juce_win32_ASIO.cpp View File

@@ -833,7 +833,7 @@ public:
AudioIODeviceCallback* const oldCallback = currentCallback;
close();
open (currentChansIn, currentChansOut,
open (BitArray (currentChansIn), BitArray (currentChansOut),
currentSampleRate, currentBlockSizeSamples);
if (oldCallback != 0)


+ 520
- 501
src/juce_appframework/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp
File diff suppressed because it is too large
View File


+ 0
- 1
src/juce_appframework/audio/midi/juce_MidiMessage.cpp View File

@@ -63,7 +63,6 @@ int MidiMessage::getMessageLengthFromFirstByte (const uint8 firstByte) throw()
{
// this method only works for valid starting bytes of a short midi message
jassert (firstByte >= 0x80
&& firstByte != 0xff
&& firstByte != 0xf0
&& firstByte != 0xf7);


+ 3
- 3
src/juce_appframework/audio/midi/juce_MidiMessageCollector.cpp View File

@@ -110,7 +110,7 @@ void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer,
{
// if our list of events is longer than the buffer we're being
// asked for, scale them down to squeeze them all in..
const int maxBlockLengthToUse = numSamples << 3;
const int maxBlockLengthToUse = numSamples << 5;
if (numSourceSamples > maxBlockLengthToUse)
{
@@ -150,7 +150,7 @@ void MidiMessageCollector::removeNextBlockOfMessages (MidiBuffer& destBuffer,
void MidiMessageCollector::handleNoteOn (MidiKeyboardState*, int midiChannel, int midiNoteNumber, float velocity)
{
MidiMessage m (MidiMessage::noteOn (midiChannel, midiNoteNumber, velocity));
m.setTimeStamp (Time::getMillisecondCounter() * 0.001);
m.setTimeStamp (Time::getMillisecondCounterHiRes() * 0.001);
addMessageToQueue (m);
}
@@ -158,7 +158,7 @@ void MidiMessageCollector::handleNoteOn (MidiKeyboardState*, int midiChannel, in
void MidiMessageCollector::handleNoteOff (MidiKeyboardState*, int midiChannel, int midiNoteNumber)
{
MidiMessage m (MidiMessage::noteOff (midiChannel, midiNoteNumber));
m.setTimeStamp (Time::getMillisecondCounter() * 0.001);
m.setTimeStamp (Time::getMillisecondCounterHiRes() * 0.001);
addMessageToQueue (m);
}


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

@@ -1,444 +1,456 @@
/*
==============================================================================
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"
//==============================================================================
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),
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::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)
{
g.fillAll (findColour (backgroundColourId));
if (editor == 0)
{
const float alpha = isEnabled() ? 1.0f : 0.5f;
g.setColour (findColour (textColourId).withMultipliedAlpha (alpha));
g.setFont (font);
g.drawFittedText (text,
3, 1, getWidth() - 6, getHeight() - 2,
justification,
jmax (1, (int) (getHeight() / font.getHeight())));
g.setColour (findColour (outlineColourId).withMultipliedAlpha (alpha));
g.drawRect (0, 0, getWidth(), getHeight());
}
else if (isEnabled())
{
g.setColour (editor->findColour (TextEditor::backgroundColourId)
.overlaidWith (findColour (outlineColourId)));
g.drawRect (0, 0, getWidth(), getHeight());
}
}
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"


//==============================================================================
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),
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)
{
g.fillAll (findColour (backgroundColourId));

if (editor == 0)
{
const float alpha = isEnabled() ? 1.0f : 0.5f;

g.setColour (findColour (textColourId).withMultipliedAlpha (alpha));
g.setFont (font);
g.drawFittedText (text,
horizontalBorderSize,
verticalBorderSize,
getWidth() - 2 * horizontalBorderSize,
getHeight() - 2 * verticalBorderSize,
justification,
jmax (1, (int) (getHeight() / font.getHeight())));

g.setColour (findColour (outlineColourId).withMultipliedAlpha (alpha));
g.drawRect (0, 0, getWidth(), getHeight());
}
else if (isEnabled())
{
g.setColour (editor->findColour (TextEditor::backgroundColourId)
.overlaidWith (findColour (outlineColourId)));

g.drawRect (0, 0, getWidth(), getHeight());
}
}

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

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

@@ -148,6 +148,12 @@ public:
/** Returns the type of justification, as set in setJustificationType(). */
const Justification getJustificationType() const throw() { return justification; }
/** Changes the gap that is left between the edge of the component and the text.
By default there's a small gap left at the sides of the component to allow for
the drawing of the border, but you can change this if necessary.
*/
void setBorderSize (int horizontalBorder, int verticalBorder);
/** Makes this label "stick to" another component.
This will cause the label to follow another component around, staying
@@ -294,7 +300,7 @@ private:
SortedSet <void*> listeners;
Component* ownerComponent;
ComponentDeletionWatcher* deletionWatcher;
int horizontalBorderSize, verticalBorderSize;
bool editSingleClick : 1;
bool editDoubleClick : 1;
bool lossOfFocusDiscardsChanges : 1;


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


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


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


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

@@ -1,421 +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;
}
}
}
//==============================================================================
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

+ 6
- 0
src/juce_appframework/gui/components/properties/juce_PropertyPanel.h View File

@@ -109,6 +109,12 @@ public:
*/
void setSectionOpen (const int sectionIndex, const bool shouldBeOpen);
/** Enables or disables one of the sections.
The index is from 0 up to the number of items returned by getSectionNames().
*/
void setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled);
//==============================================================================
/** Saves the current state of open/closed sections so it can be restored later.


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

@@ -1,376 +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 (...)
{}
}
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
- 0
src/juce_core/basics/juce_StandardHeader.h View File

@@ -81,6 +81,7 @@
#include <stdexcept>
#include <typeinfo>
#include <cstring>
#include <cstdio>
#if JUCE_MAC || JUCE_LINUX
#include <pthread.h>


+ 1
- 1
src/juce_core/containers/juce_BitArray.cpp View File

@@ -958,7 +958,7 @@ void BitArray::parseString (const String& text,
const MemoryBlock BitArray::toMemoryBlock() const throw()
{
const int numBytes = (getHighestBit() + 7) >> 3;
const int numBytes = (getHighestBit() + 8) >> 3;
MemoryBlock mb (numBytes);
for (int i = 0; i < numBytes; ++i)


+ 0
- 6
src/juce_core/io/files/juce_File.cpp View File

@@ -1068,14 +1068,8 @@ const String File::getRelativePathFrom (const File& dir) const throw()
--commonBitLength;
// if the only common bit is the root, then just return the full path..
#if JUCE_WIN32
if (commonBitLength <= 0
|| (commonBitLength == 1 && thisPath [1] == File::separator)
|| (commonBitLength <= 3 && thisPath [1] == T(':')))
#else
if (commonBitLength <= 0
|| (commonBitLength == 1 && thisPath [1] == File::separator))
#endif
return fullPath;
thisPath = thisPath.substring (commonBitLength);


+ 1
- 5
src/juce_core/text/juce_String.cpp View File

@@ -1946,15 +1946,11 @@ const String String::toHexString (const unsigned char* data,
*d++ = hexDigits [(*data) & 0xf];
++data;

if (groupSize > 0 && (i % groupSize) == 0)
if (groupSize > 0 && (i % groupSize) == (groupSize - 1) && i < (size - 1))
*d++ = T(' ');
}

if (groupSize > 0)
--d;

*d = 0;

return s;
}



Loading…
Cancel
Save