diff options
Diffstat (limited to 'libs')
122 files changed, 10358 insertions, 3553 deletions
diff --git a/libs/appleutility/CAAudioFile.h b/libs/appleutility/CAAudioFile.h index 2cfb4f3031..ce22bfe466 100644 --- a/libs/appleutility/CAAudioFile.h +++ b/libs/appleutility/CAAudioFile.h @@ -43,6 +43,7 @@ #ifndef __CAAudioFile_h__ #define __CAAudioFile_h__ +#include <iostream> #include <AvailabilityMacros.h> #if !defined(__COREAUDIO_USE_FLAT_INCLUDES__) @@ -98,6 +99,7 @@ public: // implementation-independent helpers void Open(const char *filePath) { FSRef fsref; + std::cerr << "Opening " << filePath << std::endl; XThrowIfError(FSPathMakeRef((UInt8 *)filePath, &fsref, NULL), "locate audio file"); Open(fsref); } @@ -112,9 +114,10 @@ public: // or the file's sample rate is 0 (unknown) #if CAAF_USE_EXTAUDIOFILE +#warning HERE WE ARE public: - CAAudioFile() : mExtAF(NULL) { } - virtual ~CAAudioFile() { if (mExtAF) Close(); } + CAAudioFile() : mExtAF(NULL) { std::cerr << "Constructing CAAudioFile\n"; } + virtual ~CAAudioFile() { std::cerr << "Destroying CAAudiofile @ " << this << std::endl; if (mExtAF) Close(); } void Open(const FSRef &fsref) { // open an existing file @@ -131,6 +134,7 @@ public: } void Close() { + std::cerr << "\tdisposeo of ext audio file @ " << mExtAF << std::endl; XThrowIfError(ExtAudioFileDispose(mExtAF), "ExtAudioFileClose failed"); mExtAF = NULL; } diff --git a/libs/appleutility/SConscript b/libs/appleutility/SConscript index c4f65ec81e..7a3a5c8975 100644 --- a/libs/appleutility/SConscript +++ b/libs/appleutility/SConscript @@ -4,7 +4,7 @@ import os import os.path import glob -appleutility_files = glob.glob('*.cpp') +appleutility_files = [ glob.glob('*.cpp') + glob.glob('*.c') + glob.glob('*.C') ] Import('env install_prefix') appleutility = env.Clone() diff --git a/libs/ardour/analyser.cc b/libs/ardour/analyser.cc index 2e14c74b86..28eeeb190c 100644 --- a/libs/ardour/analyser.cc +++ b/libs/ardour/analyser.cc @@ -75,7 +75,7 @@ Analyser::queue_source_for_analysis (boost::shared_ptr<Source> src, bool force) void Analyser::work () { - PBD::ThreadCreated (pthread_self(), string ("analyser-") + to_string (pthread_self(), std::dec)); + PBD::notify_gui_about_thread_creation (pthread_self(), string ("analyser-") + to_string (pthread_self(), std::dec)); while (true) { analysis_queue_lock.lock (); diff --git a/libs/ardour/ardour/audio_buffer.h b/libs/ardour/ardour/audio_buffer.h index 71eaf60ade..9a41e8e093 100644 --- a/libs/ardour/ardour/audio_buffer.h +++ b/libs/ardour/ardour/audio_buffer.h @@ -78,6 +78,19 @@ public: _silent = ( (src.silent() && _silent) || (_silent && gain_coeff == 0) ); } + + /** Accumulate (add) @a len frames FROM THE START OF @a src into self at @a offset + * scaling by @a gain_coeff */ + void accumulate_with_gain_from(const Sample* src_raw, nframes_t len, nframes_t offset, gain_t gain_coeff) { + assert(_capacity > 0); + assert(offset + len <= _capacity); + + Sample* const dst_raw = _data + offset; + + mix_buffers_with_gain (dst_raw, src_raw, len, gain_coeff); + + _silent = (_silent && gain_coeff == 0); + } void apply_gain(gain_t gain, nframes_t len, nframes_t offset=0) { apply_gain_to_buffer (_data + offset, len, gain); diff --git a/libs/ardour/ardour/audioregion.h b/libs/ardour/ardour/audioregion.h index b8cde44b77..5ebe22e312 100644 --- a/libs/ardour/ardour/audioregion.h +++ b/libs/ardour/ardour/audioregion.h @@ -56,6 +56,10 @@ class AudioRegion : public Region ~AudioRegion(); + void copy_settings (boost::shared_ptr<const AudioRegion>); + + bool source_equivalent (boost::shared_ptr<const Region>) const; + bool speed_mismatch (float) const; boost::shared_ptr<AudioSource> audio_source (uint32_t n=0) const; @@ -78,8 +82,17 @@ class AudioRegion : public Region uint32_t chan_n=0, double samples_per_unit= 1.0) const; /* Readable interface */ + + enum ReadOps { + ReadOpsNone = 0x0, + ReadOpsOwnAutomation = 0x1, + ReadOpsOwnScaling = 0x2, + ReadOpsCount = 0x4, + ReadOpsFades = 0x8 + }; virtual nframes64_t read (Sample*, nframes64_t pos, nframes64_t cnt, int channel) const; + virtual nframes64_t read_with_ops (Sample*, nframes64_t pos, nframes64_t cnt, int channel, ReadOps rops) const; virtual nframes64_t readable_length() const { return length(); } virtual nframes_t read_at (Sample *buf, Sample *mixdown_buf, @@ -151,11 +164,14 @@ class AudioRegion : public Region private: friend class RegionFactory; + friend class Crossfade; AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length); AudioRegion (boost::shared_ptr<AudioSource>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); AudioRegion (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); AudioRegion (boost::shared_ptr<const AudioRegion>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); + AudioRegion (boost::shared_ptr<const AudioRegion>, const SourceList&, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags); + AudioRegion (boost::shared_ptr<const AudioRegion>); AudioRegion (boost::shared_ptr<AudioSource>, const XMLNode&); AudioRegion (SourceList &, const XMLNode&); @@ -174,7 +190,7 @@ class AudioRegion : public Region uint32_t chan_n = 0, nframes_t read_frames = 0, nframes_t skip_frames = 0, - bool raw = false) const; + ReadOps readops = ReadOps (~0)) const; void recompute_at_start (); void recompute_at_end (); @@ -201,7 +217,6 @@ class AudioRegion : public Region /* default constructor for derived (compound) types */ AudioRegion (Session& s, nframes_t, nframes_t, std::string name); - AudioRegion (boost::shared_ptr<const AudioRegion>); int set_live_state (const XMLNode&, Change&, bool send); }; diff --git a/libs/ardour/ardour/automation_control.h b/libs/ardour/ardour/automation_control.h index db481b2f99..4cb6d1a79a 100644 --- a/libs/ardour/ardour/automation_control.h +++ b/libs/ardour/ardour/automation_control.h @@ -59,6 +59,10 @@ public: return ((ARDOUR::AutomationList*)_list.get())->automation_state(); } + inline void set_automation_state(AutoState as) { + return ((ARDOUR::AutomationList*)_list.get())->set_automation_state(as); + } + inline void start_touch() { return ((ARDOUR::AutomationList*)_list.get())->start_touch(); } diff --git a/libs/ardour/ardour/automation_list.h b/libs/ardour/ardour/automation_list.h index d5aff74ab9..923967448c 100644 --- a/libs/ardour/ardour/automation_list.h +++ b/libs/ardour/ardour/automation_list.h @@ -42,12 +42,12 @@ class AutomationList : public PBD::StatefulDestructible, public Evoral::ControlL public: AutomationList (Evoral::Parameter id); AutomationList (const XMLNode&, Evoral::Parameter id); + AutomationList (const AutomationList&); + AutomationList (const AutomationList&, double start, double end); ~AutomationList(); virtual boost::shared_ptr<Evoral::ControlList> create(Evoral::Parameter id); - AutomationList (const AutomationList&); - AutomationList (const AutomationList&, double start, double end); AutomationList& operator= (const AutomationList&); bool operator== (const AutomationList&); diff --git a/libs/ardour/ardour/configuration_vars.h b/libs/ardour/ardour/configuration_vars.h index 5565e20401..bbf766d877 100644 --- a/libs/ardour/ardour/configuration_vars.h +++ b/libs/ardour/ardour/configuration_vars.h @@ -95,6 +95,7 @@ CONFIG_VARIABLE (bool, solo_latched, "solo-latched", true) CONFIG_VARIABLE (bool, latched_record_enable, "latched-record-enable", false) CONFIG_VARIABLE (bool, all_safe, "all-safe", false) CONFIG_VARIABLE (bool, show_solo_mutes, "show-solo-mutes", false) +CONFIG_VARIABLE (bool, solo_mute_override, "solo-mute-override", false) CONFIG_VARIABLE (bool, tape_machine_mode, "tape-machine-mode", false) /* click */ @@ -161,6 +162,7 @@ CONFIG_VARIABLE (uint32_t, periodic_safety_backup_interval, "periodic-safety-bac CONFIG_VARIABLE (float, automation_interval, "automation-interval", 50) CONFIG_VARIABLE (bool, sync_all_route_ordering, "sync-all-route-ordering", true) CONFIG_VARIABLE (bool, only_copy_imported_files, "only-copy-imported-files", true) +CONFIG_VARIABLE (bool, new_plugins_active, "new-plugins-active", true) CONFIG_VARIABLE (std::string, keyboard_layout, "keyboard-layout", "ansi") CONFIG_VARIABLE (std::string, default_bindings, "default-bindings", "ardour") CONFIG_VARIABLE (bool, default_narrow_ms, "default-narrow_ms", false) diff --git a/libs/ardour/ardour/osc.h b/libs/ardour/ardour/osc.h index d7c2f4bd85..33759feb91 100644 --- a/libs/ardour/ardour/osc.h +++ b/libs/ardour/ardour/osc.h @@ -120,6 +120,29 @@ class OSC : public BasicUI, public sigc::trackable PATH_CALLBACK1(set_transport_speed,f,); PATH_CALLBACK1(access_action,s,&); + +#define PATH_CALLBACK2(name,arg1type,arg2type) \ + static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \ + return static_cast<OSC*>(user_data)->cb_ ## name (path, types, argv, argc, data); \ + } \ + int cb_ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data) { \ + if (argc > 1) { \ + name (argv[0]->arg1type, argv[1]->arg2type); \ + } \ + return 0; \ + } + + PATH_CALLBACK2(route_mute,i,i); + PATH_CALLBACK2(route_solo,i,i); + PATH_CALLBACK2(route_recenable,i,i); + PATH_CALLBACK2(route_set_gain_abs,i,f); + PATH_CALLBACK2(route_set_gain_dB,i,f); + + int route_mute (int rid, int yn); + int route_solo (int rid, int yn); + int route_recenable (int rid, int yn); + int route_set_gain_abs (int rid, float level); + int route_set_gain_dB (int rid, float dB); }; } diff --git a/libs/ardour/ardour/region.h b/libs/ardour/ardour/region.h index d3c8341623..66f5d2be35 100644 --- a/libs/ardour/ardour/region.h +++ b/libs/ardour/ardour/region.h @@ -131,8 +131,9 @@ class Region nframes_t sync_offset(int& dir) const; nframes_t sync_position() const; + nframes_t sync_point () const; - nframes_t adjust_to_sync (nframes_t); + nframes_t adjust_to_sync (nframes_t) const; /* first_frame() is an alias; last_frame() just hides some math */ @@ -264,6 +265,7 @@ class Region const string& name, DataType type, layer_t = 0, Flag flags = DefaultFlags); Region (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); + Region (boost::shared_ptr<const Region>, nframes_t length, const string& name, layer_t = 0, Flag flags = DefaultFlags); Region (boost::shared_ptr<const Region>); Region (boost::shared_ptr<Source> src, const XMLNode&); Region (const SourceList& srcs, const XMLNode&); @@ -271,6 +273,8 @@ class Region Region (Session& s, nframes_t start, nframes_t length, const string& name, DataType, layer_t = 0, Flag flags = DefaultFlags); protected: + void copy_stuff (boost::shared_ptr<const Region>, nframes_t start, nframes_t length, const string& name, layer_t, Flag flags); + XMLNode& get_short_state (); /* used only by Session */ void send_change (Change); diff --git a/libs/ardour/ardour/region_factory.h b/libs/ardour/ardour/region_factory.h index 12437ba998..b88f3b225a 100644 --- a/libs/ardour/ardour/region_factory.h +++ b/libs/ardour/ardour/region_factory.h @@ -48,11 +48,12 @@ class RegionFactory { */ static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, nframes_t start, - nframes_t length, std::string name, + nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); static boost::shared_ptr<Region> create (boost::shared_ptr<AudioRegion>, nframes_t start, - nframes_t length, std::string name, + nframes_t length, const std::string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); + static boost::shared_ptr<Region> create (boost::shared_ptr<Region>, const SourceList&, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); static boost::shared_ptr<Region> create (boost::shared_ptr<Source>, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); static boost::shared_ptr<Region> create (const SourceList &, nframes_t start, nframes_t length, const string& name, layer_t = 0, Region::Flag flags = Region::DefaultFlags, bool announce = true); static boost::shared_ptr<Region> create (Session&, XMLNode&, bool); diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h index f963d3b2cf..28d15b7090 100644 --- a/libs/ardour/ardour/route.h +++ b/libs/ardour/ardour/route.h @@ -107,6 +107,8 @@ class Route : public IO /* end of vfunc-based API */ + void shift (nframes64_t, nframes64_t); + /* override IO::set_gain() to provide group control */ void set_gain (gain_t val, void *src); @@ -117,7 +119,7 @@ class Route : public IO void set_solo_safe (bool yn, void *src); bool solo_safe() const { return _solo_safe; } - + void set_mute (bool yn, void *src); bool muted() const { return _muted; } bool solo_muted() const { return desired_solo_gain == 0.0; } @@ -262,6 +264,7 @@ class Route : public IO protected: friend class Session; + void catch_up_on_solo_mute_override (); void set_solo_mute (bool yn); void set_block_size (nframes_t nframes); bool has_external_redirects() const; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 017a78a015..16db305f94 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -413,6 +413,10 @@ class Session : public PBD::StatefulDestructible double frames_per_smpte_frame() const { return _frames_per_smpte_frame; } nframes_t smpte_frames_per_hour() const { return _smpte_frames_per_hour; } + MIDI::byte get_mtc_smpte_bits() const { + return mtc_smpte_bits; /* encoding of SMTPE type for MTC */ + } + float smpte_frames_per_second() const; bool smpte_drop_frames() const; @@ -610,6 +614,7 @@ class Session : public PBD::StatefulDestructible string doing_what; /* control info */ + uint32_t total; SrcQuality quality; volatile bool freeze; std::vector<Glib::ustring> paths; @@ -617,7 +622,6 @@ class Session : public PBD::StatefulDestructible /* result */ SourceList sources; - }; void import_audiofiles (import_status&); @@ -964,6 +968,10 @@ class Session : public PBD::StatefulDestructible void add_controllable (boost::shared_ptr<PBD::Controllable>); void remove_controllable (PBD::Controllable*); + /* metadata */ + + SessionMetadata & metadata () { return *_metadata; } + protected: friend class AudioEngine; void set_block_size (nframes_t nframes); @@ -1457,6 +1465,7 @@ class Session : public PBD::StatefulDestructible void route_mute_changed (void *src); void route_solo_changed (void *src, boost::weak_ptr<Route>); void catch_up_on_solo (); + void catch_up_on_solo_mute_override (); void update_route_solo_state (); void modify_solo_mute (bool, bool); void strip_portname_for_solo (string& portname); @@ -1701,6 +1710,12 @@ class Session : public PBD::StatefulDestructible uint32_t n_physical_outputs; uint32_t n_physical_inputs; + uint32_t n_physical_audio_outputs; + uint32_t n_physical_audio_inputs; + + uint32_t n_physical_midi_outputs; + uint32_t n_physical_midi_inputs; + int find_all_sources (std::string path, std::set<std::string>& result); int find_all_sources_across_snapshots (std::set<std::string>& result, bool exclude_this_snapshot); @@ -1728,8 +1743,10 @@ class Session : public PBD::StatefulDestructible /* Metadata */ SessionMetadata * _metadata; - public: - SessionMetadata & metadata () { return *_metadata; } + + /* used in ::audible_frame() */ + + mutable bool have_looped; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/slave.h b/libs/ardour/ardour/slave.h index ff8f48cd38..ffeacd3017 100644 --- a/libs/ardour/ardour/slave.h +++ b/libs/ardour/ardour/slave.h @@ -186,6 +186,7 @@ class MTC_Slave : public Slave, public sigc::trackable { SafeTime current; nframes_t mtc_frame; /* current time */ nframes_t last_inbound_frame; /* when we got it; audio clocked */ + MIDI::byte last_mtc_fps_byte; float mtc_speed; nframes_t first_mtc_frame; diff --git a/libs/ardour/ardour/svn_revision.h b/libs/ardour/ardour/svn_revision.h index a44b97b5da..6c11d55e50 100644 --- a/libs/ardour/ardour/svn_revision.h +++ b/libs/ardour/ardour/svn_revision.h @@ -1,6 +1,8 @@ #ifndef __ardour_svn_revision_h__ #define __ardour_svn_revision_h__ + namespace ARDOUR { -extern const char* svn_revision; + extern const char* svn_revision; } + #endif diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h index fedd83ba68..b524c5d587 100644 --- a/libs/ardour/ardour/track.h +++ b/libs/ardour/ardour/track.h @@ -124,6 +124,9 @@ class Track : public Route vector<FreezeRecordProcessorInfo*> processor_info; bool have_mementos; FreezeState state; + gain_t gain; + AutoState gain_automation_state; + AutoState pan_automation_state; }; struct RecEnableControllable : public PBD::Controllable { diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index d30899caf8..816f08cbd5 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -586,19 +586,74 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, /* copy the diskstream data to all output buffers */ - - const size_t limit = n_process_buffers().n_audio(); - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); - + + size_t limit = n_process_buffers().n_audio(); + BufferSet& bufs = _session.get_scratch_buffers (); + const size_t blimit = bufs.count().n_audio(); + uint32_t n; uint32_t i; - for (i = 0, n = 1; i < limit; ++i, ++n) { - memcpy (bufs.get_audio(i).data(), b, sizeof (Sample) * nframes); - if (n < diskstream->n_channels().n_audio()) { - tmpb = diskstream->playback_buffer(n); - if (tmpb!=0) { - b = tmpb; + if (limit > blimit) { + + /* example case: auditioner configured for stereo output, + but loaded with an 8 channel file. there are only + 2 passthrough buffers, but n_process_buffers() will + return 8. + + arbitrary decision: map all channels in the diskstream + to the outputs available. + */ + + float scaling = limit/blimit; + + for (i = 0, n = 1; i < blimit; ++i, ++n) { + + /* first time through just copy a channel into + the output buffer. + */ + + Sample* bb = bufs.get_audio (i).data(); + + for (nframes_t xx = 0; xx < nframes; ++xx) { + bb[xx] = b[xx] * scaling; + } + + if (n < diskstream->n_channels().n_audio()) { + tmpb = diskstream->playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } + } + } + + for (;i < limit; ++i, ++n) { + + /* for all remaining channels, sum with existing + data in the output buffers + */ + + bufs.get_audio (i%blimit).accumulate_with_gain_from (b, nframes, 0, scaling); + + if (n < diskstream->n_channels().n_audio()) { + tmpb = diskstream->playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } + } + + } + + limit = blimit; + + } else { + for (i = 0, n = 1; i < limit; ++i, ++n) { + memcpy (bufs.get_audio (i).data(), b, sizeof (Sample) * nframes); + if (n < diskstream->n_channels().n_audio()) { + tmpb = diskstream->playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } } } } @@ -830,6 +885,11 @@ AudioTrack::freeze (InterThreadInfo& itt) } new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false); + + _freeze_record.gain = _gain; + _freeze_record.gain_automation_state = _gain_control->automation_state(); + _freeze_record.pan_automation_state = _panner->automation_state(); + region_name = new_playlist_name; /* create a new region from all filesources, keep it private */ @@ -847,6 +907,12 @@ AudioTrack::freeze (InterThreadInfo& itt) diskstream->use_playlist (boost::dynamic_pointer_cast<AudioPlaylist>(new_playlist)); diskstream->set_record_enabled (false); + /* reset stuff that has already been accounted for in the freeze process */ + + set_gain (1.0, this); + _gain_control->set_automation_state (Off); + _panner->set_automation_state (Off); + _freeze_record.state = Frozen; FreezeChange(); /* EMIT SIGNAL */ } @@ -877,6 +943,9 @@ AudioTrack::unfreeze () } _freeze_record.playlist.reset (); + set_gain (_freeze_record.gain, this); + _gain_control->set_automation_state (_freeze_record.gain_automation_state); + _panner->set_automation_state (_freeze_record.pan_automation_state); } _freeze_record.state = UnFrozen; diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index 9c7ea0f13f..16d5e390f8 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -103,7 +103,15 @@ AUPlugin::~AUPlugin () void AUPlugin::init () { - OSErr err = CAAudioUnit::Open (*(comp.get()), *unit); + OSErr err; + + try { + err = CAAudioUnit::Open (*(comp.get()), *unit); + } catch (...) { + error << _("Exception thrown during AudioUnit plugin loading - plugin ignored") << endmsg; + cerr << _("Exception thrown during AudioUnit plugin loading - plugin ignored") << endl; + throw failed_constructor(); + } if (err != noErr) { error << _("AudioUnit: Could not convert CAComponent to CAAudioUnit") << endmsg; @@ -1090,6 +1098,7 @@ AUPluginInfo::cached_io_configuration (const std::string& unique_id, } catch (...) { warning << string_compose (_("Could not load AU plugin %1 - ignored"), name) << endmsg; + cerr << string_compose (_("Could not load AU plugin %1 - ignored"), name) << endl; return false; } diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 788017555a..8b5d4ba42c 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -132,7 +132,7 @@ _thread_init_callback (void *arg) knows about it. */ - PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("Audioengine"), 4096); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("Audioengine"), 4096); MIDI::JACK_MidiPort::set_process_thread (pthread_self()); } @@ -922,8 +922,6 @@ AudioEngine::halted (void *arg) ae->_buffer_size = 0; ae->_frame_rate = 0; - cerr << "!!! HALTED !!!\n"; - if (was_running) { ae->Halted(); /* EMIT SIGNAL */ } @@ -1318,7 +1316,7 @@ AudioEngine::reconnect_to_jack () if (Config->get_jack_time_master()) { jack_set_timebase_callback (_jack, 0, _jack_timebase_callback, this); - } + } if (jack_activate (_jack) == 0) { _running = true; diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index c5c04bc33d..5d4748c2d4 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -133,9 +133,9 @@ AudioRegion::AudioRegion (const SourceList& srcs, nframes_t start, nframes_t len AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) : Region (other, offset, length, name, layer, flags) , _automatable(other->session()) - , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation))) - , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation))) - , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation))) + , _fade_in (new AutomationList(*other->_fade_in, offset, offset + length)) + , _fade_out (new AutomationList(*other->_fade_out, offset, offset + length)) + , _envelope (new AutomationList(*other->_envelope, offset, offset + length)) { set<boost::shared_ptr<Source> > unique_srcs; @@ -185,17 +185,48 @@ AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, nframes_t AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other) : Region (other) - , _automatable(other->session()) - , _fade_in (new AutomationList(Evoral::Parameter(FadeInAutomation))) - , _fade_out (new AutomationList(Evoral::Parameter(FadeOutAutomation))) - , _envelope (new AutomationList(Evoral::Parameter(EnvelopeAutomation))) + , _automatable (other->session()) + , _fade_in (new AutomationList (*other->_fade_in)) + , _fade_out (new AutomationList (*other->_fade_out)) + , _envelope (new AutomationList (*other->_envelope)) { assert(_type == DataType::AUDIO); _scale_amplitude = other->_scale_amplitude; - _envelope = other->_envelope; set_default_fades (); - + + listen_to_my_curves (); + listen_to_my_sources (); +} + +AudioRegion::AudioRegion (boost::shared_ptr<const AudioRegion> other, const SourceList& srcs, + nframes_t length, const string& name, layer_t layer, Flag flags) + : Region (other, length, name, layer, flags) + , _automatable (other->session()) + , _fade_in (new AutomationList (*other->_fade_in)) + , _fade_out (new AutomationList (*other->_fade_out)) + , _envelope (new AutomationList (*other->_envelope)) +{ + /* make-a-sort-of-copy-with-different-sources constructor (used by audio filter) */ + + set<boost::shared_ptr<AudioSource> > unique_srcs; + + for (SourceList::const_iterator i=srcs.begin(); i != srcs.end(); ++i) { + + _sources.push_back (*i); + _master_sources.push_back (*i); + + boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> ((*i)); + if (afs) { + afs->HeaderPositionOffsetChanged.connect (mem_fun (*this, &AudioRegion::source_offset_changed)); + } + } + + _scale_amplitude = other->_scale_amplitude; + + _fade_in_disabled = 0; + _fade_out_disabled = 0; + listen_to_my_curves (); listen_to_my_sources (); } @@ -296,19 +327,25 @@ AudioRegion::read_peaks (PeakData *buf, nframes_t npeaks, nframes_t offset, nfra } nframes64_t -AudioRegion::read (Sample* buf, nframes64_t position, nframes64_t cnt, int channel) const +AudioRegion::read (Sample* buf, nframes64_t timeline_position, nframes64_t cnt, int channel) const { /* raw read, no fades, no gain, nada */ - return _read_at (_sources, _length, buf, 0, 0, _position + position, cnt, channel, 0, 0, true); + return _read_at (_sources, _length, buf, 0, 0, _position + timeline_position, cnt, channel, 0, 0, ReadOps (0)); +} + +nframes64_t +AudioRegion::read_with_ops (Sample* buf, nframes64_t file_position, nframes64_t cnt, int channel, ReadOps rops) const +{ + return _read_at (_sources, _length, buf, 0, 0, file_position, cnt, channel, 0, 0, rops); } nframes_t -AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t position, +AudioRegion::read_at (Sample *buf, Sample *mixdown_buffer, float *gain_buffer, nframes_t file_position, nframes_t cnt, uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const { /* regular diskstream/butler read complete with fades etc */ - return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, position, cnt, chan_n, read_frames, skip_frames, false); + return _read_at (_sources, _length, buf, mixdown_buffer, gain_buffer, file_position, cnt, chan_n, read_frames, skip_frames, ReadOps (~0)); } nframes_t @@ -325,11 +362,12 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames, - bool raw) const + ReadOps rops) const { nframes_t internal_offset; nframes_t buf_offset; nframes_t to_read; + bool raw = (rops == ReadOpsNone); if (muted() && !raw) { return 0; /* read nothing */ @@ -361,7 +399,7 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, mixdown_buffer += buf_offset; } - if (!raw) { + if (rops & ReadOpsCount) { _read_data_count = 0; } @@ -372,7 +410,7 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, return 0; /* "read nothing" */ } - if (!raw) { + if (rops & ReadOpsCount) { _read_data_count += src->read_data_count(); } @@ -383,18 +421,12 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, */ memset (mixdown_buffer, 0, sizeof (Sample) * cnt); - - /* no fades required */ - - if (!raw) { - goto merge; - } } - /* fade in */ - - if (!raw) { + if (rops & ReadOpsFades) { + /* fade in */ + if ((_flags & FadeIn) && Config->get_use_region_fades()) { nframes_t fade_in_length = (nframes_t) _fade_in->back()->when; @@ -407,6 +439,7 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, fi_limit = min (to_read, fade_in_length - internal_offset); + _fade_in->curve().get_vector (internal_offset, internal_offset+fi_limit, gain_buffer, fi_limit); for (nframes_t n = 0; n < fi_limit; ++n) { @@ -422,12 +455,12 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, /* see if some part of this read is within the fade out */ /* ................. >| REGION - limit + limit { } FADE fade_out_length ^ - limit - fade_out_length + limit - fade_out_length |--------------| ^internal_offset ^internal_offset + to_read @@ -457,39 +490,43 @@ AudioRegion::_read_at (const SourceList& srcs, nframes_t limit, } } + } - /* Regular gain curves */ - - if (envelope_active()) { - _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read); + /* Regular gain curves and scaling */ + + if ((rops & ReadOpsOwnAutomation) && envelope_active()) { + _envelope->curve().get_vector (internal_offset, internal_offset + to_read, gain_buffer, to_read); - if (_scale_amplitude != 1.0f) { - for (nframes_t n = 0; n < to_read; ++n) { - mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude; - } - } else { - for (nframes_t n = 0; n < to_read; ++n) { - mixdown_buffer[n] *= gain_buffer[n]; - } + if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) { + for (nframes_t n = 0; n < to_read; ++n) { + mixdown_buffer[n] *= gain_buffer[n] * _scale_amplitude; } - } else if (_scale_amplitude != 1.0f) { - apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude); + } else { + for (nframes_t n = 0; n < to_read; ++n) { + mixdown_buffer[n] *= gain_buffer[n]; + } + } + } else if ((rops & ReadOpsOwnScaling) && _scale_amplitude != 1.0f) { + + // XXX this should be using what in 2.0 would have been: + // Session::apply_gain_to_buffer (mixdown_buffer, to_read, _scale_amplitude); + + for (nframes_t n = 0; n < to_read; ++n) { + mixdown_buffer[n] *= _scale_amplitude; } + } - merge: + if (!opaque()) { - if (!opaque()) { - - /* gack. the things we do for users. - */ - - buf += buf_offset; + /* gack. the things we do for users. + */ + + buf += buf_offset; - for (nframes_t n = 0; n < to_read; ++n) { - buf[n] += mixdown_buffer[n]; - } - } - } + for (nframes_t n = 0; n < to_read; ++n) { + buf[n] += mixdown_buffer[n]; + } + } return to_read; } diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index 4383f1a696..a6aceb7842 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -19,6 +19,8 @@ */ #include <algorithm> +#define __STDC_FORMAT_MACROS +#include <inttypes.h> #include <pbd/error.h> #include <ardour/coreaudiosource.h> @@ -256,7 +258,103 @@ CoreAudioSource::get_soundfile_info (string path, SoundFileInfo& _info, string& goto out; } - _info.format_name = CFStringRefToStdString(name); + _info.format_name = ""; + + if (absd.mFormatID == kAudioFormatLinearPCM) { + if (absd.mFormatFlags & kAudioFormatFlagIsBigEndian) { + _info.format_name += "big-endian"; + } else { + _info.format_name += "little-endian"; + } + + char buf[32]; + snprintf (buf, sizeof (buf), " %" PRIu32 " bit", absd.mBitsPerChannel); + _info.format_name += buf; + _info.format_name += '\n'; + + if (absd.mFormatFlags & kAudioFormatFlagIsFloat) { + _info.format_name += "float"; + } else { + if (absd.mFormatFlags & kAudioFormatFlagIsSignedInteger) { + _info.format_name += "signed"; + } else { + _info.format_name += "unsigned"; + } + /* integer is typical, do not show it */ + } + + if (_info.channels > 1) { + if (absd.mFormatFlags & kAudioFormatFlagIsNonInterleaved) { + _info.format_name += " noninterleaved"; + } + /* interleaved is the normal case, do not show it */ + } + + _info.format_name += ' '; + } + + switch (absd.mFormatID) { + case kAudioFormatLinearPCM: + _info.format_name += "PCM"; + break; + + case kAudioFormatAC3: + _info.format_name += "AC3"; + break; + + case kAudioFormat60958AC3: + _info.format_name += "60958 AC3"; + break; + + case kAudioFormatMPEGLayer1: + _info.format_name += "MPEG-1"; + break; + + case kAudioFormatMPEGLayer2: + _info.format_name += "MPEG-2"; + break; + + case kAudioFormatMPEGLayer3: + _info.format_name += "MPEG-3"; + break; + + case kAudioFormatAppleIMA4: + _info.format_name += "IMA-4"; + break; + + case kAudioFormatMPEG4AAC: + _info.format_name += "AAC"; + break; + + case kAudioFormatMPEG4CELP: + _info.format_name += "CELP"; + break; + + case kAudioFormatMPEG4HVXC: + _info.format_name += "HVXC"; + break; + + case kAudioFormatMPEG4TwinVQ: + _info.format_name += "TwinVQ"; + break; + + /* these really shouldn't show up, but we should do something + somewhere else to make sure that doesn't happen. until + that is guaranteed, print something anyway. + */ + + case kAudioFormatTimeCode: + _info.format_name += "timecode"; + break; + + case kAudioFormatMIDIStream: + _info.format_name += "MIDI"; + break; + + case kAudioFormatParameterValueStream: + _info.format_name += "parameter values"; + break; + } // XXX it would be nice to find a way to get this information if it exists diff --git a/libs/ardour/crossfade.cc b/libs/ardour/crossfade.cc index 05ea7765f0..3a7b525db6 100644 --- a/libs/ardour/crossfade.cc +++ b/libs/ardour/crossfade.cc @@ -217,22 +217,57 @@ Crossfade::initialize () _fade_out.freeze (); _fade_out.clear (); - _fade_out.add (0.0, 1.0); - _fade_out.add ((_length * 0.1), 0.99); - _fade_out.add ((_length * 0.2), 0.97); - _fade_out.add ((_length * 0.8), 0.03); - _fade_out.add ((_length * 0.9), 0.01); - _fade_out.add (_length, 0.0); + +#define EQUAL_POWER_MINUS_3DB +#ifdef EQUAL_POWER_MINUS_3DB + + _fade_out.add ((_length * 0.000000), 1.000000); + _fade_out.add ((_length * 0.166667), 0.948859); + _fade_out.add ((_length * 0.333333), 0.851507); + _fade_out.add ((_length * 0.500000), 0.707946); + _fade_out.add ((_length * 0.666667), 0.518174); + _fade_out.add ((_length * 0.833333), 0.282192); + _fade_out.add ((_length * 1.000000), 0.000000); + +#else // EQUAL_POWER_MINUS_6DB + + _fade_out.add ((_length * 0.000000), 1.000000); + _fade_out.add ((_length * 0.166667), 0.833033); + _fade_out.add ((_length * 0.333333), 0.666186); + _fade_out.add ((_length * 0.500000), 0.499459); + _fade_out.add ((_length * 0.666667), 0.332853); + _fade_out.add ((_length * 0.833333), 0.166366); + _fade_out.add ((_length * 1.000000), 0.000000); +#endif + _fade_out.thaw (); _fade_in.freeze (); _fade_in.clear (); - _fade_in.add (0.0, 0.0); - _fade_in.add ((_length * 0.1), 0.01); - _fade_in.add ((_length * 0.2), 0.03); - _fade_in.add ((_length * 0.8), 0.97); - _fade_in.add ((_length * 0.9), 0.99); - _fade_in.add (_length, 1.0); + +#define EQUAL_POWER_MINUS_3DB +#ifdef EQUAL_POWER_MINUS_3DB + + _fade_in.add ((_length * 0.000000), 0.000000); + _fade_in.add ((_length * 0.166667), 0.282192); + _fade_in.add ((_length * 0.333333), 0.518174); + _fade_in.add ((_length * 0.500000), 0.707946); + _fade_in.add ((_length * 0.666667), 0.851507); + _fade_in.add ((_length * 0.833333), 0.948859); + _fade_in.add ((_length * 1.000000), 1.000000); + +#else // EQUAL_POWER_MINUS_SIX_DB + + _fade_in.add ((_length * 0.000000), 0.000000); + _fade_in.add ((_length * 0.166667), 0.166366); + _fade_in.add ((_length * 0.333333), 0.332853); + _fade_in.add ((_length * 0.500000), 0.499459); + _fade_in.add ((_length * 0.666667), 0.666186); + _fade_in.add ((_length * 0.833333), 0.833033); + _fade_in.add ((_length * 1.000000), 1.000000); + +#endif + _fade_in.thaw (); overlap_type = _in->coverage (_out->position(), _out->last_frame()); diff --git a/libs/ardour/export_channel_configuration.cc b/libs/ardour/export_channel_configuration.cc index a2a289737c..c8db1a6b0d 100644 --- a/libs/ardour/export_channel_configuration.cc +++ b/libs/ardour/export_channel_configuration.cc @@ -174,8 +174,7 @@ ExportChannelConfiguration::write_file () void * ExportChannelConfiguration::_write_files (void *arg) { - - PBD::ThreadCreated (pthread_self(), "Export post-processing"); + notify_gui_about_thread_creation (pthread_self(), "Export post-processing"); // cc can be trated like 'this' WriterThread & cc (*((WriterThread *) arg)); diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 04b4543b71..8be2e3b8b6 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -128,6 +128,7 @@ setup_osc () return 0; } } + #endif int @@ -204,16 +205,17 @@ ARDOUR::setup_midi () << endmsg; return 0; } + if (default_mtc_port == 0) { warning << string_compose (_("No MTC support (MIDI port \"%1\" not available)"), Config->get_mtc_port_name()) << endmsg; - } + } if (default_midi_port == 0) { warning << string_compose (_("No MIDI parameter support (MIDI port \"%1\" not available)"), Config->get_midi_port_name()) << endmsg; - } + } if (default_midi_clock_port == 0) { warning << string_compose (_("No MIDI Clock support (MIDI port \"%1\" not available)"), Config->get_midi_clock_port_name()) diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index 3f6e60af33..6b3871c814 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -56,8 +56,10 @@ #include <ardour/tempo.h> #ifdef HAVE_COREAUDIO +#ifdef USE_COREAUDIO_FOR_FILE_IO #include <ardour/caimportable.h> #endif +#endif #include "i18n.h" @@ -69,11 +71,13 @@ static boost::shared_ptr<ImportableSource> open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQuality quality) { #ifdef HAVE_COREAUDIO +#ifdef USE_COREAUDIO_FOR_FILE_IO /* see if we can use CoreAudio to handle the IO */ try { - boost::shared_ptr<CAImportableSource> source(new CAImportableSource(path)); + CAImportableSource* src = new CAImportableSource(path); + boost::shared_ptr<CAImportableSource> source (src); if (source->samplerate() == samplerate) { return source; @@ -87,8 +91,8 @@ open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQua catch (...) { /* fall back to SndFile */ - #endif +#endif try { boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path)); @@ -96,7 +100,7 @@ open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQua if (source->samplerate() == samplerate) { return source; } - + /* rewrap as a resampled source */ return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality)); @@ -107,8 +111,10 @@ open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQua } #ifdef HAVE_COREAUDIO +#ifdef USE_COREAUDIO_FOR_FILE_IO } #endif +#endif } static std::string @@ -437,7 +443,7 @@ Session::import_audiofiles (import_status& status) if (source) { // audio status.doing_what = compose_status_message (*p, source->samplerate(), - frame_rate(), cnt, status.paths.size()); + frame_rate(), cnt, status.total); write_audio_data_to_new_files (source.get(), status, newfiles); } else if (smf_reader.get()) { // midi status.doing_what = string_compose(_("loading MIDI file %1"), *p); @@ -479,8 +485,7 @@ Session::import_audiofiles (import_status& status) save_state (_name); - std::copy (all_new_sources.begin(), all_new_sources.end(), - std::back_inserter(status.sources)); + std::copy (all_new_sources.begin(), all_new_sources.end(), std::back_inserter(status.sources)); } else { // this can throw...but it seems very unlikely std::for_each (all_new_sources.begin(), all_new_sources.end(), remove_file_source); diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index e245712fee..66023f1f4d 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -2331,8 +2331,9 @@ void IO::set_gain (gain_t val, void *src) { // max gain at about +6dB (10.0 ^ ( 6 dB * 0.05)) - if (val > 1.99526231f) + if (val > 1.99526231f) { val = 1.99526231f; + } if (src != _gain_control.get()) { _gain_control->set_value(val); @@ -2347,7 +2348,7 @@ IO::set_gain (gain_t val, void *src) } if (_session.transport_stopped()) { - _gain = val; + // _gain = val; } /* @@ -2541,7 +2542,6 @@ IO::set_active (bool yn) active_changed(); /* EMIT SIGNAL */ } - AudioPort* IO::audio_input(uint32_t n) const { diff --git a/libs/ardour/mtc_slave.cc b/libs/ardour/mtc_slave.cc index 0a0fbc1529..1a8cd589da 100644 --- a/libs/ardour/mtc_slave.cc +++ b/libs/ardour/mtc_slave.cc @@ -16,7 +16,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#include <iostream> #include <errno.h> #include <poll.h> #include <sys/types.h> @@ -43,6 +43,8 @@ MTC_Slave::MTC_Slave (Session& s, MIDI::Port& p) { can_notify_on_unknown_rate = true; + last_mtc_fps_byte = session.get_mtc_smpte_bits (); + rebind (p); reset (); } @@ -96,6 +98,8 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full) smpte.seconds = msg[1]; smpte.frames = msg[0]; + last_mtc_fps_byte = msg[4]; + switch (msg[4]) { case MTC_24_FPS: smpte.rate = 24; @@ -120,7 +124,9 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full) default: /* throttle error messages about unknown MTC rates */ if (can_notify_on_unknown_rate) { - error << _("Unknown rate/drop value in incoming MTC stream, session values used instead") << endmsg; + error << string_compose (_("Unknown rate/drop value %1 in incoming MTC stream, session values used instead"), + (int) msg[4]) + << endmsg; can_notify_on_unknown_rate = false; } smpte.rate = session.smpte_frames_per_second(); @@ -170,8 +176,9 @@ MTC_Slave::update_mtc_time (const byte *msg, bool was_full) void MTC_Slave::handle_locate (const MIDI::byte* mmc_tc) { - MIDI::byte mtc[4]; + MIDI::byte mtc[5]; + mtc[4] = last_mtc_fps_byte; mtc[3] = mmc_tc[0] & 0xf; /* hrs only */ mtc[2] = mmc_tc[1]; mtc[1] = mmc_tc[2]; diff --git a/libs/ardour/osc.cc b/libs/ardour/osc.cc index 0c58040ad6..ffd2df63be 100644 --- a/libs/ardour/osc.cc +++ b/libs/ardour/osc.cc @@ -32,11 +32,13 @@ #include <pbd/pthread_utils.h> #include <pbd/file_utils.h> +#include <pbd/filesystem.h> #include <ardour/osc.h> #include <ardour/session.h> #include <ardour/route.h> #include <ardour/audio_track.h> +#include <ardour/dB.h> #include <ardour/filesystem_paths.h> #include "i18n.h" @@ -107,10 +109,10 @@ OSC::start () cerr << "OSC @ " << get_server_url () << endl; - sys::path url_file; + PBD::sys::path url_file; if (find_file_in_search_path (ardour_search_path() + system_config_search_path(), - "osc_url", url_file)) { + "osc_url", url_file)) { _osc_url_file = url_file.to_string(); ofstream urlfile; urlfile.open(_osc_url_file.c_str(), ios::trunc); @@ -154,9 +156,9 @@ OSC::stop () unlink(_osc_unix_socket_path.c_str()); } - if (! _osc_url_file.empty() ) { - unlink(_osc_url_file.c_str() ); - } + if (! _osc_url_file.empty() ) { + unlink(_osc_url_file.c_str() ); + } return 0; } @@ -204,6 +206,12 @@ OSC::register_callbacks() REGISTER_CALLBACK (serv, "/ardour/rec_enable_toggle", "", rec_enable_toggle); REGISTER_CALLBACK (serv, "/ardour/toggle_all_rec_enables", "", toggle_all_rec_enables); + REGISTER_CALLBACK (serv, "/ardour/routes/mute", "ii", route_mute); + REGISTER_CALLBACK (serv, "/ardour/routes/solo", "ii", route_solo); + REGISTER_CALLBACK (serv, "/ardour/routes/recenable", "ii", route_recenable); + REGISTER_CALLBACK (serv, "/ardour/routes/gainabs", "if", route_set_gain_abs); + REGISTER_CALLBACK (serv, "/ardour/routes/gaindB", "if", route_set_gain_dB); + #if 0 REGISTER_CALLBACK (serv, "/ardour/*/#current_value", "", current_value); REGISTER_CALLBACK (serv, "/ardour/set", "", set); @@ -310,7 +318,7 @@ OSC::get_unix_server_url() void * OSC::_osc_receiver(void * arg) { - PBD::ThreadCreated (pthread_self(), X_("OSC")); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("OSC")); static_cast<OSC*> (arg)->osc_receiver(); return 0; @@ -378,7 +386,7 @@ OSC::osc_receiver() if (pfd[i].revents & POLLIN) { // this invokes callbacks - //cerr << "invoking recv on " << pfd[i].fd << endl; + // cerr << "invoking recv on " << pfd[i].fd << endl; lo_server_recv(srvs[i]); } } @@ -390,7 +398,7 @@ OSC::osc_receiver() if (_osc_server) { int fd = lo_server_get_socket_fd(_osc_server); if (fd >=0) { - // hack around + // hack around close(fd); } lo_server_free (_osc_server); @@ -500,3 +508,70 @@ OSC::current_value (const char *path, const char *types, lo_arg **argv, int argc #endif return 0; } + +int +OSC::route_mute (int rid, int yn) +{ + if (!session) return -1; + + boost::shared_ptr<Route> r = session->route_by_remote_id (rid); + + if (r) { + r->set_mute (yn, this); + } + return 0; +} + +int +OSC::route_solo (int rid, int yn) +{ + if (!session) return -1; + + boost::shared_ptr<Route> r = session->route_by_remote_id (rid); + + if (r) { + r->set_solo (yn, this); + } + return 0; +} + +int +OSC::route_recenable (int rid, int yn) +{ + if (!session) return -1; + + boost::shared_ptr<Route> r = session->route_by_remote_id (rid); + + if (r) { + r->set_record_enable (yn, this); + } + return 0; +} + +int +OSC::route_set_gain_abs (int rid, float level) +{ + if (!session) return -1; + + boost::shared_ptr<Route> r = session->route_by_remote_id (rid); + + if (r) { + r->set_gain (level, this); + } + + return 0; +} + +int +OSC::route_set_gain_dB (int rid, float dB) +{ + if (!session) return -1; + + boost::shared_ptr<Route> r = session->route_by_remote_id (rid); + + if (r) { + r->set_gain (dB_to_coefficient (dB), this); + } + + return 0; +} diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index fe0a792b6b..04c744b880 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -749,10 +749,14 @@ Panner::reset (uint32_t nouts, uint32_t npans) { uint32_t n; bool changed = false; + bool do_not_and_did_not_need_panning = ((nouts < 2) && (outputs.size() < 2)); - //configure_io( ChanCount( DataType::AUDIO, nout ), ChanCount( DataType::AUDIO, nin ) ) - - if (nouts < 2 || (nouts == outputs.size() && npans == _streampanners.size())) { + /* if new and old config don't need panning, or if + the config hasn't changed, we're done. + */ + + if (do_not_and_did_not_need_panning || + ((nouts == outputs.size()) && (npans == _streampanners.size()))) { return; } @@ -770,6 +774,10 @@ Panner::reset (uint32_t nouts, uint32_t npans) changed = true; } + if (nouts < 2) { + goto send_changed; + } + switch (nouts) { case 0: break; @@ -871,6 +879,7 @@ Panner::reset (uint32_t nouts, uint32_t npans) } } + send_changed: if (changed) { Changed (); /* EMIT SIGNAL */ } diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index 0b5a14bf56..8dd1a7abb0 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -130,6 +130,8 @@ PluginManager::PluginManager () _lv2_world = new LV2World(); #endif + BootMessage (_("Discovering Plugins")); + refresh (); } @@ -632,7 +634,7 @@ PluginManager::add_favorite (PluginType t, string id) { FavoritePlugin fp (t, id); pair<FavoritePluginList::iterator,bool> res = favorites.insert (fp); - cerr << "Added " << t << " " << id << " success ? " << res.second << endl; + //cerr << "Added " << t << " " << id << " success ? " << res.second << endl; } void diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc index d0a8a3abbf..a1dce0497f 100644 --- a/libs/ardour/rb_effect.cc +++ b/libs/ardour/rb_effect.cc @@ -206,7 +206,7 @@ RBEffect::run (boost::shared_ptr<Region> r) while (pos < read_duration && !tsr.cancel) { nframes_t this_read = 0; - + for (uint32_t i = 0; i < channels; ++i) { this_read = 0; @@ -229,7 +229,7 @@ RBEffect::run (boost::shared_ptr<Region> r) if (this_read != this_time) { error << string_compose (_("tempoize: error reading data from %1 at %2 (wanted %3, got %4)"), - region->name(), pos + region->position(), this_time, this_read) << endmsg; + region->name(), this_position, this_time, this_read) << endmsg; goto out; } } diff --git a/libs/ardour/region.cc b/libs/ardour/region.cc index 982eb3e023..6375527664 100644 --- a/libs/ardour/region.cc +++ b/libs/ardour/region.cc @@ -38,6 +38,7 @@ #include <ardour/tempo.h> #include <ardour/region_factory.h> #include <ardour/filter.h> +#include <ardour/profile.h> #include "i18n.h" @@ -153,50 +154,90 @@ Region::Region (const SourceList& srcs, nframes_t start, nframes_t length, const /** Create a new Region from part of an existing one */ Region::Region (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) : SessionObject(other->session(), name) - , _type(other->data_type()) - , _flags(Flag(flags & ~(Locked|PositionLocked|WholeFile|Hidden))) - , _start(other->_start + offset) - , _length(length) - , _position(0) - , _last_position(0) - , _positional_lock_style(other->_positional_lock_style) - , _sync_position(_start) - , _layer(layer) - , _first_edit(EditChangesNothing) - , _frozen(0) - , _ancestral_start (other->_ancestral_start + offset) - , _ancestral_length (length) - , _stretch (other->_stretch) - , _shift (other->_shift) - , _valid_transients(false) - , _read_data_count(0) - , _pending_changed(Change (0)) - , _last_layer_op(0) + , _type (other->data_type()) + { - if (other->_sync_position < offset) - _sync_position = other->_sync_position; + _start = other->_start + offset; + copy_stuff (other, offset, length, name, layer, flags); - set<boost::shared_ptr<Source> > unique_srcs; + /* if the other region had a distinct sync point + set, then continue to use it as best we can. + otherwise, reset sync point back to start. + */ - for (SourceList::const_iterator i= other->_sources.begin(); i != other->_sources.end(); ++i) { - _sources.push_back (*i); - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); - unique_srcs.insert (*i); - } - - if (other->_sync_position < offset) { - _sync_position = other->_sync_position; + if (other->flags() & SyncMarked) { + if (other->_sync_position < _start) { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } else { + _sync_position = other->_sync_position; + } + } else { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; } + if (Profile->get_sae()) { + /* reset sync point to start if its ended up + outside region bounds. + */ - for (SourceList::const_iterator i = other->_master_sources.begin(); i != other->_master_sources.end(); ++i) { - if (unique_srcs.find (*i) == unique_srcs.end()) { - (*i)->GoingAway.connect (bind (mem_fun (*this, &Region::source_deleted), (*i))); + if (_sync_position < _start || _sync_position >= _start + _length) { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; } - _master_sources.push_back (*i); } +} + +Region::Region (boost::shared_ptr<const Region> other, nframes_t length, const string& name, layer_t layer, Flag flags) + : SessionObject(other->session(), name) + , _type (other->data_type()) +{ + /* create a new Region exactly like another but starting at 0 in its sources */ + + _start = 0; + copy_stuff (other, 0, length, name, layer, flags); + + /* sync pos is relative to start of file. our start-in-file is now zero, + so set our sync position to whatever the the difference between + _start and _sync_pos was in the other region. + + result is that our new sync pos points to the same point in our source(s) + as the sync in the other region did in its source(s). + + since we start at zero in our source(s), it is not possible to use a sync point that + is before the start. reset it to _start if that was true in the other region. + */ - assert(_sources.size() > 0); + if (other->flags() & SyncMarked) { + if (other->_start < other->_sync_position) { + /* sync pos was after the start point of the other region */ + _sync_position = other->_sync_position - other->_start; + } else { + /* sync pos was before the start point of the other region. not possible here. */ + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } + } else { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } + + if (Profile->get_sae()) { + /* reset sync point to start if its ended up + outside region bounds. + */ + + if (_sync_position < _start || _sync_position >= _start + _length) { + _flags = Flag (_flags & ~SyncMarked); + _sync_position = _start; + } + } + + /* reset a couple of things that copy_stuff() gets wrong in this particular case */ + + _positional_lock_style = other->_positional_lock_style; + _first_edit = other->_first_edit; } /** Pure copy constructor */ @@ -337,6 +378,31 @@ Region::~Region () } void +Region::copy_stuff (boost::shared_ptr<const Region> other, nframes_t offset, nframes_t length, const string& name, layer_t layer, Flag flags) +{ + _frozen = 0; + _pending_changed = Change (0); + _read_data_count = 0; + _valid_transients = false; + + _length = length; + _last_length = length; + _sync_position = other->_sync_position; + _ancestral_start = other->_ancestral_start; + _ancestral_length = other->_ancestral_length; + _stretch = other->_stretch; + _shift = other->_shift; + _name = name; + _last_position = 0; + _position = 0; + _layer = layer; + _flags = Flag (flags & ~(Locked|WholeFile|Hidden)); + _first_edit = EditChangesNothing; + _last_layer_op = 0; + _positional_lock_style = AudioTime; +} + +void Region::set_playlist (boost::weak_ptr<Playlist> wpl) { boost::shared_ptr<Playlist> old_playlist = (_playlist.lock()); @@ -982,7 +1048,7 @@ Region::sync_offset (int& dir) const } nframes_t -Region::adjust_to_sync (nframes_t pos) +Region::adjust_to_sync (nframes_t pos) const { int sync_dir; nframes_t offset = sync_offset (sync_dir); @@ -1245,16 +1311,26 @@ Region::set_live_state (const XMLNode& node, Change& what_changed, bool send) if ((prop = node.property ("stretch")) != 0) { _stretch = atof (prop->value()); - if( _stretch == 0.0 ) + + /* fix problem with old sessions corrupted by an impossible + value for _stretch + */ + if (_stretch == 0.0) { _stretch = 1.0; + } } else { _stretch = 1.0; } if ((prop = node.property ("shift")) != 0) { _shift = atof (prop->value()); - if( _shift == 0.0 ) + + /* fix problem with old sessions corrupted by an impossible + value for _shift + */ + if (_shift == 0.0) { _shift = 1.0; + } } else { _shift = 1.0; } diff --git a/libs/ardour/region_factory.cc b/libs/ardour/region_factory.cc index 88925a7f16..742a65962e 100644 --- a/libs/ardour/region_factory.cc +++ b/libs/ardour/region_factory.cc @@ -37,7 +37,7 @@ sigc::signal<void,boost::shared_ptr<Region> > RegionFactory::CheckNewRegion; boost::shared_ptr<Region> RegionFactory::create (boost::shared_ptr<Region> region, nframes_t start, - nframes_t length, std::string name, + nframes_t length, const std::string& name, layer_t layer, Region::Flag flags, bool announce) { boost::shared_ptr<const AudioRegion> other_a; @@ -91,13 +91,40 @@ RegionFactory::create (boost::shared_ptr<const Region> region) boost::shared_ptr<Region> RegionFactory::create (boost::shared_ptr<AudioRegion> region, nframes_t start, - nframes_t length, std::string name, + nframes_t length, const std::string& name, layer_t layer, Region::Flag flags, bool announce) { return create (boost::static_pointer_cast<Region> (region), start, length, name, layer, flags, announce); } boost::shared_ptr<Region> +RegionFactory::create (boost::shared_ptr<Region> region, const SourceList& srcs, + const std::string& name, layer_t layer, Region::Flag flags, bool announce) + +{ + boost::shared_ptr<const AudioRegion> other; + + /* used by AudioFilter when constructing a new region that is intended to have nearly + identical settings to an original, but using different sources. + */ + + if ((other = boost::dynamic_pointer_cast<AudioRegion>(region)) != 0) { + AudioRegion* ar = new AudioRegion (other, srcs, srcs.front()->length(), name, layer, flags); + boost::shared_ptr<AudioRegion> arp (ar); + boost::shared_ptr<Region> ret (boost::static_pointer_cast<Region> (arp)); + if (announce) { + CheckNewRegion (ret); + } + return ret; + } else { + fatal << _("programming error: RegionFactory::create() called with unknown Region type") + << endmsg; + /*NOTREACHED*/ + return boost::shared_ptr<Region>(); + } +} + +boost::shared_ptr<Region> RegionFactory::create (Session& session, XMLNode& node, bool yn) { boost::shared_ptr<Region> r = session.XMLRegionFactory (node, yn); diff --git a/libs/ardour/reverse.cc b/libs/ardour/reverse.cc index 02ec2924b0..9c15b1e4d9 100644 --- a/libs/ardour/reverse.cc +++ b/libs/ardour/reverse.cc @@ -70,6 +70,7 @@ Reverse::run (boost::shared_ptr<Region> r) } fpos = max (fstart, (fstart + region->length() - blocksize)); + buf = new Sample[blocksize]; to_read = blocksize; @@ -81,7 +82,7 @@ Reverse::run (boost::shared_ptr<Region> r) for (n = 0, si = nsrcs.begin(); n < region->n_channels(); ++n, ++si) { - /* read it in */ + /* read it in directly from the source */ if (region->audio_source (n)->read (buf, fpos, to_read) != to_read) { goto out; @@ -92,7 +93,7 @@ Reverse::run (boost::shared_ptr<Region> r) for (nframes_t i = 0; i < to_read/2; ++i) { swap (buf[i],buf[to_read-1-i]); } - + /* write it out */ boost::shared_ptr<AudioSource> asrc(boost::dynamic_pointer_cast<AudioSource>(*si)); diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 5d1a26d3d0..96f26a515c 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -25,6 +25,7 @@ #include <pbd/xml++.h> #include <pbd/enumwriter.h> #include <pbd/stacktrace.h> +#include <pbd/memento_command.h> #include <ardour/timestamps.h> #include <ardour/audioengine.h> @@ -1087,6 +1088,31 @@ Route::set_solo (bool yn, void *src) _soloed = yn; solo_changed (src); /* EMIT SIGNAL */ _solo_control->Changed (); /* EMIT SIGNAL */ + } + + catch_up_on_solo_mute_override (); +} + +void +Route::catch_up_on_solo_mute_override () +{ + if (Config->get_solo_model() != InverseMute) { + return; + } + + { + + Glib::Mutex::Lock lm (declick_lock); + + if (_muted) { + if (Config->get_solo_mute_override()) { + desired_mute_gain = (_soloed?1.0:0.0); + } else { + desired_mute_gain = 0.0; + } + } else { + desired_mute_gain = 1.0; + } } } @@ -1126,7 +1152,12 @@ Route::set_mute (bool yn, void *src) _mute_control->Changed (); /* EMIT SIGNAL */ Glib::Mutex::Lock lm (declick_lock); - desired_mute_gain = (yn?0.0f:1.0f); + + if (_soloed && Config->get_solo_mute_override()){ + desired_mute_gain = 1.0f; + } else { + desired_mute_gain = (yn?0.0f:1.0f); + } } } @@ -1234,7 +1265,6 @@ Route::add_processors (const ProcessorList& others, ProcessorStreams* err) return -1; } - (*i)->activate (); (*i)->ActiveChanged.connect (bind (mem_fun (_session, &Session::update_latency_compensation), false, false)); } @@ -3089,3 +3119,50 @@ Route::set_pending_declick (int declick) } +/** Shift automation forwards from a particular place, thereby inserting time. + * Adds undo commands for any shifts that are performed. + * + * @param pos Position to start shifting from. + * @param frames Amount to shift forwards by. + */ + +void +Route::shift (nframes64_t pos, nframes64_t frames) +{ +#ifdef THIS_NEEDS_FIXING_FOR_V3 + + /* gain automation */ + XMLNode &before = _gain_control->get_state (); + _gain_control->shift (pos, frames); + XMLNode &after = _gain_control->get_state (); + _session.add_command (new MementoCommand<AutomationList> (_gain_automation_curve, &before, &after)); + + /* pan automation */ + for (std::vector<StreamPanner*>::iterator i = _panner->begin (); i != _panner->end (); ++i) { + Curve & c = (*i)->automation (); + XMLNode &before = c.get_state (); + c.shift (pos, frames); + XMLNode &after = c.get_state (); + _session.add_command (new MementoCommand<AutomationList> (c, &before, &after)); + } + + /* redirect automation */ + { + Glib::RWLock::ReaderLock lm (redirect_lock); + for (RedirectList::iterator i = _redirects.begin (); i != _redirects.end (); ++i) { + + set<uint32_t> a; + (*i)->what_has_automation (a); + + for (set<uint32_t>::const_iterator j = a.begin (); j != a.end (); ++j) { + AutomationList & al = (*i)->automation_list (*j); + XMLNode &before = al.get_state (); + al.shift (pos, frames); + XMLNode &after = al.get_state (); + _session.add_command (new MementoCommand<AutomationList> (al, &before, &after)); + } + } + } +#endif + +} diff --git a/libs/ardour/send.cc b/libs/ardour/send.cc index 034bed77c3..58352a5dfe 100644 --- a/libs/ardour/send.cc +++ b/libs/ardour/send.cc @@ -27,6 +27,8 @@ #include <ardour/audio_port.h> #include <ardour/buffer_set.h> #include <ardour/meter.h> +#include <ardour/panner.h> + #include "i18n.h" using namespace ARDOUR; @@ -55,6 +57,41 @@ Send::Send (const Send& other) : IOProcessor (other._session, string_compose (_("send %1"), (bitslot = other._session.next_send_id()) + 1), other.placement()) { _metering = false; + + expected_inputs.set (DataType::AUDIO, 0); + +#ifdef THIS_NEEDS_FIXING_FOR_V3 + + /* set up the same outputs, and connect them to the same places */ + + _io->no_panner_reset = true; + + for (uint32_t i = 0; i < other.n_outputs (); ++i) { + add_output_port ("", 0); + Port* p = other.output (i); + if (p) { + /* this is what the other send's output is connected to */ + const char **connections = p->get_connections (); + if (connections) { + for (uint32_t c = 0; connections[c]; ++c) { + connect_output (output (i), connections [c], 0); + } + } + } + } + + /* setup panner */ + + _io->no_panner_reset = false; + + /* copy state */ + + XMLNode& other_state (const_cast<Send*>(&other)->_panner->get_state()); + _panner->set_state (other_state); + + delete &other_state; +#endif + ProcessorCreated (this); /* EMIT SIGNAL */ } diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 14ef0e1ac5..875b317936 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -123,23 +123,31 @@ Session::Session (AudioEngine &eng, _scratch_buffers(new BufferSet()), _silent_buffers(new BufferSet()), _mix_buffers(new BufferSet()), + mmc (0), _mmc_port (default_mmc_port), _mtc_port (default_mtc_port), _midi_port (default_midi_port), _midi_clock_port (default_midi_clock_port), _session_dir (new SessionDirectory(fullpath)), pending_events (2048), + state_tree (0), + butler_mixdown_buffer (0), + butler_gain_buffer (0), post_transport_work((PostTransportWork)0), _send_smpte_update (false), - midi_requests (128), + midi_thread (pthread_t (0)), + midi_requests (128), // the size of this should match the midi request pool size diskstreams (new DiskstreamList), routes (new RouteList), auditioner ((Auditioner*) 0), _total_free_4k_blocks (0), _bundle_xml_node (0), _click_io ((IO*) 0), + click_data (0), + click_emphasis_data (0), main_outs (0), _metadata (new SessionMetadata()) + { bool new_session; @@ -196,21 +204,30 @@ Session::Session (AudioEngine &eng, _scratch_buffers(new BufferSet()), _silent_buffers(new BufferSet()), _mix_buffers(new BufferSet()), + mmc (0), _mmc_port (default_mmc_port), _mtc_port (default_mtc_port), _midi_port (default_midi_port), _midi_clock_port (default_midi_clock_port), _session_dir ( new SessionDirectory(fullpath)), pending_events (2048), + state_tree (0), + butler_mixdown_buffer (0), + butler_gain_buffer (0), post_transport_work((PostTransportWork)0), _send_smpte_update (false), + midi_thread (pthread_t (0)), midi_requests (16), diskstreams (new DiskstreamList), routes (new RouteList), + auditioner ((Auditioner *) 0), _total_free_4k_blocks (0), _bundle_xml_node (0), - main_outs (0) - + _click_io ((IO *) 0), + click_data (0), + click_emphasis_data (0), + main_outs (0), + _metadata (new SessionMetadata()) { bool new_session; @@ -316,18 +333,16 @@ Session::destroy () /* clear state tree so that no references to objects are held any more */ - if (state_tree) { - delete state_tree; - } + delete state_tree; terminate_butler_thread (); //terminate_midi_thread (); - if (click_data && click_data != default_click) { + if (click_data != default_click) { delete [] click_data; } - if (click_emphasis_data && click_emphasis_data != default_click_emphasis) { + if (click_emphasis_data != default_click_emphasis) { delete [] click_emphasis_data; } @@ -471,19 +486,12 @@ Session::destroy () i = tmp; } - if (butler_mixdown_buffer) { - delete [] butler_mixdown_buffer; - } - - if (butler_gain_buffer) { - delete [] butler_gain_buffer; - } + delete [] butler_mixdown_buffer; + delete [] butler_gain_buffer; Crossfade::set_buffer_size (0); - if (mmc) { - delete mmc; - } + delete mmc; } void @@ -1213,6 +1221,10 @@ Session::audible_frame () const nframes_t offset; nframes_t tf; + if (_transport_speed == 0.0f && non_realtime_work_pending()) { + return last_stop_frame; + } + /* the first of these two possible settings for "offset" mean that the audible frame is stationary until audio emerges from the latency compensation @@ -1241,24 +1253,43 @@ Session::audible_frame () const } else { tf = _transport_frame; } - - if (_transport_speed == 0) { - return tf; - } - - if (tf < offset) { - return 0; - } - + ret = tf; if (!non_realtime_work_pending()) { /* MOVING */ - /* take latency into account */ + /* check to see if we have passed the first guaranteed + audible frame past our last stopping position. if not, + the return that last stopping point because in terms + of audible frames, we have not moved yet. + */ + + if (_transport_speed > 0.0f) { + + if (!play_loop || !have_looped) { + if (tf < last_stop_frame + offset) { + return last_stop_frame; + + } + } + + + /* forwards */ + ret -= offset; + + } else if (_transport_speed < 0.0f) { - ret -= offset; + /* XXX wot? no backward looping? */ + + if (tf > last_stop_frame - offset) { + return last_stop_frame; + } else { + /* backwards */ + ret += offset; + } + } } return ret; @@ -1875,6 +1906,10 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_ _engine.get_physical_outputs (DataType::AUDIO, physoutputs); _engine.get_physical_inputs (DataType::AUDIO, physinputs); + + n_physical_audio_outputs = physoutputs.size(); + n_physical_audio_inputs = physinputs.size(); + control_id = ntracks() + nbusses() + 1; while (how_many) { @@ -1900,21 +1935,24 @@ Session::new_audio_route (int input_channels, int output_channels, uint32_t how_ goto failure; } - for (uint32_t x = 0; n_physical_inputs && x < bus->n_inputs().n_audio(); ++x) { - port = ""; + /* + for (uint32_t x = 0; n_physical_audio_inputs && x < bus->n_inputs(); ++x) { + + port = ""; + if (Config->get_input_auto_connect() & AutoConnectPhysical) { - port = physinputs[((n+x)%n_physical_inputs)]; - } - + port = physinputs[((n+x)%n_physical_audio_inputs)]; + } + if (port.length() && bus->connect_input (bus->input (x), port, this)) { break; } } + */ - for (uint32_t x = 0; x < bus->n_outputs().n_audio(); ++x) { - + for (uint32_t x = 0; n_physical_audio_outputs && x < bus->n_outputs().n_audio(); ++x) { port = ""; if (Config->get_output_auto_connect() & AutoConnectPhysical) { @@ -2240,8 +2278,6 @@ Session::update_route_solo_state () bool is_track = false; bool signal = false; - /* caller must hold RouteLock */ - /* this is where we actually implement solo by changing the solo mute setting of each track. */ @@ -2341,7 +2377,24 @@ Session::catch_up_on_solo () has. */ update_route_solo_state(); -} +} + +void +Session::catch_up_on_solo_mute_override () +{ + if (Config->get_solo_model() != InverseMute) { + return; + } + + /* this is called whenever the param solo-mute-override is + changed. + */ + shared_ptr<RouteList> r = routes.reader (); + + for (RouteList::iterator i = r->begin(); i != r->end(); ++i) { + (*i)->catch_up_on_solo_mute_override (); + } +} shared_ptr<Route> Session::route_by_name (string name) @@ -4220,8 +4273,13 @@ Session::get_silent_buffers (ChanCount count) BufferSet& Session::get_scratch_buffers (ChanCount count) { - assert(_scratch_buffers->available() >= count); - _scratch_buffers->set_count(count); + if (count != ChanCount::ZERO) { + assert(_scratch_buffers->available() >= count); + _scratch_buffers->set_count(count); + } else { + _scratch_buffers->set_count (_scratch_buffers->available()); + } + return *_scratch_buffers; } diff --git a/libs/ardour/session_butler.cc b/libs/ardour/session_butler.cc index 02f8569a3d..5fe7a92d3d 100644 --- a/libs/ardour/session_butler.cc +++ b/libs/ardour/session_butler.cc @@ -162,7 +162,7 @@ Session::wait_till_butler_finished () void * Session::_butler_thread_work (void* arg) { - PBD::ThreadCreated (pthread_self(), X_("Butler")); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("Butler")); return ((Session *) arg)->butler_thread_work (); return 0; } diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 2e19041b9c..90ad257d3b 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -60,6 +60,7 @@ Session::get_export_status () return export_status; } + int Session::pre_export () { diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc index 64903f24a2..b85df5b714 100644 --- a/libs/ardour/session_midi.cc +++ b/libs/ardour/session_midi.cc @@ -1120,7 +1120,7 @@ Session::midi_thread_work () bool restart; vector<MIDI::Port*> ports; - PBD::ThreadCreatedWithRequestSize (pthread_self(), X_("MIDI"), 2048); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("MIDI"), 2048); memset (&rtparam, 0, sizeof (rtparam)); rtparam.sched_priority = 9; /* XXX should be relative to audio (JACK) thread */ @@ -1145,6 +1145,7 @@ Session::midi_thread_work () pfd[nfds].fd = _mmc_port->selectable(); pfd[nfds].events = POLLIN|POLLHUP|POLLERR; ports[nfds] = _mmc_port; + //cerr << "MIDI port " << nfds << " = MMC @ " << _mmc_port << endl; nfds++; } @@ -1157,6 +1158,7 @@ Session::midi_thread_work () pfd[nfds].fd = _mtc_port->selectable(); pfd[nfds].events = POLLIN|POLLHUP|POLLERR; ports[nfds] = _mtc_port; + //cerr << "MIDI port " << nfds << " = MTC @ " << _mtc_port << endl; nfds++; } @@ -1175,6 +1177,7 @@ Session::midi_thread_work () pfd[nfds].fd = _midi_port->selectable(); pfd[nfds].events = POLLIN|POLLHUP|POLLERR; ports[nfds] = _midi_port; + // cerr << "MIDI port " << nfds << " = MIDI @ " << _midi_port << endl; nfds++; } diff --git a/libs/ardour/session_process.cc b/libs/ardour/session_process.cc index 3b81092a96..c2e78df643 100644 --- a/libs/ardour/session_process.cc +++ b/libs/ardour/session_process.cc @@ -677,12 +677,13 @@ Session::follow_slave (nframes_t nframes, nframes_t offset) #if 0 cerr << "adjust using " << delta - << " towards " << adjusted_speed - << " ratio = " << adjusted_speed / slave_speed - << " current = " << _transport_speed - << " slave @ " << slave_speed - << endl; -#endif + << " towards " << adjusted_speed + << " ratio = " << adjusted_speed / slave_speed + << " current = " << _transport_speed + << " slave @ " << slave_speed + << endl; +#endif + request_transport_speed (adjusted_speed); #if 1 diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index b1a494584a..cb4a9e5813 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -165,6 +165,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) g_atomic_int_set (&_record_status, Disabled); loop_changing = false; play_loop = false; + have_looped = false; _last_roll_location = 0; _last_record_location = 0; pending_locate_frame = 0; @@ -172,7 +173,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) pending_locate_flush = false; audio_dstream_buffer_size = 0; midi_dstream_buffer_size = 0; - state_tree = 0; state_was_pending = false; set_next_event (); outbound_mtc_smpte_frame = 0; @@ -187,9 +187,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) _state_of_the_state = StateOfTheState(CannotSave|InitialConnecting|Loading); _slave = 0; - butler_mixdown_buffer = 0; - butler_gain_buffer = 0; - mmc = 0; session_send_mmc = false; session_send_mtc = false; post_transport_work = PostTransportWork (0); @@ -227,8 +224,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) waveforms for clicks. */ - click_data = 0; - click_emphasis_data = 0; click_length = 0; click_emphasis_length = 0; _clicking = false; @@ -362,6 +357,8 @@ Session::second_stage_init (bool new_session) MidiClockTicker::instance().set_session(*this); MIDI::Name::MidiPatchManager::instance().set_session(*this); + /* initial program change will be delivered later; see ::config_changed() */ + BootMessage (_("Reset Control Protocols")); ControlProtocolManager::instance().set_session (*this); @@ -3272,6 +3269,17 @@ Session::config_changed (const char* parameter_name) _mmc_port->midimsg (buf, sizeof (buf), 0); } + } else if (PARAM_IS ("initial-program-change")) { + + if (_mmc_port && Config->get_initial_program_change() >= 0) { + MIDI::byte* buf = new MIDI::byte[2]; + + buf[0] = MIDI::program; // channel zero by default + buf[1] = (Config->get_initial_program_change() & 0x7f); + // deliver_midi (_mmc_port, buf, 2); + } + } else if (PARAM_IS ("solo-mute-override")) { + catch_up_on_solo_mute_override (); } set_dirty (); diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc index 7f574d4811..5612429d0d 100644 --- a/libs/ardour/session_transport.cc +++ b/libs/ardour/session_transport.cc @@ -212,8 +212,7 @@ Session::butler_transport_work () } if (post_transport_work & PostTransportReverse) { - - + clear_clicks(); cumulative_rf_motion = 0; reset_rf_scale (0); @@ -449,6 +448,12 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished) _requested_return_frame = -1; } + have_looped = false; + + send_full_time_code (0); + deliver_mmc (MIDI::MachineControl::cmdStop, 0); + deliver_mmc (MIDI::MachineControl::cmdLocate, _transport_frame); + if (did_record) { /* XXX its a little odd that we're doing this here @@ -779,7 +784,7 @@ Session::locate (nframes_t target_frame, bool with_roll, bool with_flush, bool w } } } - + have_looped = true; TransportLooped(); // EMIT SIGNAL } } @@ -886,6 +891,7 @@ Session::set_transport_speed (float speed, bool abort) if ((_transport_speed && speed * _transport_speed < 0.0f) || (_last_transport_speed * speed < 0.0f) || (_last_transport_speed == 0.0f && speed < 0.0f)) { post_transport_work = PostTransportWork (post_transport_work | PostTransportReverse); + last_stop_frame = _transport_frame; } _last_transport_speed = _transport_speed; @@ -951,6 +957,7 @@ void Session::start_transport () { _last_roll_location = _transport_frame; + have_looped = false; /* if record status is Enabled, move it to Recording. if its already Recording, move it to Disabled. diff --git a/libs/ardour/sndfileimportable.cc b/libs/ardour/sndfileimportable.cc index eb0e8a8afb..5cd00a8e96 100644 --- a/libs/ardour/sndfileimportable.cc +++ b/libs/ardour/sndfileimportable.cc @@ -1,5 +1,6 @@ #include <ardour/sndfileimportable.h> #include <sndfile.h> +#include <iostream> using namespace ARDOUR; using namespace std; diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index 097f0c235d..6a4b5e325d 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -317,7 +317,12 @@ SndFileSource::read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const if (_info.channels == 1) { nframes_t ret = sf_read_float (sf, dst, file_cnt); - _read_data_count = cnt * sizeof(float); + _read_data_count = ret * sizeof(float); + if (ret != file_cnt) { + char errbuf[256]; + sf_error_str (0, errbuf, sizeof (errbuf) - 1); + cerr << string_compose(_("SndFileSource: @ %1 could not read %2 within %3 (%4) (len = %5)"), start, file_cnt, _name.substr (1), errbuf, _length) << endl; + } return ret; } } @@ -381,7 +386,7 @@ SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) } _write_data_count = cnt; - + return cnt; } diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index 0b7c0f3d9e..4ada6b766c 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -52,7 +52,7 @@ std::list<boost::weak_ptr<AudioSource> > SourceFactory::files_with_peaks; static void peak_thread_work () { - PBD::ThreadCreated (pthread_self(), string ("peakbuilder-") + to_string (pthread_self(), std::dec)); + PBD::notify_gui_about_thread_creation (pthread_self(), string ("peakbuilder-") + to_string (pthread_self(), std::dec)); while (true) { diff --git a/libs/ardour/utils.cc b/libs/ardour/utils.cc index c598a3d279..18194678ed 100644 --- a/libs/ardour/utils.cc +++ b/libs/ardour/utils.cc @@ -282,7 +282,7 @@ compute_equal_power_fades (nframes_t nframes, float* in, float* out) { double step; - step = 1.0/nframes; + step = 1.0/(nframes-1); in[0] = 0.0f; diff --git a/libs/clearlooks/SConscript b/libs/clearlooks-newer/SConscript index df730460aa..ca527c70da 100644 --- a/libs/clearlooks/SConscript +++ b/libs/clearlooks-newer/SConscript @@ -6,7 +6,7 @@ import glob libclearlooks_files = [ 'animation.c', 'cairo-support.c', - 'clearlooks_draw.c', + 'clearlooks_draw.c', 'clearlooks_draw_glossy.c', 'clearlooks_draw_gummy.c', 'clearlooks_draw_inverted.c', @@ -28,16 +28,23 @@ if env['GTKOSX']: clearlooks.Append (CCFLAGS = '-DGTKOSX') libclearlooks = clearlooks.SharedLibrary('clearlooks', libclearlooks_files) - usable_libclearlooks = clearlooks.Install ('engines', libclearlooks) -Default (usable_libclearlooks) -env.Alias('install', - env.Install(os.path.join(install_prefix,env['LIBDIR'], 'ardour3', 'engines'), - libclearlooks)) +if env['GTKOSX']: + # GTK looks only for foo.so, not foo.dylib + print ("GTKOSX part"); + really_usable_module = clearlooks.Command ('engines/libclearlooks.so', usable_libclearlooks, 'ln -s libclearlooks.dylib libclearlooks.so', chdir=1) + Default (really_usable_module) +else: + print ("non-GTKOSX part"); + Default (usable_libclearlooks) + +env.Alias('install', env.Install ( + os.path.join(install_prefix,env['LIBDIR'], 'ardour2', 'engines'), + libclearlooks)) env.Alias('tarball', env.Distribute (env['DISTTREE'], - [ 'SConscript' ] + + [ 'SConscript', 'bits.c'] + libclearlooks_files + glob.glob('*.h') )) diff --git a/libs/clearlooks/animation.c b/libs/clearlooks-newer/animation.c index 82af498949..82af498949 100644 --- a/libs/clearlooks/animation.c +++ b/libs/clearlooks-newer/animation.c diff --git a/libs/clearlooks/animation.h b/libs/clearlooks-newer/animation.h index b2059c29c2..da70b6ce66 100644 --- a/libs/clearlooks/animation.h +++ b/libs/clearlooks-newer/animation.h @@ -16,7 +16,7 @@ * Boston, MA 02111-1307, USA. */ -#include <config.h> +#include "config.h" #ifdef HAVE_ANIMATION #include <gtk/gtk.h> diff --git a/libs/clearlooks-newer/bits.c b/libs/clearlooks-newer/bits.c new file mode 100644 index 0000000000..1e871bc5d3 --- /dev/null +++ b/libs/clearlooks-newer/bits.c @@ -0,0 +1,121 @@ +static unsigned char dot_intensity[] = { +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x98,0xb9,0xc6,0xb9,0x91,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0xbd,0xac,0x9e,0x65,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xc6,0xac,0x9e,0x96,0x5c,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0x9e,0x96,0x62,0x55,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x91,0x65,0x5c,0x55,0x68,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +}; +static unsigned char dot_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static unsigned char circle_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x23,0x62,0x92,0xb3,0xb2,0x95,0x2b,0x00,0x00,0x00, +0x00,0x00,0x3e,0xab,0xc9,0xeb,0xf9,0xf5,0xfd,0xff,0x57,0x00,0x00, +0x00,0x1f,0xb5,0xd8,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x67,0xb9,0xf2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x9a,0xe2,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0xba,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xc0,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0x9b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x2b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x00,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x00,0x00, +0x00,0x00,0x00,0x2b,0x9c,0xe5,0xff,0xe5,0x9c,0x2b,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char outline_alpha[] = { +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +}; +static unsigned char inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_base_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, 137, 151,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, 183, 172, 7,0x00,0x00, +0x00,0x00, 12, 18,0x00,0x00, 3, 161, 233, 27,0x00,0x00,0x00, +0x00,0x00, 199, 239, 101,0x00, 85, 253, 108,0x00,0x00,0x00,0x00, +0x00,0x00, 83, 245, 250, 75, 206, 230, 8,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 104, 252, 243, 253, 124,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 2, 162, 255, 241, 28,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, 18, 228, 163,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00, 78, 62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/libs/clearlooks/cairo-support.c b/libs/clearlooks-newer/cairo-support.c index 450c41bcfc..dbe6fd3d34 100644 --- a/libs/clearlooks/cairo-support.c +++ b/libs/clearlooks-newer/cairo-support.c @@ -81,31 +81,31 @@ ge_color_from_hsb (gdouble hue, gdouble m1, m2, m3; if (!color) return; - + if (brightness <= 0.5) m2 = brightness * (1 + saturation); else m2 = brightness + saturation - brightness * saturation; - + m1 = 2 * brightness - m2; - + hue_shift[0] = hue + 120; hue_shift[1] = hue; hue_shift[2] = hue - 120; - + color_shift[0] = color_shift[1] = color_shift[2] = brightness; - + i = (saturation == 0)?3:0; - + for (; i < 3; i++) { m3 = hue_shift[i]; - + if (m3 > 360) m3 = MODULA(m3, 360); else if (m3 < 0) m3 = 360 - MODULA(ABS(m3), 360); - + if (m3 < 60) color_shift[i] = m1 + (m2 - m1) * m3 / 60; else if (m3 < 180) @@ -114,8 +114,8 @@ ge_color_from_hsb (gdouble hue, color_shift[i] = m1 + (m2 - m1) * (240 - m3) / 60; else color_shift[i] = m1; - } - + } + color->r = color_shift[0]; color->g = color_shift[1]; color->b = color_shift[2]; @@ -163,7 +163,7 @@ ge_gtk_style_to_cairo_color_cube (GtkStyle * style, CairoColorCube *cube) g_return_if_fail (style && cube); for (i = 0; i < 5; i++) - { + { ge_gdk_color_to_cairo (&style->bg[i], &cube->bg[i]); ge_gdk_color_to_cairo (&style->fg[i], &cube->fg[i]); @@ -174,7 +174,7 @@ ge_gtk_style_to_cairo_color_cube (GtkStyle * style, CairoColorCube *cube) ge_gdk_color_to_cairo (&style->base[i], &cube->base[i]); ge_gdk_color_to_cairo (&style->text[i], &cube->text[i]); ge_gdk_color_to_cairo (&style->text_aa[i], &cube->text_aa[i]); - } + } cube->black.r = cube->black.g = cube->black.b = 0; cube->black.a = 1; @@ -189,27 +189,17 @@ ge_shade_color(const CairoColor *base, gdouble shade_ratio, CairoColor *composit gdouble hue = 0; gdouble saturation = 0; gdouble brightness = 0; - + g_return_if_fail (base && composite); - - if (shade_ratio == 1.0) - { - composite->r = base->r; - composite->g = base->g; - composite->b = base->b; - composite->a = base->a; - - return; - } ge_hsb_from_color (base, &hue, &saturation, &brightness); - + brightness = MIN(brightness*shade_ratio, 1.0); brightness = MAX(brightness, 0.0); - + saturation = MIN(saturation*shade_ratio, 1.0); saturation = MAX(saturation, 0.0); - + ge_color_from_hsb (hue, saturation, brightness, composite); composite->a = base->a; } @@ -220,7 +210,7 @@ ge_saturate_color (const CairoColor *base, gdouble saturate_level, CairoColor *c gdouble hue = 0; gdouble saturation = 0; gdouble brightness = 0; - + g_return_if_fail (base && composite); ge_hsb_from_color (base, &hue, &saturation, &brightness); @@ -233,7 +223,7 @@ ge_saturate_color (const CairoColor *base, gdouble saturate_level, CairoColor *c } void -ge_mix_color (const CairoColor *color1, const CairoColor *color2, +ge_mix_color (const CairoColor *color1, const CairoColor *color2, gdouble mix_factor, CairoColor *composite) { g_return_if_fail (color1 && color2 && composite); @@ -256,7 +246,7 @@ ge_gdk_drawable_to_cairo (GdkDrawable *window, GdkRectangle *area) cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); - if (area) + if (area) { cairo_rectangle (cr, area->x, area->y, area->width, area->height); cairo_clip_preserve (cr); @@ -287,8 +277,8 @@ ge_cairo_set_gdk_color_with_alpha (cairo_t *cr, const GdkColor *color, gdouble a void ge_cairo_pattern_add_color_stop_color (cairo_pattern_t *pattern, - gfloat offset, - const CairoColor *color) + gfloat offset, + const CairoColor *color) { g_return_if_fail (pattern && color); @@ -296,10 +286,10 @@ ge_cairo_pattern_add_color_stop_color (cairo_pattern_t *pattern, } void -ge_cairo_pattern_add_color_stop_shade (cairo_pattern_t *pattern, - gdouble offset, - const CairoColor *color, - gdouble shade) +ge_cairo_pattern_add_color_stop_shade(cairo_pattern_t *pattern, + gdouble offset, + const CairoColor *color, + gdouble shade) { CairoColor shaded; @@ -312,14 +302,12 @@ ge_cairo_pattern_add_color_stop_shade (cairo_pattern_t *pattern, ge_shade_color(color, shade, &shaded); } - ge_cairo_pattern_add_color_stop_color(pattern, offset, &shaded); + ge_cairo_pattern_add_color_stop_color(pattern, offset, &shaded); } -/* - * This function will draw a rounded corner at position x,y. If the radius +/* This function will draw a rounded corner at position x,y. If the radius * is very small (or negative) it will instead just do a line_to. - * ge_cairo_rounded_corner assumes clockwise drawing. - */ + * ge_cairo_rounded_corner assumes clockwise drawing. */ void ge_cairo_rounded_corner (cairo_t *cr, double x, @@ -333,29 +321,28 @@ ge_cairo_rounded_corner (cairo_t *cr, } else { - switch (corner) - { - case CR_CORNER_NONE: - cairo_line_to (cr, x, y); - break; - case CR_CORNER_TOPLEFT: - cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 3/2); - break; - case CR_CORNER_TOPRIGHT: - cairo_arc (cr, x - radius, y + radius, radius, G_PI * 3/2, G_PI * 2); - break; - case CR_CORNER_BOTTOMRIGHT: - cairo_arc (cr, x - radius, y - radius, radius, 0, G_PI * 1/2); - break; - case CR_CORNER_BOTTOMLEFT: - cairo_arc (cr, x + radius, y - radius, radius, G_PI * 1/2, G_PI); - break; - - default: - /* A bitfield and not a sane value ... */ - g_assert_not_reached (); - cairo_line_to (cr, x, y); - return; + switch (corner) { + case CR_CORNER_NONE: + cairo_line_to (cr, x, y); + break; + case CR_CORNER_TOPLEFT: + cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 3/2); + break; + case CR_CORNER_TOPRIGHT: + cairo_arc (cr, x - radius, y + radius, radius, G_PI * 3/2, G_PI * 2); + break; + case CR_CORNER_BOTTOMRIGHT: + cairo_arc (cr, x - radius, y - radius, radius, 0, G_PI * 1/2); + break; + case CR_CORNER_BOTTOMLEFT: + cairo_arc (cr, x + radius, y - radius, radius, G_PI * 1/2, G_PI); + break; + + default: + /* A bitfield and not a sane value ... */ + g_assert_not_reached (); + cairo_line_to (cr, x, y); + return; } } } @@ -408,9 +395,9 @@ ge_cairo_rounded_rectangle (cairo_t *cr, /* ge_cairo_stroke_rectangle. * - * A simple function to stroke the rectangle { x, y, w, h}. - * (This function only exists because of a cairo performance bug that - * has been fixed and it may be a good idea to get rid of it again.) + * A simple function to stroke the rectangle { x, y, w, h}. + * (This function only exists because of a cairo performance bug that + * has been fixed and it may be a good idea to get rid of it again.) */ void ge_cairo_stroke_rectangle (cairo_t *cr, double x, double y, double w, double h) @@ -419,48 +406,19 @@ ge_cairo_stroke_rectangle (cairo_t *cr, double x, double y, double w, double h) cairo_stroke (cr); } -void -ge_cairo_inner_rectangle (cairo_t *cr, - double x, double y, - double width, double height) -{ - double line_width = cairo_get_line_width (cr); - - cairo_rectangle (cr, x + line_width / 2.0, - y + line_width / 2.0, - width - line_width, - height - line_width); -} - -void -ge_cairo_inner_rounded_rectangle (cairo_t *cr, - double x, double y, - double width, double height, - double radius, CairoCorners corners) -{ - double line_width = cairo_get_line_width (cr); - - ge_cairo_rounded_rectangle (cr, - x + line_width / 2.0, - y + line_width / 2.0, - width - line_width, - height - line_width, - radius, corners); -} - /*********************************************** * ge_cairo_simple_border - * * A simple routine to draw thin squared * borders with a topleft and bottomright color. - * + * * It originated in Smooth-Engine. ***********************************************/ void ge_cairo_simple_border (cairo_t *cr, - const CairoColor * tl, const CairoColor * br, - gint x, gint y, gint width, gint height, - gboolean topleft_overlap) + const CairoColor * tl, const CairoColor * br, + gint x, gint y, gint width, gint height, + gboolean topleft_overlap) { gboolean solid_color; @@ -487,7 +445,7 @@ ge_cairo_simple_border (cairo_t *cr, cairo_stroke (cr); } - + ge_cairo_set_color(cr, tl); cairo_move_to(cr, x + 0.5, y + height - 0.5); @@ -513,9 +471,9 @@ ge_cairo_simple_border (cairo_t *cr, } void ge_cairo_polygon (cairo_t *cr, - const CairoColor *color, - GdkPoint *points, - gint npoints) + const CairoColor *color, + GdkPoint *points, + gint npoints) { int i = 0; @@ -545,12 +503,12 @@ void ge_cairo_polygon (cairo_t *cr, } void ge_cairo_line (cairo_t *cr, - const CairoColor *color, - gint x1, - gint y1, - gint x2, - gint y2) -{ + const CairoColor *color, + gint x1, + gint y1, + gint x2, + gint y2) +{ cairo_save(cr); ge_cairo_set_color(cr, color); @@ -626,19 +584,18 @@ ge_cairo_exchange_axis (cairo_t *cr, ***********************************************/ void ge_cairo_pattern_fill(cairo_t *canvas, - CairoPattern *pattern, - gint x, - gint y, - gint width, - gint height) + CairoPattern *pattern, + gint x, + gint y, + gint width, + gint height) { cairo_matrix_t original_matrix, current_matrix; if (pattern->operator == CAIRO_OPERATOR_DEST) + { return; - - if (width <= 0 || height <= 0) - return; + } cairo_pattern_get_matrix(pattern->handle, &original_matrix); current_matrix = original_matrix; @@ -684,7 +641,7 @@ ge_cairo_pattern_fill(cairo_t *canvas, cairo_save(canvas); cairo_set_source(canvas, pattern->handle); - cairo_set_operator(canvas, pattern->operator); + cairo_set_operator(canvas, pattern->operator); cairo_rectangle(canvas, x, y, width, height); cairo_fill (canvas); @@ -701,7 +658,7 @@ ge_cairo_pattern_fill(cairo_t *canvas, ***********************************************/ CairoPattern* ge_cairo_color_pattern(CairoColor *base) -{ +{ CairoPattern * result = g_new0(CairoPattern, 1); #if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) @@ -711,10 +668,10 @@ ge_cairo_color_pattern(CairoColor *base) result->scale = GE_DIRECTION_NONE; result->translate = GE_DIRECTION_NONE; - result->handle = cairo_pattern_create_rgba(base->r, - base->g, - base->b, - base->a); + result->handle = cairo_pattern_create_rgba(base->r, + base->g, + base->b, + base->a); result->operator = CAIRO_OPERATOR_SOURCE; @@ -728,14 +685,14 @@ ge_cairo_color_pattern(CairoColor *base) ***********************************************/ CairoPattern* ge_cairo_pixbuf_pattern(GdkPixbuf *pixbuf) -{ +{ CairoPattern * result = g_new0(CairoPattern, 1); cairo_t *canvas; cairo_surface_t * surface; gint width, height; - #if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) + #if ((CAIRO_VERSION_MAJOR < 1) || ((CAIRO_VERSION_MAJOR == 1) && (CAIRO_VERSION_MINOR < 2))) result->type = CAIRO_PATTERN_TYPE_SURFACE; #endif @@ -780,8 +737,8 @@ ge_cairo_pixmap_pattern(GdkPixmap *pixmap) gdk_drawable_get_size (GDK_DRAWABLE (pixmap), &width, &height); pixbuf = gdk_pixbuf_get_from_drawable(NULL, GDK_DRAWABLE (pixmap), - gdk_drawable_get_colormap(GDK_DRAWABLE (pixmap)), - 0, 0, 0, 0, width, height); + gdk_drawable_get_colormap(GDK_DRAWABLE (pixmap)), + 0, 0, 0, 0, width, height); result = ge_cairo_pixbuf_pattern(pixbuf); @@ -800,9 +757,9 @@ ge_cairo_pixmap_pattern(GdkPixmap *pixmap) ***********************************************/ CairoPattern * ge_cairo_linear_shade_gradient_pattern(CairoColor *base, - gdouble shade1, - gdouble shade2, - gboolean vertical) + gdouble shade1, + gdouble shade2, + gboolean vertical) { CairoPattern * result = g_new0(CairoPattern, 1); @@ -839,13 +796,12 @@ ge_cairo_pattern_destroy(CairoPattern *pattern) { if (pattern->handle) cairo_pattern_destroy(pattern->handle); - + g_free(pattern); } } -/* - * The following function will be called by GTK+ when the module +/* The following function will be called by GTK+ when the module * is loaded and checks to see if we are compatible with the * version of GTK+ that loads us. */ @@ -853,7 +809,7 @@ GE_EXPORT const gchar* g_module_check_init (GModule *module); const gchar* g_module_check_init (GModule *module) { - return gtk_check_version (GTK_MAJOR_VERSION, - GTK_MINOR_VERSION, - GTK_MICRO_VERSION - GTK_INTERFACE_AGE); + return gtk_check_version (GTK_MAJOR_VERSION, + GTK_MINOR_VERSION, + GTK_MICRO_VERSION - GTK_INTERFACE_AGE); } diff --git a/libs/clearlooks/cairo-support.h b/libs/clearlooks-newer/cairo-support.h index 2abcb81609..12163b0469 100644 --- a/libs/clearlooks/cairo-support.h +++ b/libs/clearlooks-newer/cairo-support.h @@ -101,8 +101,6 @@ GE_INTERNAL void ge_cairo_rounded_corner (cairo_t *cr, double x, double y, doubl GE_INTERNAL void ge_cairo_rounded_rectangle (cairo_t *cr, double x, double y, double w, double h, double radius, CairoCorners corners); GE_INTERNAL void ge_cairo_stroke_rectangle (cairo_t *cr, double x, double y, double w, double h); -GE_INTERNAL void ge_cairo_inner_rectangle (cairo_t *cr, double x, double y, double width, double height); -GE_INTERNAL void ge_cairo_inner_rounded_rectangle (cairo_t *cr, double x, double y, double width, double height, double radius, CairoCorners corners); GE_INTERNAL void ge_cairo_simple_border (cairo_t *cr, const CairoColor * tl, const CairoColor * br, gint x, gint y, gint width, gint height, gboolean topleft_overlap); GE_INTERNAL void ge_cairo_line (cairo_t *cr, const CairoColor *color, gint x1, gint y1, gint x2, gint y2); diff --git a/libs/clearlooks/clearlooks_draw.c b/libs/clearlooks-newer/clearlooks_draw.c index a6586ab0d6..614317ea3b 100644 --- a/libs/clearlooks/clearlooks_draw.c +++ b/libs/clearlooks-newer/clearlooks_draw.c @@ -31,12 +31,6 @@ #include <cairo.h> -/* Normal shadings */ -#define SHADE_TOP 1.055 -#define SHADE_CENTER_TOP 1.01 -#define SHADE_CENTER_BOTTOM 0.98 -#define SHADE_BOTTOM 0.90 - typedef void (*menubar_draw_proto) (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *params, @@ -44,124 +38,98 @@ typedef void (*menubar_draw_proto) (cairo_t *cr, int x, int y, int width, int height); static void -clearlooks_draw_inset (cairo_t *cr, - const CairoColor *bg_color, - double x, double y, double width, double height, +clearlooks_draw_inset (cairo_t *cr, + const CairoColor *bg_color, + double x, double y, double w, double h, double radius, uint8 corners) { CairoColor shadow; CairoColor highlight; - double line_width; - double min = MIN (width, height); - - line_width = cairo_get_line_width (cr); /* not really sure of shading ratios... we will think */ ge_shade_color (bg_color, 0.94, &shadow); ge_shade_color (bg_color, 1.06, &highlight); /* highlight */ - cairo_save (cr); + cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */ - cairo_move_to (cr, x, y + height); - cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0); - cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0); - cairo_line_to (cr, x + width, y); - cairo_line_to (cr, x, y); - cairo_close_path (cr); - - cairo_clip (cr); + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2); + else + cairo_line_to (cr, x + w, y); - ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0, - width - line_width, height - line_width, - radius, corners); + if (corners & CR_CORNER_BOTTOMRIGHT) + cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5); + else + cairo_line_to (cr, x + w, y + h); - ge_cairo_set_color (cr, &shadow); + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75); + else + cairo_line_to (cr, x, y + h); + + ge_cairo_set_color (cr, &highlight); cairo_stroke (cr); - - cairo_restore (cr); /* shadow */ - cairo_save (cr); + cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188)); - cairo_move_to (cr, x, y + height); - cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0); - cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0); - cairo_line_to (cr, x + width, y); - cairo_line_to (cr, x + width, y + height); - cairo_close_path (cr); - - cairo_clip (cr); + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI); + else + cairo_line_to (cr, x, y + h); - ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0, - width - line_width, height - line_width, - radius, corners); + if (corners & CR_CORNER_TOPLEFT) + cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5); + else + cairo_line_to (cr, x, y); - ge_cairo_set_color (cr, &highlight); - cairo_stroke (cr); + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75); + else + cairo_line_to (cr, x + w, y); - cairo_restore (cr); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); } static void clearlooks_draw_shadow (cairo_t *cr, const ClearlooksColors *colors, gfloat radius, int width, int height) { - CairoColor shadow; - cairo_save (cr); - + CairoColor shadow; ge_shade_color (&colors->shade[6], 0.92, &shadow); cairo_set_line_width (cr, 1.0); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1); - - cairo_move_to (cr, width - 0.5, radius); - ge_cairo_rounded_corner (cr, width - 0.5, height - 0.5, radius, CR_CORNER_BOTTOMRIGHT); - cairo_line_to (cr, radius, height - 0.5); + + cairo_move_to (cr, width, radius); + ge_cairo_rounded_corner (cr, width, height, radius, CR_CORNER_BOTTOMRIGHT); + cairo_line_to (cr, radius, height); cairo_stroke (cr); - cairo_restore (cr); } -/* This is copied at least in clearlooks_draw_gummy.c. - * KEEP IN SYNC IF POSSIBLE! */ static void clearlooks_draw_top_left_highlight (cairo_t *cr, const CairoColor *color, const WidgetParameters *params, - int x, int y, int width, int height, - gdouble radius, CairoCorners corners) + int width, int height, gdouble radius) { - CairoColor hilight; - - double line_width = cairo_get_line_width (cr); - double offset = line_width / 2.0; - double light_top, light_bottom, light_left, light_right; - - cairo_save (cr); + CairoColor hilight; - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); + double light_top = params->ythickness-1, + light_bottom = height - params->ythickness - 1, + light_left = params->xthickness-1, + light_right = width - params->xthickness - 1; - light_top = y + offset; - light_bottom = y + height; - light_left = x + offset; - light_right = x + width; - - if (corners & CR_CORNER_BOTTOMLEFT) - light_bottom -= radius; - if (corners & CR_CORNER_TOPRIGHT) - light_right -= radius; + ge_shade_color (color, 1.3, &hilight); + cairo_move_to (cr, light_left, light_bottom - (int)radius/2); - ge_shade_color (color, params->style_constants->topleft_highlight_shade, &hilight); - cairo_move_to (cr, light_left, light_bottom); + ge_cairo_rounded_corner (cr, light_left, light_top, radius, params->corners & CR_CORNER_TOPLEFT); - ge_cairo_rounded_corner (cr, light_left, light_top, radius, corners & CR_CORNER_TOPLEFT); - - cairo_line_to (cr, light_right, light_top); - cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, params->style_constants->topleft_highlight_alpha); + cairo_line_to (cr, light_right - (int)radius/2, light_top); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); cairo_stroke (cr); - - cairo_restore (cr); } #ifdef DEVELOPMENT @@ -179,46 +147,47 @@ clearlooks_draw_highlight_and_shade (cairo_t *cr, const ClearlooksColors *colors double x = 1.0; double y = 1.0; - ge_shade_color (&colors->bg[0], 1.06, &hilight); - ge_shade_color (&colors->bg[0], 0.94, &shadow); - - width -= 2; - height -= 2; + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 1.06, &hilight); + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 0.94, &shadow); + width -= 3; + height -= 3; + cairo_save (cr); - + /* Top/Left highlight */ if (corners & CR_CORNER_BOTTOMLEFT) - cairo_move_to (cr, x + 0.5, y+height-radius); + cairo_move_to (cr, x, y+height-radius); else - cairo_move_to (cr, x + 0.5, y+height); - - ge_cairo_rounded_corner (cr, x + 0.5, y + 0.5, radius, corners & CR_CORNER_TOPLEFT); + cairo_move_to (cr, x, y+height); + + ge_cairo_rounded_corner (cr, x, y, radius, corners & CR_CORNER_TOPLEFT); if (corners & CR_CORNER_TOPRIGHT) - cairo_line_to (cr, x+width-radius, y + 0.5); + cairo_line_to (cr, x+width-radius, y); else - cairo_line_to (cr, x+width, y + 0.5); - + cairo_line_to (cr, x+width, y); + if (params->shadow & CL_SHADOW_OUT) ge_cairo_set_color (cr, &hilight); else ge_cairo_set_color (cr, &shadow); - + cairo_stroke (cr); - + /* Bottom/Right highlight -- this includes the corners */ - cairo_arc (cr, x + width - 0.5 - radius, y + radius, radius, G_PI * (3/2.0+1/4.0), G_PI * 2); - ge_cairo_rounded_corner (cr, x+width - 0.5, y+height - 0.5, radius, corners & CR_CORNER_BOTTOMRIGHT); - cairo_arc (cr, x + radius, y + height - 0.5 - radius, radius, G_PI * 1/2, G_PI * 3/4); - + cairo_move_to (cr, x+width-radius, y); /* topright and by radius to the left */ + ge_cairo_rounded_corner (cr, x+width, y, radius, corners & CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, x+width, y+height, radius, corners & CR_CORNER_BOTTOMRIGHT); + ge_cairo_rounded_corner (cr, x, y+height, radius, corners & CR_CORNER_BOTTOMLEFT); + if (params->shadow & CL_SHADOW_OUT) ge_cairo_set_color (cr, &shadow); else ge_cairo_set_color (cr, &hilight); - + cairo_stroke (cr); - + cairo_restore (cr); } @@ -233,7 +202,7 @@ clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hil pattern = cairo_pattern_create_linear (0, 0, width, height); cairo_pattern_add_color_stop_rgb (pattern, 0, color->r, color->g, color->b); cairo_pattern_add_color_stop_rgb (pattern, 1, bottom_shade.r, bottom_shade.g, bottom_shade.b); - + cairo_set_source (cr, pattern); cairo_pattern_destroy (pattern); } @@ -247,25 +216,20 @@ clearlooks_draw_gripdots (cairo_t *cr, const ClearlooksColors *colors, int x, in CairoColor hilight; int i, j; int xoff, yoff; - int x_start, y_start; ge_shade_color (dark, 1.5, &hilight); - - /* The "- 1" is because there is no space in front of the first dot. */ - x_start = x + width / 2 - ((xr * 3 - 1) / 2); - y_start = y + height / 2 - ((yr * 3 - 1) / 2); - - for ( i = 0; i < xr; i++ ) + + for ( i = 0; i < xr; i++ ) { for ( j = 0; j < yr; j++ ) { - xoff = 3 * i; - yoff = 3 * j; - - cairo_rectangle (cr, x_start + xoff, y_start + yoff, 2, 2); + xoff = x -(xr * 3 / 2) + 3 * i; + yoff = y -(yr * 3 / 2) + 3 * j; + + cairo_rectangle (cr, width/2+0.5+xoff, height/2+0.5+yoff, 2, 2); cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.8+contrast); cairo_fill (cr); - cairo_rectangle (cr, x_start + xoff, y_start + yoff, 1, 1); + cairo_rectangle (cr, width/2+0.5+xoff, height/2+0.5+yoff, 1, 1); cairo_set_source_rgba (cr, dark->r, dark->g, dark->b, 0.8+contrast); cairo_fill (cr); } @@ -281,16 +245,14 @@ clearlooks_draw_button (cairo_t *cr, double xoffset = 0, yoffset = 0; double radius = params->radius; const CairoColor *fill = &colors->bg[params->state_type]; - CairoColor border_normal = colors->shade[6]; - CairoColor border_disabled = colors->shade[4]; + const CairoColor *border_normal = &colors->shade[6]; + const CairoColor *border_disabled = &colors->shade[4]; CairoColor shadow; - ge_shade_color (&border_normal, 1.04, &border_normal); - ge_shade_color (&border_normal, 0.94, &shadow); - ge_shade_color (&border_disabled, 1.08, &border_disabled); - + ge_shade_color (border_normal, 0.925, &shadow); + cairo_save (cr); - + cairo_translate (cr, x, y); cairo_set_line_width (cr, 1.0); @@ -306,52 +268,42 @@ clearlooks_draw_button (cairo_t *cr, if (params->xthickness == 3 || params->ythickness == 3) { - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, radius+1, params->corners); - } - + cairo_translate (cr, 0.5, 0.5); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); + } + ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height-(yoffset*2)-2, radius, params->corners); - + if (!params->active) { cairo_pattern_t *pattern; - CairoColor top_shade, topmiddle_shade, bottom_shade, middle_shade; - - ge_shade_color (fill, SHADE_TOP, &top_shade); - ge_shade_color (fill, SHADE_CENTER_TOP, &topmiddle_shade); - ge_shade_color (fill, SHADE_CENTER_BOTTOM, &middle_shade); - ge_shade_color (fill, SHADE_BOTTOM, &bottom_shade); - - cairo_save (cr); - cairo_clip_preserve (cr); - + gdouble shade_size = ((100.0/height)*8.0)/100.0; + CairoColor top_shade, bottom_shade, middle_shade; + + ge_shade_color (fill, 1.1, &top_shade); + ge_shade_color (fill, 0.98, &middle_shade); + ge_shade_color (fill, 0.93, &bottom_shade); + pattern = cairo_pattern_create_linear (0, 0, 0, height); cairo_pattern_add_color_stop_rgb (pattern, 0.0, top_shade.r, top_shade.g, top_shade.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.3, topmiddle_shade.r, topmiddle_shade.g, topmiddle_shade.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.7, middle_shade.r, middle_shade.g, middle_shade.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, shade_size, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0 - shade_size, middle_shade.r, middle_shade.g, middle_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, (height-(yoffset*2)-1)/height, bottom_shade.r, bottom_shade.g, bottom_shade.b); + cairo_pattern_add_color_stop_rgba (pattern, (height-(yoffset*2)-1)/height, bottom_shade.r, bottom_shade.g, bottom_shade.b, 0.7); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, bottom_shade.r, bottom_shade.g, bottom_shade.b, 0.7); + cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - - cairo_move_to (cr, width-(xoffset*2)-0.5, 0); - cairo_line_to (cr, width-(xoffset*2)-0.5, height); - ge_cairo_set_color (cr, &bottom_shade); - cairo_stroke (cr); - - /* Draw topleft shadow */ - params->style_functions->draw_top_left_highlight (cr, fill, params, xoffset + 1, yoffset + 1, - width - 2*(xoffset + 1), height - 2*(yoffset + 1), - MAX(radius-1, 0), params->corners); - - cairo_restore (cr); } else { cairo_pattern_t *pattern; - + ge_cairo_set_color (cr, fill); cairo_fill_preserve (cr); @@ -364,46 +316,58 @@ clearlooks_draw_button (cairo_t *cr, cairo_pattern_destroy (pattern); pattern = cairo_pattern_create_linear (0, yoffset+1, 0, 3+yoffset); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.32); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3); cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); cairo_set_source (cr, pattern); cairo_fill_preserve (cr); cairo_pattern_destroy (pattern); pattern = cairo_pattern_create_linear (xoffset+1, 0, 3+xoffset, 0); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.32); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, params->disabled ? 0.125 : 0.3); cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } + /* Drawing the border */ if (!params->active && params->is_default) { - ge_shade_color (&border_normal, 0.74, &border_normal); - } + const CairoColor *l = &colors->shade[4]; + const CairoColor *d = &colors->shade[4]; + ge_cairo_set_color (cr, l); + ge_cairo_stroke_rectangle (cr, 2.5, 2.5, width-5, height-5); - ge_cairo_inner_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, params->corners); + ge_cairo_set_color (cr, d); + ge_cairo_stroke_rectangle (cr, 3.5, 3.5, width-7, height-7); + } + + ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5, width-(xoffset*2)-1, height-(yoffset*2)-1, radius, params->corners); if (params->disabled) - { - ge_cairo_set_color (cr, &border_disabled); - } + ge_cairo_set_color (cr, border_disabled); else - { if (!params->active) - clearlooks_set_border_gradient (cr, &border_normal, - params->is_default ? 1.1 : 1.3, 0, height); + clearlooks_set_border_gradient (cr, border_normal, 1.32, 0, height); else - { - ge_shade_color (&border_normal, 1.08, &border_normal); - ge_cairo_set_color (cr, &border_normal); - } - } - + ge_cairo_set_color (cr, border_normal); + cairo_stroke (cr); - + + /* Draw the "shadow" */ + if (!params->active) + { + cairo_translate (cr, 0.5, 0.5); + /* Draw right shadow */ + cairo_move_to (cr, width-params->xthickness, params->ythickness - 1); + cairo_line_to (cr, width-params->xthickness, height - params->ythickness - 1); + cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1); + cairo_stroke (cr); + + /* Draw topleft shadow */ + clearlooks_draw_top_left_highlight (cr, fill, params, width, height, radius); + } cairo_restore (cr); } @@ -414,53 +378,56 @@ clearlooks_draw_entry (cairo_t *cr, int x, int y, int width, int height) { const CairoColor *base = &colors->base[params->state_type]; - CairoColor border = colors->shade[params->disabled ? 3 : 6]; + CairoColor border = colors->shade[params->disabled ? 4 : 6]; double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0)); - + if (params->focus) border = colors->spot[2]; - cairo_save (cr); - - cairo_translate (cr, x, y); + cairo_translate (cr, x+0.5, y+0.5); cairo_set_line_width (cr, 1.0); + + /* Fill the background (shouldn't have to) */ + cairo_rectangle (cr, -0.5, -0.5, width, height); + ge_cairo_set_color (cr, ¶ms->parentbg); + cairo_fill (cr); - /* Now fill the area we want to be base[NORMAL]. */ - ge_cairo_rounded_rectangle (cr, 2, 2, width-4, height-4, MAX(0, radius-1), params->corners); + /* Fill the entry's base color (why isn't is large enough by default?) */ + cairo_rectangle (cr, 1.5, 1.5, width-4, height-4); ge_cairo_set_color (cr, base); cairo_fill (cr); - - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, radius+1, params->corners); + + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); /* Draw the inner shadow */ if (params->focus) { + /* ge_cairo_rounded_rectangle (cr, 2, 2, width-5, height-5, RADIUS-1, params->corners); */ ge_cairo_set_color (cr, &colors->spot[0]); - ge_cairo_inner_rounded_rectangle (cr, 2, 2, width-4, height-4, MAX(0, radius-1), params->corners); - cairo_stroke (cr); + ge_cairo_stroke_rectangle (cr, 2, 2, width-5, height-5); } else { - CairoColor shadow; + CairoColor shadow; ge_shade_color (&border, 0.925, &shadow); cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.05 : 0.1); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_move_to (cr, 2.5, height-radius); - cairo_arc (cr, 2.5+MAX(0, radius-1), 2.5+MAX(0, radius-1), MAX(0, radius-1), G_PI, 270*(G_PI/180)); - cairo_line_to (cr, width-radius, 2.5); + /* + cairo_move_to (cr, 2, height-3); + cairo_arc (cr, params->xthickness+RADIUS-1, params->ythickness+RADIUS-1, RADIUS, G_PI, 270*(G_PI/180)); + cairo_line_to (cr, width-3, 2);*/ + cairo_move_to (cr, 2, height-3); + cairo_line_to (cr, 2, 2); + cairo_line_to (cr, width-3, 2); cairo_stroke (cr); } - ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, params->corners); if (params->focus || params->disabled) ge_cairo_set_color (cr, &border); else - clearlooks_set_border_gradient (cr, &border, 1.32, 0, height); + clearlooks_set_border_gradient (cr, &border, 1.32, 0, height); cairo_stroke (cr); - - cairo_restore (cr); } static void @@ -470,12 +437,11 @@ clearlooks_draw_spinbutton (cairo_t *cr, int x, int y, int width, int height) { const CairoColor *border = &colors->shade[!params->disabled ? 5 : 3]; - CairoColor hilight; + CairoColor hilight; params->style_functions->draw_button (cr, colors, params, x, y, width, height); - ge_shade_color (&colors->bg[0], params->style_constants->topleft_highlight_shade, &hilight); - hilight.a = params->style_constants->topleft_highlight_alpha; + ge_shade_color (border, 1.5, &hilight); cairo_translate (cr, x, y); @@ -498,24 +464,24 @@ clearlooks_draw_spinbutton_down (cairo_t *cr, { cairo_pattern_t *pattern; double radius = MIN (params->radius, MIN ((width - 4.0) / 2.0, (height - 4.0) / 2.0)); - CairoColor shadow; - ge_shade_color (&colors->bg[0], 0.8, &shadow); + CairoColor shadow; + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 0.8, &shadow); cairo_translate (cr, x+1, y+1); - + ge_cairo_rounded_rectangle (cr, 1, 1, width-4, height-4, radius, params->corners); - + ge_cairo_set_color (cr, &colors->bg[params->state_type]); - + cairo_fill_preserve (cr); - + pattern = cairo_pattern_create_linear (0, 0, 0, height); cairo_pattern_add_color_stop_rgb (pattern, 0.0, shadow.r, shadow.g, shadow.b); cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.0); - + cairo_set_source (cr, pattern); cairo_fill (cr); - + cairo_pattern_destroy (pattern); } @@ -529,21 +495,20 @@ clearlooks_scale_draw_gradient (cairo_t *cr, { cairo_pattern_t *pattern; - pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 : width + 1, horizontal ? height + 1: 0.5); + pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 : width, horizontal ? height : 0); cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b); - cairo_rectangle (cr, x, y, width, height); + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - + ge_cairo_set_color (cr, c3); - ge_cairo_inner_rectangle (cr, x, y, width, height); - cairo_stroke (cr); + ge_cairo_stroke_rectangle (cr, x, y, width, height); } -#define TROUGH_SIZE 7 +#define TROUGH_SIZE 6 static void clearlooks_draw_scale_trough (cairo_t *cr, const ClearlooksColors *colors, @@ -554,54 +519,43 @@ clearlooks_draw_scale_trough (cairo_t *cr, int trough_width, trough_height; double translate_x, translate_y; - cairo_save (cr); - if (slider->horizontal) { - trough_width = width; - trough_height = TROUGH_SIZE; + trough_width = width-3; + trough_height = TROUGH_SIZE-2; - translate_x = x; - translate_y = y + (height/2) - (TROUGH_SIZE/2); + translate_x = x + 0.5; + translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2); } else { - trough_width = TROUGH_SIZE; - trough_height = height; + trough_width = TROUGH_SIZE-2; + trough_height = height-3; - translate_x = x + (width/2) - (TROUGH_SIZE/2); - translate_y = y; + translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2); + translate_y = y + 0.5; } cairo_set_line_width (cr, 1.0); cairo_translate (cr, translate_x, translate_y); - + if (!slider->fill_level) - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width, trough_height, 0, 0); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0); - if (!slider->lower && !slider->fill_level) - { - CairoColor shadow; - ge_shade_color (&colors->shade[2], 0.96, &shadow); - - clearlooks_scale_draw_gradient (cr, &shadow, /* top */ - &colors->shade[2], /* bottom */ - &colors->shade[4], /* border */ - 1.0, 1.0, trough_width - 2, trough_height - 2, - slider->horizontal); - } + cairo_translate (cr, 1, 1); + + if (!slider->lower && ! slider->fill_level) + clearlooks_scale_draw_gradient (cr, &colors->shade[3], /* top */ + &colors->shade[2], /* bottom */ + &colors->shade[6], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal); else - { - CairoColor border = colors->spot[2]; - border.a = 0.64; - - clearlooks_scale_draw_gradient (cr, &colors->spot[1], /* top */ - &colors->spot[0], /* bottom */ - &border, /* border */ - 1.0, 1.0, trough_width - 2, trough_height - 2, - slider->horizontal); - } - cairo_restore (cr); + clearlooks_scale_draw_gradient (cr, &colors->spot[1], /* top */ + &colors->spot[0], /* bottom */ + &colors->spot[2], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal); } static void @@ -610,21 +564,21 @@ clearlooks_draw_slider (cairo_t *cr, const WidgetParameters *params, int x, int y, int width, int height) { + const CairoColor *border = &colors->shade[params->disabled ? 4 : 6]; const CairoColor *spot = &colors->spot[1]; const CairoColor *fill = &colors->shade[2]; - CairoColor border = colors->shade[params->disabled ? 4 : 6]; double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0)); cairo_pattern_t *pattern; - cairo_set_line_width (cr, 1.0); + cairo_set_line_width (cr, 1.0); cairo_translate (cr, x, y); if (params->prelight) - border = colors->spot[2]; + border = &colors->spot[2]; /* fill the widget */ - ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-2, height-2, radius, params->corners); + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); /* Fake light */ if (!params->disabled) @@ -642,33 +596,34 @@ clearlooks_draw_slider (cairo_t *cr, else { ge_cairo_set_color (cr, fill); + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); cairo_fill (cr); } /* Set the clip */ cairo_save (cr); - cairo_rectangle (cr, 1.0, 1.0, 6, height-2); - cairo_rectangle (cr, width-7.0, 1.0, 6, height-2); + cairo_rectangle (cr, 0.5, 0.5, 6, height-2); + cairo_rectangle (cr, width-7.5, 0.5, 6 , height-2); cairo_clip_preserve (cr); cairo_new_path (cr); /* Draw the handles */ - ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-1, height-1, radius, params->corners); - pattern = cairo_pattern_create_linear (1.0, 1.0, 1.0, 1.0+height); + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners); + pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, 0.5+height); if (params->prelight) { CairoColor highlight; - ge_shade_color (spot, 1.3, &highlight); + ge_shade_color (spot, 1.5, &highlight); cairo_pattern_add_color_stop_rgb (pattern, 0.0, highlight.r, highlight.g, highlight.b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, spot->r, spot->g, spot->b); cairo_set_source (cr, pattern); } - else + else { - CairoColor hilight; - ge_shade_color (fill, 1.3, &hilight); + CairoColor hilight; + ge_shade_color (fill, 1.5, &hilight); cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); } @@ -678,26 +633,28 @@ clearlooks_draw_slider (cairo_t *cr, cairo_restore (cr); /* Draw the border */ - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); if (params->prelight || params->disabled) - ge_cairo_set_color (cr, &border); + ge_cairo_set_color (cr, border); else - clearlooks_set_border_gradient (cr, &border, 1.2, 0, height); + clearlooks_set_border_gradient (cr, border, 1.2, 0, height); cairo_stroke (cr); /* Draw handle lines */ if (width > 14) { - cairo_move_to (cr, 6.5, 1.0); - cairo_line_to (cr, 6.5, height-1); - - cairo_move_to (cr, width-6.5, 1.0); - cairo_line_to (cr, width-6.5, height-1); - + cairo_move_to (cr, 6, 0.5); + cairo_line_to (cr, 6, height-1); + + cairo_move_to (cr, width-7, 0.5); + cairo_line_to (cr, width-7, height-1); + cairo_set_line_width (cr, 1.0); - border.a = params->disabled ? 0.6 : 0.3; - ge_cairo_set_color (cr, &border); + cairo_set_source_rgba (cr, border->r, + border->g, + border->b, + 0.3); cairo_stroke (cr); } } @@ -709,22 +666,18 @@ clearlooks_draw_slider_button (cairo_t *cr, const SliderParameters *slider, int x, int y, int width, int height) { - double radius = MIN (params->radius, MIN ((width - 1.0) / 2.0, (height - 1.0) / 2.0)); - - cairo_save (cr); + double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); cairo_set_line_width (cr, 1.0); - + if (!slider->horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); - cairo_translate (cr, x, y); + cairo_translate (cr, x+0.5, y+0.5); - params->style_functions->draw_shadow (cr, colors, radius, width, height); + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); if (width > 24) - params->style_functions->draw_gripdots (cr, colors, 1, 1, width-2, height-2, 3, 3, 0); - - cairo_restore (cr); + params->style_functions->draw_gripdots (cr, colors, 0, 0, width-2, height-2, 3, 3, 0); } static void @@ -733,18 +686,24 @@ clearlooks_draw_progressbar_trough (cairo_t *cr, const WidgetParameters *params, int x, int y, int width, int height) { - const CairoColor *border = &colors->shade[4]; - CairoColor shadow; - cairo_pattern_t *pattern; - double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0)); - + const CairoColor *border = &colors->shade[6]; + CairoColor shadow; + cairo_pattern_t *pattern; + double radius = MIN (params->radius, MIN ((height-2.0) / 2.0, (width-2.0) / 2.0)); + cairo_save (cr); cairo_set_line_width (cr, 1.0); + + /* Fill with bg color */ + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); /* Create trough box */ ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); - ge_cairo_set_color (cr, &colors->shade[2]); + ge_cairo_set_color (cr, &colors->shade[3]); cairo_fill (cr); /* Draw border */ @@ -761,8 +720,8 @@ clearlooks_draw_progressbar_trough (cairo_t *cr, /* Top shadow */ cairo_rectangle (cr, x+1, y+1, width-2, 4); pattern = cairo_pattern_create_linear (x, y, x, y+4); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.2); - cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); @@ -770,8 +729,8 @@ clearlooks_draw_progressbar_trough (cairo_t *cr, /* Left shadow */ cairo_rectangle (cr, x+1, y+1, 4, height-2); pattern = cairo_pattern_create_linear (x, y, x+4, y); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.2); - cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.3); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); @@ -811,9 +770,9 @@ clearlooks_draw_progressbar_fill (cairo_t *cr, /* Clamp the radius so that the _height_ fits ... */ radius = MIN (radius, height / 2.0); - stroke_width = height; + stroke_width = height*2; x_step = (((float)stroke_width/10)*offset); /* This looks weird ... */ - + cairo_translate (cr, x, y); cairo_save (cr); @@ -826,19 +785,13 @@ clearlooks_draw_progressbar_fill (cairo_t *cr, /* Draw the background gradient */ ge_shade_color (&colors->spot[1], 1.1, &bg_shade); - - /* Just leave this disabled, maybe we could use the same gradient - * as the buttons in the future, not flat fill */ -/* pattern = cairo_pattern_create_linear (0, 0, 0, height);*/ -/* cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b);*/ -/* cairo_pattern_add_color_stop_rgb (pattern, 0.6, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b);*/ -/* cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b);*/ -/* cairo_set_source (cr, pattern);*/ -/* cairo_paint (cr);*/ -/* cairo_pattern_destroy (pattern);*/ - - ge_cairo_set_color (cr, &bg_shade); + pattern = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.6, colors->spot[1].r, colors->spot[1].g, colors->spot[1].b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg_shade.r, bg_shade.g, bg_shade.b); + cairo_set_source (cr, pattern); cairo_paint (cr); + cairo_pattern_destroy (pattern); /* Draw the Strokes */ while (tile_pos <= width+x_step) @@ -847,20 +800,50 @@ clearlooks_draw_progressbar_fill (cairo_t *cr, cairo_line_to (cr, stroke_width-x_step, 0); cairo_line_to (cr, stroke_width/2-x_step, height); cairo_line_to (cr, -x_step, height); - + cairo_translate (cr, stroke_width, 0); tile_pos += stroke_width; } - - pattern = cairo_pattern_create_linear (0, 0, 0, height); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0); - cairo_pattern_add_color_stop_rgba (pattern, 1.0, colors->spot[2].r, colors->spot[2].g, colors->spot[2].b, 0.24); - cairo_set_source (cr, pattern); + + cairo_set_source_rgba (cr, colors->spot[2].r, + colors->spot[2].g, + colors->spot[2].b, + 0.15); + cairo_fill (cr); - cairo_pattern_destroy (pattern); - cairo_restore (cr); /* rounded clip region */ + /* inner highlight border + * This is again kinda ugly. Draw once from each side, clipping away the other. */ + cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 0.5); + + /* left side */ + cairo_save (cr); + cairo_rectangle (cr, 0, 0, width / 2, height); + cairo_clip (cr); + + if (progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, 1.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + else + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + /* right side */ + cairo_save (cr); + cairo_rectangle (cr, width / 2, 0, (width+1) / 2, height); + cairo_clip (cr); + + if (progressbar->value < 1.0 || progressbar->pulsing) + ge_cairo_rounded_rectangle (cr, -1.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + else + ge_cairo_rounded_rectangle (cr, -0.5 - radius, 0.5, width + radius, height - 1, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); + + cairo_stroke (cr); + cairo_restore (cr); /* clip */ + + /* Draw the dark lines and the shadow */ cairo_save (cr); /* Again, this weird clip area. */ @@ -869,6 +852,8 @@ clearlooks_draw_progressbar_fill (cairo_t *cr, ge_cairo_rounded_rectangle (cr, -radius - 1.0, 0, width + radius + 2.0, height, radius, CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT); cairo_clip (cr); + border = colors->spot[2]; + border.a = 0.5; shadow.r = 0.0; shadow.g = 0.0; shadow.b = 0.0; @@ -877,6 +862,12 @@ clearlooks_draw_progressbar_fill (cairo_t *cr, if (progressbar->pulsing) { /* At the beginning of the bar. */ + cairo_move_to (cr, 0.5 + radius, height + 0.5); + ge_cairo_rounded_corner (cr, 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); + ge_cairo_rounded_corner (cr, 0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + cairo_move_to (cr, -0.5 + radius, height + 0.5); ge_cairo_rounded_corner (cr, -0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMLEFT); ge_cairo_rounded_corner (cr, -0.5, -0.5, radius + 1, CR_CORNER_TOPLEFT); @@ -886,27 +877,19 @@ clearlooks_draw_progressbar_fill (cairo_t *cr, if (progressbar->value < 1.0 || progressbar->pulsing) { /* At the end of the bar. */ + cairo_move_to (cr, width - 0.5 - radius, -0.5); + ge_cairo_rounded_corner (cr, width - 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); + ge_cairo_rounded_corner (cr, width - 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); + cairo_move_to (cr, width + 0.5 - radius, -0.5); ge_cairo_rounded_corner (cr, width + 0.5, -0.5, radius + 1, CR_CORNER_TOPRIGHT); ge_cairo_rounded_corner (cr, width + 0.5, height + 0.5, radius + 1, CR_CORNER_BOTTOMRIGHT); ge_cairo_set_color (cr, &shadow); cairo_stroke (cr); } - -/* ge_cairo_rounded_rectangle (cr, 1.5,1.5, width-2, height-2, radius, CR_CORNER_ALL);*/ -/* cairo_set_source_rgba (cr, colors->spot[0].r, colors->spot[0].g, colors->spot[0].b, 1);*/ -/* cairo_stroke (cr);*/ - - params->style_functions->draw_top_left_highlight (cr, &colors->spot[1], params, 1.5, 1.5, - width - 1, height - 1, - radius, params->corners); - - border = colors->spot[2]; - border.a = 0.6; - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, CR_CORNER_ALL); - ge_cairo_set_color (cr, &border); - cairo_stroke (cr); - + cairo_restore (cr); cairo_restore (cr); /* rotation, mirroring */ @@ -920,10 +903,10 @@ clearlooks_draw_optionmenu (cairo_t *cr, int x, int y, int width, int height) { SeparatorParameters separator; - int offset = params->ythickness + 2; - + int offset = params->ythickness + 1; + params->style_functions->draw_button (cr, colors, params, x, y, width, height); - + separator.horizontal = FALSE; params->style_functions->draw_separator (cr, colors, params, &separator, x+optionmenu->linepos, y + offset, 2, height - offset*2); } @@ -956,19 +939,21 @@ clearlooks_draw_menubar0 (cairo_t *cr, const MenuBarParameters *menubar, int x, int y, int width, int height) { +/* const CairoColor *light = &colors->shade[0]; */ const CairoColor *dark = &colors->shade[3]; - cairo_save (cr); - cairo_set_line_width (cr, 1); - cairo_translate (cr, x, y); + cairo_translate (cr, x, y+0.5); - cairo_move_to (cr, 0, height-0.5); - cairo_line_to (cr, width, height-0.5); +/* cairo_move_to (cr, 0, 0); */ +/* cairo_line_to (cr, width, 0); */ +/* ge_cairo_set_color (cr, light); */ +/* cairo_stroke (cr); */ + + cairo_move_to (cr, 0, height-1); + cairo_line_to (cr, width, height-1); ge_cairo_set_color (cr, dark); cairo_stroke (cr); - - cairo_restore (cr); } static void @@ -981,13 +966,11 @@ clearlooks_draw_menubar2 (cairo_t *cr, CairoColor lower; cairo_pattern_t *pattern; - cairo_save (cr); - ge_shade_color (&colors->bg[0], 0.96, &lower); - + cairo_translate (cr, x, y); cairo_rectangle (cr, 0, 0, width, height); - + /* Draw the gradient */ pattern = cairo_pattern_create_linear (0, 0, 0, height); cairo_pattern_add_color_stop_rgb (pattern, 0.0, colors->bg[0].r, @@ -999,15 +982,13 @@ clearlooks_draw_menubar2 (cairo_t *cr, cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - + /* Draw bottom line */ cairo_set_line_width (cr, 1.0); cairo_move_to (cr, 0, height-0.5); cairo_line_to (cr, width, height-0.5); ge_cairo_set_color (cr, &colors->shade[3]); cairo_stroke (cr); - - cairo_restore (cr); } static void @@ -1028,10 +1009,10 @@ clearlooks_draw_menubar1 (cairo_t *cr, static menubar_draw_proto clearlooks_menubar_draw[3] = -{ - clearlooks_draw_menubar0, +{ + clearlooks_draw_menubar0, clearlooks_draw_menubar1, - clearlooks_draw_menubar2 + clearlooks_draw_menubar2 }; static void @@ -1041,7 +1022,7 @@ clearlooks_draw_menubar (cairo_t *cr, const MenuBarParameters *menubar, int x, int y, int width, int height) { - if (menubar->style < 0 || menubar->style >= G_N_ELEMENTS (clearlooks_menubar_draw)) + if (menubar->style < 0 || menubar->style > 3) return; clearlooks_menubar_draw[menubar->style](cr, colors, params, menubar, @@ -1049,38 +1030,38 @@ clearlooks_draw_menubar (cairo_t *cr, } static void -clearlooks_get_frame_gap_clip (int x, int y, int width, int height, +clearlooks_get_frame_gap_clip (int x, int y, int width, int height, const FrameParameters *frame, ClearlooksRectangle *bevel, ClearlooksRectangle *border) { if (frame->gap_side == CL_GAP_TOP) { - CLEARLOOKS_RECTANGLE_SET (*bevel, 2.0 + frame->gap_x, 0.0, - frame->gap_width - 3, 2.0); - CLEARLOOKS_RECTANGLE_SET (*border, 1.0 + frame->gap_x, 0.0, - frame->gap_width - 2, 2.0); + CLEARLOOKS_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, -0.5, + frame->gap_width - 3, 2.0); + CLEARLOOKS_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, -0.5, + frame->gap_width - 2, 2.0); } else if (frame->gap_side == CL_GAP_BOTTOM) { - CLEARLOOKS_RECTANGLE_SET (*bevel, 2.0 + frame->gap_x, height - 2.0, - frame->gap_width - 3, 2.0); - CLEARLOOKS_RECTANGLE_SET (*border, 1.0 + frame->gap_x, height - 1.0, - frame->gap_width - 2, 2.0); + CLEARLOOKS_RECTANGLE_SET ((*bevel), 1.5 + frame->gap_x, height - 2.5, + frame->gap_width - 3, 2.0); + CLEARLOOKS_RECTANGLE_SET ((*border), 0.5 + frame->gap_x, height - 1.5, + frame->gap_width - 2, 2.0); } else if (frame->gap_side == CL_GAP_LEFT) { - CLEARLOOKS_RECTANGLE_SET (*bevel, 0.0, 2.0 + frame->gap_x, - 2.0, frame->gap_width - 3); - CLEARLOOKS_RECTANGLE_SET (*border, 0.0, 1.0 + frame->gap_x, - 1.0, frame->gap_width - 2); + CLEARLOOKS_RECTANGLE_SET ((*bevel), -0.5, 1.5 + frame->gap_x, + 2.0, frame->gap_width - 3); + CLEARLOOKS_RECTANGLE_SET ((*border), -0.5, 0.5 + frame->gap_x, + 1.0, frame->gap_width - 2); } else if (frame->gap_side == CL_GAP_RIGHT) { - CLEARLOOKS_RECTANGLE_SET (*bevel, width - 2.0, 2.0 + frame->gap_x, - 2.0, frame->gap_width - 3); - CLEARLOOKS_RECTANGLE_SET (*border, width - 1.0, 1.0 + frame->gap_x, - 1.0, frame->gap_width - 2); + CLEARLOOKS_RECTANGLE_SET ((*bevel), width - 2.5, 1.5 + frame->gap_x, + 2.0, frame->gap_width - 3); + CLEARLOOKS_RECTANGLE_SET ((*border), width - 1.5, 0.5 + frame->gap_x, + 1.0, frame->gap_width - 2); } } @@ -1098,18 +1079,18 @@ clearlooks_draw_frame (cairo_t *cr, double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); CairoColor hilight; - ge_shade_color (&colors->bg[0], 1.05, &hilight); - + ge_shade_color (&colors->bg[GTK_STATE_NORMAL], 1.05, &hilight); + if (frame->shadow == CL_SHADOW_NONE) return; - + if (frame->gap_x != -1) clearlooks_get_frame_gap_clip (x, y, width, height, frame, &bevel_clip, &frame_clip); - + cairo_set_line_width (cr, 1.0); - cairo_translate (cr, x, y); - + cairo_translate (cr, x+0.5, y+0.5); + /* save everything */ cairo_save (cr); /* Set clip for the bevel */ @@ -1117,19 +1098,19 @@ clearlooks_draw_frame (cairo_t *cr, { /* Set clip for gap */ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_rectangle (cr, 0, 0, width, height); + cairo_rectangle (cr, -0.5, -0.5, width, height); cairo_rectangle (cr, bevel_clip.x, bevel_clip.y, bevel_clip.width, bevel_clip.height); cairo_clip (cr); } - + /* Draw the bevel */ if (frame->shadow == CL_SHADOW_ETCHED_IN || frame->shadow == CL_SHADOW_ETCHED_OUT) { ge_cairo_set_color (cr, &hilight); if (frame->shadow == CL_SHADOW_ETCHED_IN) - ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, params->corners); else - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-2, height-2, radius, params->corners); cairo_stroke (cr); } else if (frame->shadow != CL_SHADOW_NONE) @@ -1137,9 +1118,9 @@ clearlooks_draw_frame (cairo_t *cr, ShadowParameters shadow; shadow.corners = params->corners; shadow.shadow = frame->shadow; - clearlooks_draw_highlight_and_shade (cr, colors, &shadow, width, height, radius); + clearlooks_draw_highlight_and_shade (cr, colors, &shadow, width, height, 0); } - + /* restore the previous clip region */ cairo_restore (cr); cairo_save (cr); @@ -1147,7 +1128,7 @@ clearlooks_draw_frame (cairo_t *cr, { /* Set clip for gap */ cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD); - cairo_rectangle (cr, 0, 0, width, height); + cairo_rectangle (cr, -0.5, -0.5, width, height); cairo_rectangle (cr, frame_clip.x, frame_clip.y, frame_clip.width, frame_clip.height); cairo_clip (cr); } @@ -1157,14 +1138,14 @@ clearlooks_draw_frame (cairo_t *cr, { ge_cairo_set_color (cr, dark); if (frame->shadow == CL_SHADOW_ETCHED_IN) - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-2, height-2, radius, params->corners); else - ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, params->corners); } else { ge_cairo_set_color (cr, border); - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); } cairo_stroke (cr); @@ -1178,32 +1159,28 @@ clearlooks_draw_tab (cairo_t *cr, const TabParameters *tab, int x, int y, int width, int height) { - const CairoColor *border1 = &colors->shade[6]; - const CairoColor *border2 = &colors->shade[5]; - const CairoColor *stripe_fill = &colors->spot[1]; - const CairoColor *stripe_border = &colors->spot[2]; - const CairoColor *fill; - CairoColor hilight; - - cairo_pattern_t *pattern; - - double radius; - double stripe_size = 2.0; - double stripe_fill_size; - double length; + const CairoColor *border1 = &colors->shade[6]; + const CairoColor *border2 = &colors->shade[5]; + const CairoColor *stripe_fill = &colors->spot[1]; + const CairoColor *stripe_border = &colors->spot[2]; + const CairoColor *fill; + CairoColor hilight; + + cairo_pattern_t *pattern; + + double radius; + double strip_size; radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); - cairo_save (cr); - /* Set clip */ cairo_rectangle (cr, x, y, width, height); cairo_clip (cr); cairo_new_path (cr); - /* Translate and set line width */ + /* Translate and set line width */ cairo_set_line_width (cr, 1.0); - cairo_translate (cr, x, y); + cairo_translate (cr, x+0.5, y+0.5); /* Make the tabs slightly bigger than they should be, to create a gap */ @@ -1211,29 +1188,27 @@ clearlooks_draw_tab (cairo_t *cr, if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) { height += 3.0; - length = height; - stripe_fill_size = (tab->gap_side == CL_GAP_TOP ? stripe_size/height : stripe_size/(height-2)); - + strip_size = 2.0/height; /* 2 pixel high strip */ + if (tab->gap_side == CL_GAP_TOP) cairo_translate (cr, 0.0, -3.0); /* gap at the other side */ } else { width += 3.0; - length = width; - stripe_fill_size = (tab->gap_side == CL_GAP_LEFT ? stripe_size/width : stripe_size/(width-2)); - - if (tab->gap_side == CL_GAP_LEFT) + strip_size = 2.0/width; + + if (tab->gap_side == CL_GAP_LEFT) cairo_translate (cr, -3.0, 0.0); /* gap at the other side */ } - + /* Set the fill color */ fill = &colors->bg[params->state_type]; /* Set tab shape */ - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); - + /* Draw fill */ ge_cairo_set_color (cr, fill); cairo_fill (cr); @@ -1245,45 +1220,32 @@ clearlooks_draw_tab (cairo_t *cr, if (!params->active) { ShadowParameters shadow; - + shadow.shadow = CL_SHADOW_OUT; shadow.corners = params->corners; - + clearlooks_draw_highlight_and_shade (cr, colors, &shadow, width, height, radius); } - + if (params->active) { CairoColor shadow; - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0.5, height-1.5, 0.5, 0.5); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0.5, 1.5, 0.5, height+0.5); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-1.5, 0.5, 1.5, 0.5); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (1.5, 0.5, width-1.5, 0.5); - break; - default: - pattern = NULL; - } - - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners); + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + ge_shade_color (fill, 0.92, &shadow); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, hilight.r, hilight.g, hilight.b, 0.4); - cairo_pattern_add_color_stop_rgba (pattern, 1.0/length, hilight.r, hilight.g, hilight.b, 0.4); - cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, fill->r,fill->g,fill->b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r,shadow.g,shadow.b); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, hilight.r, hilight.g, hilight.b, 0.4); + cairo_pattern_add_color_stop_rgba (pattern, 1.0/height, hilight.r, hilight.g, hilight.b, 0.4); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, fill->r,fill->g,fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r,shadow.g,shadow.b); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); @@ -1291,37 +1253,25 @@ clearlooks_draw_tab (cairo_t *cr, else { /* Draw shade */ - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0.5, height-1.5, 0.5, 0.5); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, height+0.5); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-1.5, 0.5, 0.5, 0.5); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (0.5, 0.5, width+0.5, 0.5); - break; - default: - pattern = NULL; - } - - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners); + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b); - cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, stripe_fill->r, stripe_fill->g, stripe_fill->b); - cairo_pattern_add_color_stop_rgba (pattern, stripe_fill_size, hilight.r, hilight.g, hilight.b, 0.5); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_fill->r, stripe_fill->g, stripe_fill->b); + cairo_pattern_add_color_stop_rgba (pattern, strip_size, hilight.r, hilight.g, hilight.b, 0.5); cairo_pattern_add_color_stop_rgba (pattern, 0.8, hilight.r, hilight.g, hilight.b, 0.0); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners); - + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + if (params->active) { ge_cairo_set_color (cr, border2); @@ -1329,34 +1279,19 @@ clearlooks_draw_tab (cairo_t *cr, } else { - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (2.5, height-1.5, 2.5, 2.5); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (2.5, 2.5, 2.5, height+0.5); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-1.5, 2.5, 2.5, 2.5); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (2.5, 2.5, width+0.5, 2.5); - break; - default: - pattern = NULL; - } - + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2 ); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); - cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, stripe_border->r, stripe_border->g, stripe_border->b); - cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, border1->r, border1->g, border1->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b); + cairo_pattern_add_color_stop_rgb (pattern, strip_size, border1->r, border1->g, border1->b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, border2->r, border2->g, border2->b); cairo_set_source (cr, pattern); cairo_stroke (cr); cairo_pattern_destroy (pattern); } - - cairo_restore (cr); } static void @@ -1366,9 +1301,9 @@ clearlooks_draw_separator (cairo_t *cr, const SeparatorParameters *separator, int x, int y, int width, int height) { - CairoColor color = colors->shade[2]; - CairoColor hilight; - ge_shade_color (&colors->bg[0], 1.065, &hilight); + CairoColor color = colors->shade[3]; + CairoColor hilight; + ge_shade_color (&color, 1.4, &hilight); cairo_save (cr); cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); @@ -1377,12 +1312,12 @@ clearlooks_draw_separator (cairo_t *cr, { cairo_set_line_width (cr, 1.0); cairo_translate (cr, x, y+0.5); - + cairo_move_to (cr, 0.0, 0.0); cairo_line_to (cr, width, 0.0); ge_cairo_set_color (cr, &color); cairo_stroke (cr); - + cairo_move_to (cr, 0.0, 1.0); cairo_line_to (cr, width, 1.0); ge_cairo_set_color (cr, &hilight); @@ -1392,12 +1327,12 @@ clearlooks_draw_separator (cairo_t *cr, { cairo_set_line_width (cr, 1.0); cairo_translate (cr, x+0.5, y); - + cairo_move_to (cr, 0.0, 0.0); cairo_line_to (cr, 0.0, height); ge_cairo_set_color (cr, &color); cairo_stroke (cr); - + cairo_move_to (cr, 1.0, 0.0); cairo_line_to (cr, 1.0, height); ge_cairo_set_color (cr, &hilight); @@ -1414,43 +1349,54 @@ clearlooks_draw_list_view_header (cairo_t *cr, const ListViewHeaderParameters *header, int x, int y, int width, int height) { - const CairoColor *border = &colors->shade[4]; - CairoColor hilight; + const CairoColor *border = &colors->shade[5]; + cairo_pattern_t *pattern; + CairoColor hilight; + CairoColor shadow; - ge_shade_color (&colors->bg[params->state_type], - params->style_constants->topleft_highlight_shade, &hilight); - hilight.a = params->style_constants->topleft_highlight_alpha; + ge_shade_color (border, 1.5, &hilight); + ge_shade_color (border, 0.925, &shadow); cairo_translate (cr, x, y); cairo_set_line_width (cr, 1.0); - + /* Draw highlight */ - if (header->order & CL_ORDER_FIRST) + if (header->order == CL_ORDER_FIRST) { cairo_move_to (cr, 0.5, height-1); cairo_line_to (cr, 0.5, 0.5); } else cairo_move_to (cr, 0.0, 0.5); - + cairo_line_to (cr, width, 0.5); - + ge_cairo_set_color (cr, &hilight); cairo_stroke (cr); - + /* Draw bottom border */ cairo_move_to (cr, 0.0, height-0.5); cairo_line_to (cr, width, height-0.5); ge_cairo_set_color (cr, border); cairo_stroke (cr); + /* Draw bottom shade */ + pattern = cairo_pattern_create_linear (0.0, height-5.0, 0.0, height-1.0); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, shadow.r, shadow.g, shadow.b, 0.0); + cairo_pattern_add_color_stop_rgba (pattern, 1.0, shadow.r, shadow.g, shadow.b, 0.3); + + cairo_rectangle (cr, 0.0, height-5.0, width, 4.0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + /* Draw resize grip */ - if ((params->ltr && !(header->order & CL_ORDER_LAST)) || - (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable) + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) { SeparatorParameters separator; separator.horizontal = FALSE; - + if (params->ltr) params->style_functions->draw_separator (cr, colors, params, &separator, width-1.5, 4.0, 2, height-8.0); @@ -1469,18 +1415,18 @@ clearlooks_draw_toolbar (cairo_t *cr, const ToolbarParameters *toolbar, int x, int y, int width, int height) { - const CairoColor *fill = &colors->bg[0]; + const CairoColor *fill = &colors->bg[GTK_STATE_NORMAL]; const CairoColor *dark = &colors->shade[3]; CairoColor light; - ge_shade_color (fill, 1.065, &light); - + ge_shade_color (fill, 1.1, &light); + cairo_set_line_width (cr, 1.0); cairo_translate (cr, x, y); ge_cairo_set_color (cr, fill); cairo_paint (cr); - if (!toolbar->topmost) + if (!toolbar->topmost) { /* Draw highlight */ cairo_move_to (cr, 0, 0.5); @@ -1535,10 +1481,10 @@ clearlooks_draw_menubaritem (cairo_t *cr, CairoColor fill_shade; CairoColor border = colors->spot[2]; cairo_pattern_t *pattern; - + ge_shade_color (&border, 1.05, &border); ge_shade_color (fill, 0.85, &fill_shade); - + cairo_set_line_width (cr, 1.0); ge_cairo_rounded_rectangle (cr, x + 0.5, y + 0.5, width - 1, height, widget->radius, widget->corners); @@ -1562,9 +1508,10 @@ clearlooks_draw_selected_cell (cairo_t *cr, { CairoColor upper_color; CairoColor lower_color; + CairoColor border; cairo_pattern_t *pattern; cairo_save (cr); - + cairo_translate (cr, x, y); if (params->focus) @@ -1587,6 +1534,16 @@ clearlooks_draw_selected_cell (cairo_t *cr, cairo_fill (cr); cairo_pattern_destroy (pattern); + + ge_shade_color(&upper_color, 0.8, &border); + + cairo_move_to (cr, 0, 0.5); + cairo_rel_line_to (cr, width, 0); + cairo_move_to (cr, 0, height-0.5); + cairo_rel_line_to (cr, width, 0); + + ge_cairo_set_color (cr, &border); + cairo_stroke (cr); cairo_restore (cr); } @@ -1603,44 +1560,34 @@ clearlooks_draw_scrollbar_trough (cairo_t *cr, const CairoColor *border = &colors->shade[5]; CairoColor bg_shade; cairo_pattern_t *pattern; - double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); - + ge_shade_color (bg, 0.95, &bg_shade); - + cairo_set_line_width (cr, 1); /* cairo_translate (cr, x, y); */ - + if (scrollbar->horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); - cairo_translate (cr, x, y); + cairo_translate (cr, x, y); /* Draw fill */ - if (radius > 3.0) - ge_cairo_rounded_rectangle (cr, 1, 0, width-2, height, - radius, widget->corners); - else - cairo_rectangle (cr, 1, 0, width-2, height); + cairo_rectangle (cr, 1, 0, width-2, height); ge_cairo_set_color (cr, bg); cairo_fill (cr); /* Draw shadow */ pattern = cairo_pattern_create_linear (1, 0, 3, 0); cairo_pattern_add_color_stop_rgb (pattern, 0, bg_shade.r, bg_shade.g, bg_shade.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg->r, bg->g, bg->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, bg->r, bg->g, bg->b); cairo_rectangle (cr, 1, 0, 4, height); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - + /* Draw border */ - if (radius > 3.0) - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, - radius, widget->corners); - else - cairo_rectangle (cr, 0.5, 0.5, width-1, height-1); ge_cairo_set_color (cr, border); - cairo_stroke (cr); + ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); } static void @@ -1655,10 +1602,11 @@ clearlooks_draw_scrollbar_stepper (cairo_t *cr, CairoColor border; CairoColor s1, s2, s3, s4; cairo_pattern_t *pattern; + ShadowParameters shadow; double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); - ge_shade_color(&colors->shade[6], 1.08, &border); - + ge_shade_color(&colors->shade[6], 1.05, &border); + if (scrollbar->horizontal) { if (stepper->stepper == CL_STEPPER_A) @@ -1673,35 +1621,45 @@ clearlooks_draw_scrollbar_stepper (cairo_t *cr, else if (stepper->stepper == CL_STEPPER_D) corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; } - + cairo_translate (cr, x, y); cairo_set_line_width (cr, 1); - + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, corners); - + if (scrollbar->horizontal) pattern = cairo_pattern_create_linear (0, 0, 0, height); else pattern = cairo_pattern_create_linear (0, 0, width, 0); - - ge_shade_color (&colors->bg[widget->state_type], SHADE_TOP, &s1); - ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_TOP, &s2); - ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_BOTTOM, &s3); - ge_shade_color (&colors->bg[widget->state_type], SHADE_BOTTOM, &s4); - - cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b); - cairo_pattern_add_color_stop_rgb(pattern, 0.3, s2.r, s2.g, s2.b); - cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b); - cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b); + + s2 = colors->bg[widget->state_type]; + ge_shade_color(&s2, 1.06, &s1); + ge_shade_color(&s2, 0.98, &s3); + ge_shade_color(&s2, 0.94, &s4); + + cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - - widget->style_functions->draw_top_left_highlight (cr, &s2, widget, 1, 1, width - 2, height - 2, MAX(radius - 1, 0), corners); - - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, corners); - clearlooks_set_border_gradient (cr, &border, 1.1, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0)); + + cairo_translate (cr, 0.5, 0.5); + clearlooks_draw_top_left_highlight (cr, &s2, widget, width, height, (stepper->stepper == CL_STEPPER_A) ? radius : 0); + cairo_translate (cr, -0.5, -0.5); + + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); + clearlooks_set_border_gradient (cr, &border, 1.2, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0)); cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; + /* + clearlooks_draw_highlight_and_shade (cr, &shadow, + width, + height, params->radius);*/ } static void @@ -1711,8 +1669,6 @@ clearlooks_draw_scrollbar_slider (cairo_t *cr, const ScrollBarParameters *scrollbar, int x, int y, int width, int height) { - cairo_save (cr); - if (scrollbar->junction & CL_JUNCTION_BEGIN) { if (scrollbar->horizontal) @@ -1733,11 +1689,11 @@ clearlooks_draw_scrollbar_slider (cairo_t *cr, else height += 1; } - + if (!scrollbar->horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); - cairo_translate (cr, x, y); + cairo_translate (cr, x, y); if (scrollbar->has_color) { @@ -1749,27 +1705,27 @@ clearlooks_draw_scrollbar_slider (cairo_t *cr, if (widget->prelight) ge_shade_color (&fill, 1.1, &fill); - + cairo_set_line_width (cr, 1); - + ge_shade_color (&fill, 1.3, &hilight); ge_shade_color (&fill, 1.1, &shade1); ge_shade_color (&fill, 1.05, &shade2); ge_shade_color (&fill, 0.98, &shade3); - + pattern = cairo_pattern_create_linear (1, 1, 1, height-2); cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade3.r, shade3.g, shade3.b); cairo_pattern_add_color_stop_rgb (pattern, 1, fill.r, fill.g, fill.b); cairo_rectangle (cr, 1, 1, width-2, height-2); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.5); ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); - + ge_cairo_set_color (cr, border); ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); } @@ -1782,15 +1738,16 @@ clearlooks_draw_scrollbar_slider (cairo_t *cr, cairo_pattern_t *pattern; int bar_x, i; - ge_shade_color (&colors->shade[6], 1.08, &border); - ge_shade_color (&colors->bg[widget->state_type], SHADE_TOP, &s1); - ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_TOP, &s2); - ge_shade_color (&colors->bg[widget->state_type], SHADE_CENTER_BOTTOM, &s3); - ge_shade_color (&colors->bg[widget->state_type], SHADE_BOTTOM, &s4); - + ge_shade_color(&colors->shade[6], 1.05, &border); + + s2 = colors->bg[widget->state_type]; + ge_shade_color(&s2, 1.06, &s1); + ge_shade_color(&s2, 0.98, &s3); + ge_shade_color(&s2, 0.94, &s4); + pattern = cairo_pattern_create_linear(1, 1, 1, height-1); cairo_pattern_add_color_stop_rgb(pattern, 0, s1.r, s1.g, s1.b); - cairo_pattern_add_color_stop_rgb(pattern, 0.3, s2.r, s2.g, s2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, s2.r, s2.g, s2.b); cairo_pattern_add_color_stop_rgb(pattern, 0.7, s3.r, s3.g, s3.b); cairo_pattern_add_color_stop_rgb(pattern, 1.0, s4.r, s4.g, s4.b); @@ -1798,41 +1755,38 @@ clearlooks_draw_scrollbar_slider (cairo_t *cr, cairo_set_source(cr, pattern); cairo_fill(cr); cairo_pattern_destroy(pattern); - - clearlooks_set_border_gradient (cr, &border, 1.1, 0, height); + + clearlooks_set_border_gradient (cr, &border, 1.2, 0, height); ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); - + cairo_move_to (cr, 1.5, height-1.5); cairo_line_to (cr, 1.5, 1.5); cairo_line_to (cr, width-1.5, 1.5); - ge_shade_color (&s2, widget->style_constants->topleft_highlight_shade, &s5); - s5.a = widget->style_constants->topleft_highlight_alpha; - ge_cairo_set_color (cr, &s5); + ge_shade_color (&s2, 1.3, &s5); + cairo_set_source_rgba (cr, s5.r, s5.g, s5.b, 0.5); cairo_stroke(cr); - + /* draw handles */ cairo_set_line_width (cr, 1); - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - + bar_x = width/2 - 4; - + cairo_translate(cr, 0.5, 0.5); for (i=0; i<3; i++) { - cairo_move_to (cr, bar_x + 0.5, 4); - cairo_line_to (cr, bar_x + 0.5, height-4); + cairo_move_to (cr, bar_x, 4); + cairo_line_to (cr, bar_x, height-5); ge_cairo_set_color (cr, dark); cairo_stroke (cr); - - cairo_move_to (cr, bar_x+1.5, 4); - cairo_line_to (cr, bar_x+1.5, height-4); + + cairo_move_to (cr, bar_x+1, 4); + cairo_line_to (cr, bar_x+1, height-5); ge_cairo_set_color (cr, light); cairo_stroke (cr); - + bar_x += 3; } } - - cairo_restore (cr); + } static void @@ -1850,7 +1804,7 @@ clearlooks_draw_statusbar (cairo_t *cr, cairo_translate (cr, x, y+0.5); cairo_move_to (cr, 0, 0); cairo_line_to (cr, width, 0); - ge_cairo_set_color (cr, dark); + ge_cairo_set_color (cr, dark); cairo_stroke (cr); cairo_translate (cr, 0, 1); @@ -1869,7 +1823,11 @@ clearlooks_draw_menu_frame (cairo_t *cr, const CairoColor *border = &colors->shade[5]; cairo_translate (cr, x, y); cairo_set_line_width (cr, 1); - +/* + cairo_set_source_rgba (cr, colors->bg[0].r, colors->bg[0].g, colors->bg[0].b, 0.9); + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + cairo_paint (cr); +*/ ge_cairo_set_color (cr, border); ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); } @@ -1908,16 +1866,17 @@ clearlooks_draw_handle (cairo_t *cr, { const CairoColor *fill = &colors->bg[params->state_type]; int num_bars = 6; /* shut up gcc warnings */ - - cairo_save (cr); - + int bar_spacing; + switch (handle->type) { case CL_HANDLE_TOOLBAR: num_bars = 6; + bar_spacing = 3; break; case CL_HANDLE_SPLITTER: num_bars = 16; + bar_spacing = 3; break; } @@ -1927,11 +1886,11 @@ clearlooks_draw_handle (cairo_t *cr, ge_cairo_set_color (cr, fill); cairo_fill (cr); } - - cairo_translate (cr, x, y); - + + cairo_translate (cr, x+0.5, y+0.5); + cairo_set_line_width (cr, 1); - + if (handle->horizontal) { params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, num_bars, 2, 0.1); @@ -1940,8 +1899,6 @@ clearlooks_draw_handle (cairo_t *cr, { params->style_functions->draw_gripdots (cr, colors, 0, 0, width, height, 2, num_bars, 0.1); } - - cairo_restore (cr); } static void @@ -1957,7 +1914,7 @@ clearlooks_draw_resize_grip (cairo_t *cr, int x_down; int y_down; int dots; - + ge_shade_color (dark, 1.5, &hilight); /* The number of dots fitting into the area. Just hardcoded to 4 right now. */ @@ -2028,13 +1985,6 @@ clearlooks_draw_radiobutton (cairo_t *cr, cairo_pattern_t *pt; gboolean inconsistent; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); - gdouble w, h, cx, cy, radius; - - w = (gdouble) width; - h = (gdouble) height; - cx = width / 2.0; - cy = height / 2.0; - radius = MIN (width, height) / 2.0; inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; @@ -2053,53 +2003,53 @@ clearlooks_draw_radiobutton (cairo_t *cr, ge_shade_color (&widget->parentbg, 0.9, &shadow); ge_shade_color (&widget->parentbg, 1.1, &highlight); - pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0); + pt = cairo_pattern_create_linear (0, 0, 13, 13); cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); cairo_pattern_add_color_stop_rgb (pt, 1.0, highlight.r, highlight.g, highlight.b); - + cairo_translate (cr, x, y); - - cairo_set_line_width (cr, MAX (1.0, floor (radius/3))); - cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2); + + cairo_set_line_width (cr, 2); + cairo_arc (cr, 7, 7, 6, 0, G_PI*2); cairo_set_source (cr, pt); cairo_stroke (cr); cairo_pattern_destroy (pt); - cairo_set_line_width (cr, MAX (1.0, floor (radius/6))); - - cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2); + cairo_set_line_width (cr, 1); + cairo_arc (cr, 7, 7, 5.5, 0, G_PI*2); + if (!widget->disabled) { ge_cairo_set_color (cr, &colors->base[0]); cairo_fill_preserve (cr); } - + ge_cairo_set_color (cr, border); cairo_stroke (cr); - + if (draw_bullet) { if (inconsistent) { cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width (cr, ceil (radius * 2 / 3)); + cairo_set_line_width (cr, 4); - cairo_move_to (cr, ceil (cx - radius/3.0), ceil (cy)); - cairo_line_to (cr, ceil (cx + radius/3.0), ceil (cy)); + cairo_move_to(cr, 5, 7); + cairo_line_to(cr, 9, 7); ge_cairo_set_color (cr, dot); cairo_stroke (cr); } else { - cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2); + cairo_arc (cr, 7, 7, 3, 0, G_PI*2); ge_cairo_set_color (cr, dot); cairo_fill (cr); - - cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2); + + cairo_arc (cr, 6, 6, 1, 0, G_PI*2); cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); cairo_fill (cr); } @@ -2120,7 +2070,7 @@ clearlooks_draw_checkbox (cairo_t *cr, inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; - + if (widget->disabled) { border = &colors->shade[5]; @@ -2134,11 +2084,11 @@ clearlooks_draw_checkbox (cairo_t *cr, cairo_translate (cr, x, y); cairo_set_line_width (cr, 1); - + if (widget->xthickness > 2 && widget->ythickness > 2) { - widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0, width, height, 1, CR_CORNER_ALL); - + widget->style_functions->draw_inset (cr, &widget->parentbg, 0.5, 0.5, width-1, height-1, 1, CR_CORNER_ALL); + /* Draw the rectangle for the checkbox itself */ ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); } @@ -2147,13 +2097,13 @@ clearlooks_draw_checkbox (cairo_t *cr, /* Draw the rectangle for the checkbox itself */ ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); } - + if (!widget->disabled) { ge_cairo_set_color (cr, &colors->base[0]); cairo_fill_preserve (cr); } - + ge_cairo_set_color (cr, border); cairo_stroke (cr); @@ -2170,13 +2120,13 @@ clearlooks_draw_checkbox (cairo_t *cr, cairo_set_line_width (cr, 1.7); cairo_move_to (cr, 0.5 + (width*0.2), (height*0.5)); cairo_line_to (cr, 0.5 + (width*0.4), (height*0.7)); - + cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7), 0.5 + (width*0.5), (height*0.4), 0.5 + (width*0.70), (height*0.25)); } - + ge_cairo_set_color (cr, dot); cairo_stroke (cr); } @@ -2195,7 +2145,7 @@ clearlooks_draw_normal_arrow (cairo_t *cr, const CairoColor *color, arrow_width = MIN (height * 2.0 + MAX (1.0, ceil (height * 2.0 / 6.0 * 2.0) / 2.0) / 2.0, width); line_width_2 = MAX (1.0, ceil (arrow_width / 6.0 * 2.0) / 2.0) / 2.0; arrow_height = arrow_width / 2.0 + line_width_2; - + cairo_translate (cr, x, y - arrow_height / 2.0); cairo_move_to (cr, -arrow_width / 2.0, line_width_2); @@ -2206,10 +2156,10 @@ clearlooks_draw_normal_arrow (cairo_t *cr, const CairoColor *color, cairo_line_to (cr, arrow_width / 2.0, line_width_2); cairo_line_to (cr, 0, arrow_height); cairo_close_path (cr); - + ge_cairo_set_color (cr, color); cairo_fill (cr); - + cairo_restore (cr); } @@ -2220,13 +2170,13 @@ clearlooks_draw_combo_arrow (cairo_t *cr, const CairoColor *color, double arrow_width = MIN (height * 2 / 3.0, width); double arrow_height = arrow_width / 2.0; double gap_size = 1.0 * arrow_height; - + cairo_save (cr); cairo_translate (cr, x, y - (arrow_height + gap_size) / 2.0); cairo_rotate (cr, G_PI); clearlooks_draw_normal_arrow (cr, color, 0, 0, arrow_width, arrow_height); cairo_restore (cr); - + clearlooks_draw_normal_arrow (cr, color, x, y + (arrow_height + gap_size) / 2.0, arrow_width, arrow_height); } @@ -2236,7 +2186,7 @@ _clearlooks_draw_arrow (cairo_t *cr, const CairoColor *color, double x, double y, double width, double height) { double rotate; - + if (dir == CL_DIRECTION_LEFT) rotate = G_PI*1.5; else if (dir == CL_DIRECTION_RIGHT) @@ -2247,11 +2197,11 @@ _clearlooks_draw_arrow (cairo_t *cr, const CairoColor *color, rotate = 0; else return; - + if (type == CL_ARROW_NORMAL) { cairo_translate (cr, x, y); - cairo_rotate (cr, -rotate); + cairo_rotate (cr, -rotate); clearlooks_draw_normal_arrow (cr, color, 0, 0, width, height); } else if (type == CL_ARROW_COMBO) @@ -2263,17 +2213,17 @@ _clearlooks_draw_arrow (cairo_t *cr, const CairoColor *color, static void clearlooks_draw_arrow (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ArrowParameters *arrow, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ArrowParameters *arrow, int x, int y, int width, int height) { const CairoColor *color = &colors->fg[widget->state_type]; gdouble tx, ty; - + tx = x + width/2.0; ty = y + height/2.0; - + if (widget->disabled) { _clearlooks_draw_arrow (cr, &colors->shade[0], @@ -2282,104 +2232,48 @@ clearlooks_draw_arrow (cairo_t *cr, } cairo_identity_matrix (cr); - + _clearlooks_draw_arrow (cr, color, arrow->direction, arrow->type, tx, ty, width, height); } void -clearlooks_draw_focus (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const FocusParameters *focus, - int x, int y, int width, int height) -{ - if (focus->has_color) - ge_cairo_set_color (cr, &focus->color); - else if (focus->type == CL_FOCUS_COLOR_WHEEL_LIGHT) - cairo_set_source_rgb (cr, 0., 0., 0.); - else if (focus->type == CL_FOCUS_COLOR_WHEEL_DARK) - cairo_set_source_rgb (cr, 1., 1., 1.); - else - cairo_set_source_rgba (cr, - colors->fg[widget->state_type].r, - colors->fg[widget->state_type].g, - colors->fg[widget->state_type].b, - 0.7); - - cairo_set_line_width (cr, focus->line_width); - - if (focus->dash_list[0]) - { - gint n_dashes = strlen ((gchar *)focus->dash_list); - gdouble *dashes = g_new (gdouble, n_dashes); - gdouble total_length = 0; - gdouble dash_offset; - gint i; - - for (i = 0; i < n_dashes; i++) - { - dashes[i] = focus->dash_list[i]; - total_length += focus->dash_list[i]; - } - - dash_offset = -focus->line_width / 2.0; - while (dash_offset < 0) - dash_offset += total_length; - - cairo_set_dash (cr, dashes, n_dashes, dash_offset); - g_free (dashes); - } - - cairo_rectangle (cr, - x + focus->line_width / 2.0, - y + focus->line_width / 2.0, - width - focus->line_width, height - focus->line_width); - cairo_stroke (cr); -} - -void -clearlooks_register_style_classic (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants) +clearlooks_register_style_classic (ClearlooksStyleFunctions *functions) { g_assert (functions); - functions->draw_top_left_highlight = clearlooks_draw_top_left_highlight; - functions->draw_button = clearlooks_draw_button; - functions->draw_scale_trough = clearlooks_draw_scale_trough; - functions->draw_progressbar_trough = clearlooks_draw_progressbar_trough; - functions->draw_progressbar_fill = clearlooks_draw_progressbar_fill; - functions->draw_slider_button = clearlooks_draw_slider_button; - functions->draw_entry = clearlooks_draw_entry; - functions->draw_spinbutton = clearlooks_draw_spinbutton; - functions->draw_spinbutton_down = clearlooks_draw_spinbutton_down; - functions->draw_optionmenu = clearlooks_draw_optionmenu; - functions->draw_inset = clearlooks_draw_inset; - functions->draw_menubar = clearlooks_draw_menubar; - functions->draw_tab = clearlooks_draw_tab; - functions->draw_frame = clearlooks_draw_frame; - functions->draw_separator = clearlooks_draw_separator; + functions->draw_button = clearlooks_draw_button; + functions->draw_scale_trough = clearlooks_draw_scale_trough; + functions->draw_progressbar_trough = clearlooks_draw_progressbar_trough; + functions->draw_progressbar_fill = clearlooks_draw_progressbar_fill; + functions->draw_slider_button = clearlooks_draw_slider_button; + functions->draw_entry = clearlooks_draw_entry; + functions->draw_spinbutton = clearlooks_draw_spinbutton; + functions->draw_spinbutton_down = clearlooks_draw_spinbutton_down; + functions->draw_optionmenu = clearlooks_draw_optionmenu; + functions->draw_inset = clearlooks_draw_inset; + functions->draw_menubar = clearlooks_draw_menubar; + functions->draw_tab = clearlooks_draw_tab; + functions->draw_frame = clearlooks_draw_frame; + functions->draw_separator = clearlooks_draw_separator; functions->draw_menu_item_separator = clearlooks_draw_menu_item_separator; - functions->draw_list_view_header = clearlooks_draw_list_view_header; - functions->draw_toolbar = clearlooks_draw_toolbar; - functions->draw_menuitem = clearlooks_draw_menuitem; - functions->draw_menubaritem = clearlooks_draw_menubaritem; - functions->draw_selected_cell = clearlooks_draw_selected_cell; - functions->draw_scrollbar_stepper = clearlooks_draw_scrollbar_stepper; - functions->draw_scrollbar_slider = clearlooks_draw_scrollbar_slider; - functions->draw_scrollbar_trough = clearlooks_draw_scrollbar_trough; - functions->draw_statusbar = clearlooks_draw_statusbar; - functions->draw_menu_frame = clearlooks_draw_menu_frame; - functions->draw_tooltip = clearlooks_draw_tooltip; - functions->draw_handle = clearlooks_draw_handle; - functions->draw_resize_grip = clearlooks_draw_resize_grip; - functions->draw_arrow = clearlooks_draw_arrow; - functions->draw_focus = clearlooks_draw_focus; - functions->draw_checkbox = clearlooks_draw_checkbox; - functions->draw_radiobutton = clearlooks_draw_radiobutton; - functions->draw_shadow = clearlooks_draw_shadow; - functions->draw_slider = clearlooks_draw_slider; - functions->draw_gripdots = clearlooks_draw_gripdots; - - constants->topleft_highlight_shade = 1.3; - constants->topleft_highlight_alpha = 0.6; + functions->draw_list_view_header = clearlooks_draw_list_view_header; + functions->draw_toolbar = clearlooks_draw_toolbar; + functions->draw_menuitem = clearlooks_draw_menuitem; + functions->draw_menubaritem = clearlooks_draw_menubaritem; + functions->draw_selected_cell = clearlooks_draw_selected_cell; + functions->draw_scrollbar_stepper = clearlooks_draw_scrollbar_stepper; + functions->draw_scrollbar_slider = clearlooks_draw_scrollbar_slider; + functions->draw_scrollbar_trough = clearlooks_draw_scrollbar_trough; + functions->draw_statusbar = clearlooks_draw_statusbar; + functions->draw_menu_frame = clearlooks_draw_menu_frame; + functions->draw_tooltip = clearlooks_draw_tooltip; + functions->draw_handle = clearlooks_draw_handle; + functions->draw_resize_grip = clearlooks_draw_resize_grip; + functions->draw_arrow = clearlooks_draw_arrow; + functions->draw_checkbox = clearlooks_draw_checkbox; + functions->draw_radiobutton = clearlooks_draw_radiobutton; + functions->draw_shadow = clearlooks_draw_shadow; + functions->draw_slider = clearlooks_draw_slider; + functions->draw_gripdots = clearlooks_draw_gripdots; } diff --git a/libs/clearlooks-newer/clearlooks_draw.h b/libs/clearlooks-newer/clearlooks_draw.h new file mode 100644 index 0000000000..a3f26764da --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_draw.h @@ -0,0 +1,17 @@ +#ifndef CLEARLOOKS_DRAW_H +#define CLEARLOOKS_DRAW_H + +#include "clearlooks_types.h" +#include "clearlooks_style.h" + +#include <gtk/gtk.h> +#include <gdk/gdk.h> + +#include <cairo.h> + +GE_INTERNAL void clearlooks_register_style_classic (ClearlooksStyleFunctions *functions); +GE_INTERNAL void clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions); +GE_INTERNAL void clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions); +GE_INTERNAL void clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions); + +#endif /* CLEARLOOKS_DRAW_H */ diff --git a/libs/clearlooks/clearlooks_draw_glossy.c b/libs/clearlooks-newer/clearlooks_draw_glossy.c index 752b31b3e2..8a5921efc2 100644 --- a/libs/clearlooks/clearlooks_draw_glossy.c +++ b/libs/clearlooks-newer/clearlooks_draw_glossy.c @@ -36,9 +36,9 @@ static void clearlooks_draw_glossy_gradient (cairo_t *cr, - double x, double y, int width, int height, - const CairoColor *color, - gboolean disabled, gboolean radius, CairoCorners corners) + double x, double y, int width, int height, + const CairoColor *color, + gboolean disabled, gboolean radius, CairoCorners corners) { CairoColor a, b, c, d; cairo_pattern_t *pt; @@ -49,10 +49,10 @@ clearlooks_draw_glossy_gradient (cairo_t *cr, ge_shade_color (color, disabled? 1.02 : 1.08, &d); pt = cairo_pattern_create_linear (x, y, x, y+height); - cairo_pattern_add_color_stop_rgb (pt, 0.0, a.r, a.g, a.b); - cairo_pattern_add_color_stop_rgb (pt, 0.5, b.r, b.g, b.b); - cairo_pattern_add_color_stop_rgb (pt, 0.5, c.r, c.g, c.b); - cairo_pattern_add_color_stop_rgb (pt, 1.0, d.r, d.g, d.b); + cairo_pattern_add_color_stop_rgb (pt, 0.0, a.r, a.g, a.b); + cairo_pattern_add_color_stop_rgb (pt, 0.5, b.r, b.g, b.b); + cairo_pattern_add_color_stop_rgb (pt, 0.5, c.r, c.g, c.b); + cairo_pattern_add_color_stop_rgb (pt, 1.0, d.r, d.g, d.b); cairo_set_source (cr, pt); ge_cairo_rounded_rectangle (cr, x, y, width, height, radius, corners); @@ -73,66 +73,60 @@ clearlooks_set_mixed_color (cairo_t *cr, ge_cairo_set_color (cr, &composite); } -/* This draw_inset implementation only differes in the shades values from the - * default one. */ static void clearlooks_glossy_draw_inset (cairo_t *cr, const CairoColor *bg_color, - double x, double y, double width, double height, + double x, double y, double w, double h, double radius, uint8 corners) { CairoColor shadow; CairoColor highlight; - double line_width; - double min = MIN (width, height); - - line_width = cairo_get_line_width (cr); /* not really sure of shading ratios... we will think */ ge_shade_color (bg_color, 0.93, &shadow); ge_shade_color (bg_color, 1.07, &highlight); /* highlight */ - cairo_save (cr); + cairo_move_to (cr, x + w + (radius * -0.2928932188), y - (radius * -0.2928932188)); /* 0.2928932... 1-sqrt(2)/2 gives middle of curve */ - cairo_move_to (cr, x, y + height); - cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0); - cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0); - cairo_line_to (cr, x + width, y); - cairo_line_to (cr, x, y); - cairo_close_path (cr); - - cairo_clip (cr); + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.75, G_PI * 2); + else + cairo_line_to (cr, x + w, y); - ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0, - width - line_width, height - line_width, - radius, corners); + if (corners & CR_CORNER_BOTTOMRIGHT) + cairo_arc (cr, x + w - radius, y + h - radius, radius, 0, G_PI * 0.5); + else + cairo_line_to (cr, x + w, y + h); - ge_cairo_set_color (cr, &shadow); + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.5, G_PI * 0.75); + else + cairo_line_to (cr, x, y + h); + + ge_cairo_set_color (cr, &highlight); cairo_stroke (cr); - - cairo_restore (cr); /* shadow */ - cairo_save (cr); + cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188)); - cairo_move_to (cr, x, y + height); - cairo_line_to (cr, x + min / 2.0, y + height - min / 2.0); - cairo_line_to (cr, x + width - min / 2.0, y + min / 2.0); - cairo_line_to (cr, x + width, y); - cairo_line_to (cr, x + width, y + height); - cairo_close_path (cr); - - cairo_clip (cr); + if (corners & CR_CORNER_BOTTOMLEFT) + cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI); + else + cairo_line_to (cr, x, y + h); - ge_cairo_rounded_rectangle (cr, x + line_width / 2.0, y + line_width / 2.0, - width - line_width, height - line_width, - radius, corners); + if (corners & CR_CORNER_TOPLEFT) + cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5); + else + cairo_line_to (cr, x, y); - ge_cairo_set_color (cr, &highlight); - cairo_stroke (cr); + if (corners & CR_CORNER_TOPRIGHT) + cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75); + else + cairo_line_to (cr, x + w, y); - cairo_restore (cr); + ge_cairo_set_color (cr, &shadow); + cairo_stroke (cr); } static void @@ -173,17 +167,17 @@ clearlooks_glossy_draw_light_inset (cairo_t *cr, cairo_move_to (cr, x + (radius * 0.2928932188), y + h + (radius * -0.2928932188)); if (corners & CR_CORNER_BOTTOMLEFT) - cairo_arc (cr, x + radius, y + h - radius, radius, G_PI * 0.75, G_PI); + cairo_arc (cr, x + radius, y + h - radius, radius, M_PI * 0.75, M_PI); else cairo_line_to (cr, x, y + h); if (corners & CR_CORNER_TOPLEFT) - cairo_arc (cr, x + radius, y + radius, radius, G_PI, G_PI * 1.5); + cairo_arc (cr, x + radius, y + radius, radius, M_PI, M_PI * 1.5); else cairo_line_to (cr, x, y); if (corners & CR_CORNER_TOPRIGHT) - cairo_arc (cr, x + w - radius, y + radius, radius, G_PI * 1.5, G_PI * 1.75); + cairo_arc (cr, x + w - radius, y + radius, radius, M_PI * 1.5, M_PI * 1.75); else cairo_line_to (cr, x + w, y); @@ -191,7 +185,6 @@ clearlooks_glossy_draw_light_inset (cairo_t *cr, cairo_stroke (cr); } -/* This function currently assumes that the input is translated by 0.5px! */ static void clearlooks_glossy_draw_highlight_and_shade (cairo_t *cr, const CairoColor *bg_color, @@ -248,9 +241,9 @@ clearlooks_glossy_draw_highlight_and_shade (cairo_t *cr, static void clearlooks_glossy_draw_button (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *params, - int x, int y, int width, int height) + const ClearlooksColors *colors, + const WidgetParameters *params, + int x, int y, int width, int height) { double xoffset = 0, yoffset = 0; CairoColor fill = colors->bg[params->state_type]; @@ -264,7 +257,7 @@ clearlooks_glossy_draw_button (cairo_t *cr, cairo_translate (cr, x, y); cairo_set_line_width (cr, 1.0); - /* Shadows and shadow */ + /* Shadows and Glow */ if (params->xthickness == 3 || params->ythickness == 3) { if (params->xthickness == 3) @@ -277,32 +270,35 @@ clearlooks_glossy_draw_button (cairo_t *cr, if (params->xthickness == 3 || params->ythickness == 3) { - /* if (params->enable_shadow && !params->active && !params->disabled) */ - if (!params->active && (params->prelight || params->enable_shadow)) + cairo_translate (cr, 0.5, 0.5); + + /* if (params->enable_glow && !params->active && !params->disabled) */ + if (params->prelight && params->enable_glow && !params->active) { - /* shadow becomes a shadow to have 3d prelight buttons :) */ - CairoColor shadow; + /* Glow becomes a shadow to have 3d prelight buttons :) */ + CairoColor glow; radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0)); - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius+1, params->corners); - ge_shade_color (¶ms->parentbg, 0.96, &shadow); - ge_cairo_set_color (cr, &shadow); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius+1, params->corners); + ge_shade_color (¶ms->parentbg, 0.96, &glow); + ge_cairo_set_color (cr, &glow); cairo_stroke (cr); - ge_cairo_rounded_rectangle (cr, 1.5, 1.5, width-2, height-2, radius+1, params->corners); - ge_shade_color (¶ms->parentbg, 0.92, &shadow); - ge_cairo_set_color (cr, &shadow); + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius+1, params->corners); + ge_shade_color (¶ms->parentbg, 0.92, &glow); + ge_cairo_set_color (cr, &glow); cairo_stroke (cr); } - else - { + + /* if (!(params->enable_glow && !params->active && !params->disabled)) */ + if (!(params->prelight && params->enable_glow && !params->active)) if (!(params->disabled)) - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, params->radius+1, params->corners); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, params->radius+1, params->corners); else /*Draw a lighter inset */ - clearlooks_glossy_draw_light_inset (cr, ¶ms->parentbg, 0, 0, width, height, params->radius+1, params->corners); - } + clearlooks_glossy_draw_light_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, params->radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); } clearlooks_draw_glossy_gradient (cr, xoffset+1, yoffset+1, @@ -343,30 +339,30 @@ clearlooks_glossy_draw_button (cairo_t *cr, /* Default button highlight */ if (params->is_default && !params->active && !params->disabled) { - const CairoColor *shadow = &colors->spot[0]; + const CairoColor *glow = &colors->spot[0]; double hh = (height-5)/2.0 + 1; cairo_rectangle (cr, 3.5, 3.5, width-7, height-7); - ge_cairo_set_color (cr, shadow); + ge_cairo_set_color (cr, glow); cairo_stroke (cr); - shadow = &colors->spot[0]; + glow = &colors->spot[0]; cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, -hh); cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, hh); - ge_cairo_set_color (cr, shadow); + ge_cairo_set_color (cr, glow); cairo_stroke (cr); hh--; - shadow = &colors->spot[1]; + glow = &colors->spot[1]; cairo_move_to (cr, 2.5, 2.5+hh); cairo_rel_line_to (cr, 0, hh); cairo_rel_line_to (cr, width-5, 0); cairo_rel_line_to (cr, 0, -hh); - ge_cairo_set_color (cr, shadow); + ge_cairo_set_color (cr, glow); cairo_stroke (cr); } /* Border */ - if (params->is_default || (params->prelight && params->enable_shadow)) + if (params->is_default || (params->prelight && params->enable_glow)) border_normal = colors->spot[2]; /* ge_mix_color (&border_normal, &colors->spot[2], 0.5, &border_normal); */ if (params->disabled) @@ -395,6 +391,12 @@ clearlooks_glossy_draw_progressbar_trough (cairo_t *cr, cairo_set_line_width (cr, 1.0); + /* Fill with bg color */ + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); + /* Create trough box */ ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); ge_cairo_set_color (cr, &colors->shade[2]); @@ -602,21 +604,20 @@ clearlooks_glossy_scale_draw_gradient (cairo_t *cr, { cairo_pattern_t *pattern; - pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 : width + 1, horizontal ? height + 1 : 0.5); + pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 : width, horizontal ? height : 0); cairo_pattern_add_color_stop_rgb (pattern, 0.0, c1->r, c1->g, c1->b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, c2->r, c2->g, c2->b); - cairo_rectangle (cr, x, y, width, height); + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); clearlooks_set_mixed_color (cr, c3, c1, 0.3); - ge_cairo_inner_rectangle (cr, x, y, width, height); - cairo_stroke (cr); + ge_cairo_stroke_rectangle (cr, x, y, width, height); } -#define TROUGH_SIZE 7 +#define TROUGH_SIZE 6 static void clearlooks_glossy_draw_scale_trough (cairo_t *cr, const ClearlooksColors *colors, @@ -627,44 +628,43 @@ clearlooks_glossy_draw_scale_trough (cairo_t *cr, int trough_width, trough_height; double translate_x, translate_y; - cairo_save (cr); - if (slider->horizontal) { - trough_width = width; - trough_height = TROUGH_SIZE; + trough_width = width-3; + trough_height = TROUGH_SIZE-2; - translate_x = x; - translate_y = y + (height/2) - (TROUGH_SIZE/2); + translate_x = x + 0.5; + translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2); } else { - trough_width = TROUGH_SIZE; - trough_height = height; + trough_width = TROUGH_SIZE-2; + trough_height = height-3; - translate_x = x + (width/2) - (TROUGH_SIZE/2); - translate_y = y; + translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2); + translate_y = y + 0.5; } cairo_set_line_width (cr, 1.0); cairo_translate (cr, translate_x, translate_y); if (!slider->fill_level) - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width, trough_height, 0, 0); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0); + + cairo_translate (cr, 1, 1); if (!slider->lower && !slider->fill_level) clearlooks_glossy_scale_draw_gradient (cr, &colors->shade[3], /* top */ &colors->shade[2], /* bottom */ &colors->shade[6], /* border */ - 1.0, 1.0, trough_width - 2, trough_height - 2, + 0, 0, trough_width, trough_height, slider->horizontal); else clearlooks_glossy_scale_draw_gradient (cr, &colors->spot[1], /* top */ &colors->spot[0], /* bottom */ &colors->spot[2], /* border */ - 1.0, 1.0, trough_width - 2, trough_height - 2, + 0, 0, trough_width, trough_height, slider->horizontal); - cairo_restore (cr); } static void @@ -685,7 +685,6 @@ clearlooks_glossy_draw_tab (cairo_t *cr, double radius; double strip_size; - double length; radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); @@ -704,7 +703,6 @@ clearlooks_glossy_draw_tab (cairo_t *cr, if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) { height += 3.0; - length = height; strip_size = 2.0/height; /* 2 pixel high strip */ if (tab->gap_side == CL_GAP_TOP) @@ -713,7 +711,6 @@ clearlooks_glossy_draw_tab (cairo_t *cr, else { width += 3.0; - length = width; strip_size = 2.0/width; if (tab->gap_side == CL_GAP_LEFT) @@ -741,8 +738,6 @@ clearlooks_glossy_draw_tab (cairo_t *cr, shadow.shadow = CL_SHADOW_OUT; shadow.corners = params->corners; - /* This is the only usage of clearlooks_glossy_draw_highlight_and_shade, - * the function assumes currently that the input is translated by 0.5 px. */ clearlooks_glossy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow, width, height, radius); @@ -752,23 +747,10 @@ clearlooks_glossy_draw_tab (cairo_t *cr, { CairoColor shadow, hilight, f1, f2; - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0, height-2, 0, 0); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0, 1, 0, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 0, 1, 0); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (1, 0, width-2, 0); - break; - default: - pattern = NULL; - } + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); @@ -778,8 +760,8 @@ clearlooks_glossy_draw_tab (cairo_t *cr, ge_shade_color (fill, 1.06, &f2); cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, hilight.r, hilight.g, hilight.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0/length, f1.r, f1.g, f1.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, f1.r, f1.g, f1.b); cairo_pattern_add_color_stop_rgb (pattern, 0.45, f2.r, f2.g, f2.b); cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b); cairo_pattern_add_color_stop_rgb (pattern, 1.0, shadow.r, shadow.g, shadow.b); @@ -790,23 +772,10 @@ clearlooks_glossy_draw_tab (cairo_t *cr, else { /* Draw shade */ - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0, height-2, 0, 0); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0, 0, 0, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 0, 0, 0); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (0, 0, width, 0); - break; - default: - pattern = NULL; - } + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); @@ -827,23 +796,10 @@ clearlooks_glossy_draw_tab (cairo_t *cr, } else { - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (2, height-2, 2, 2); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (2, 2, 2, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 2, 2, 2); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (2, 2, width, 2); - break; - default: - pattern = NULL; - } + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2); cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r, border->g, border->b); @@ -868,6 +824,8 @@ clearlooks_glossy_draw_slider (cairo_t *cr, cairo_set_line_width (cr, 1.0); cairo_translate (cr, x, y); + cairo_translate (cr, -0.5, -0.5); + ge_shade_color (&colors->bg[params->state_type], 1.0, &fill); if (params->prelight) ge_shade_color (&fill, 1.1, &fill); @@ -913,8 +871,9 @@ clearlooks_glossy_draw_slider_button (cairo_t *cr, if (!slider->horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); - cairo_translate (cr, x, y); - params->style_functions->draw_shadow (cr, colors, radius, width, height); + cairo_translate (cr, x+0.5, y+0.5); + + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); } @@ -971,12 +930,16 @@ clearlooks_glossy_draw_scrollbar_stepper (cairo_t *cr, cairo_fill (cr); cairo_pattern_destroy (pattern); - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, corners); + cairo_translate (cr, 0.5, 0.5); + cairo_translate (cr, -0.5, -0.5); + + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); clearlooks_set_mixed_color (cr, border, &fill, 0.2); if (widget->prelight) ge_cairo_set_color (cr, &colors->spot[2]); cairo_stroke (cr); + cairo_translate (cr, 0.5, 0.5); shadow.shadow = CL_SHADOW_OUT; shadow.corners = corners; } @@ -1091,7 +1054,7 @@ clearlooks_glossy_draw_list_view_header (cairo_t *cr, cairo_pattern_destroy (pattern); /* Draw highlight */ - if (header->order & CL_ORDER_FIRST) + if (header->order == CL_ORDER_FIRST) { cairo_move_to (cr, 0.5, height-1); cairo_line_to (cr, 0.5, 0.5); @@ -1105,8 +1068,8 @@ clearlooks_glossy_draw_list_view_header (cairo_t *cr, cairo_stroke (cr); /* Draw resize grip */ - if ((params->ltr && !(header->order & CL_ORDER_LAST)) || - (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable) + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) { SeparatorParameters separator; separator.horizontal = FALSE; @@ -1274,13 +1237,6 @@ clearlooks_glossy_draw_radiobutton (cairo_t *cr, cairo_pattern_t *pt; gboolean inconsistent; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); - gdouble w, h, cx, cy, radius; - - w = (gdouble) width; - h = (gdouble) height; - cx = width / 2.0; - cy = height / 2.0; - radius = MIN (width, height) / 2.0; inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; @@ -1302,7 +1258,7 @@ clearlooks_glossy_draw_radiobutton (cairo_t *cr, ge_shade_color (&widget->parentbg, 0.9, &shadow); ge_shade_color (&widget->parentbg, 1.1, &highlight); - pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0); + pt = cairo_pattern_create_linear (0, 0, 13, 13); cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); @@ -1310,15 +1266,15 @@ clearlooks_glossy_draw_radiobutton (cairo_t *cr, cairo_translate (cr, x, y); - cairo_set_line_width (cr, MAX (1.0, floor (radius/3))); - cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2); + cairo_set_line_width (cr, 2); + cairo_arc (cr, 7, 7, 6, 0, G_PI*2); cairo_set_source (cr, pt); cairo_stroke (cr); cairo_pattern_destroy (pt); - cairo_set_line_width (cr, MAX (1.0, floor (radius/6))); + cairo_set_line_width (cr, 1); - cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2); + cairo_arc (cr, 7, 7, 5.5, 0, G_PI*2); if (!widget->disabled) { @@ -1337,21 +1293,21 @@ clearlooks_glossy_draw_radiobutton (cairo_t *cr, if (inconsistent) { cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width (cr, ceil (radius * 2 / 3)); + cairo_set_line_width (cr, 4); - cairo_move_to (cr, ceil (cx - radius/3.0), ceil (cy)); - cairo_line_to (cr, ceil (cx + radius/3.0), ceil (cy)); + cairo_move_to(cr, 5, 7); + cairo_line_to(cr, 9, 7); ge_cairo_set_color (cr, dot); cairo_stroke (cr); } else { - cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2); + cairo_arc (cr, 7, 7, 3, 0, G_PI*2); ge_cairo_set_color (cr, dot); cairo_fill (cr); - cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2); + cairo_arc (cr, 6, 6, 1, 0, G_PI*2); cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); cairo_fill (cr); } @@ -1392,8 +1348,8 @@ clearlooks_glossy_draw_checkbox (cairo_t *cr, if (widget->xthickness > 2 && widget->ythickness > 2) { - widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0, - width, height, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + widget->style_functions->draw_inset (cr, &widget->parentbg, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); /* Draw the rectangle for the checkbox itself */ ge_cairo_rounded_rectangle (cr, 1.5, 1.5, @@ -1444,7 +1400,7 @@ clearlooks_glossy_draw_checkbox (cairo_t *cr, } void -clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants) +clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions) { functions->draw_inset = clearlooks_glossy_draw_inset; functions->draw_button = clearlooks_glossy_draw_button; diff --git a/libs/clearlooks/clearlooks_draw_gummy.c b/libs/clearlooks-newer/clearlooks_draw_gummy.c index ccbd7d9e0f..e2a990230b 100644 --- a/libs/clearlooks/clearlooks_draw_gummy.c +++ b/libs/clearlooks-newer/clearlooks_draw_gummy.c @@ -33,6 +33,10 @@ #define SHADE_CENTER_TOP 1.02 #define SHADE_BOTTOM 0.94 +/* Topleft highlight */ +#define TOPLEFT_HIGHLIGHT_SHADE 1.3 +#define TOPLEFT_HIGHLIGHT_ALPHA 0.4 + /* Listview */ #define LISTVIEW_SHADE_TOP 1.06 #define LISTVIEW_SHADE_CENTER_TOP 1.02 @@ -43,6 +47,7 @@ #define TOOLBAR_SHADE_CENTER_TOP 1.01 #define TOOLBAR_SHADE_BOTTOM 0.97 + static void clearlooks_draw_gummy_gradient (cairo_t *cr, double x, double y, int width, int height, @@ -72,9 +77,9 @@ clearlooks_draw_gummy_gradient (cairo_t *cr, } static void -clearlooks_set_mixed_color (cairo_t *cr, - const CairoColor *color1, - const CairoColor *color2, +clearlooks_set_mixed_color (cairo_t *cr, + const CairoColor *color1, + const CairoColor *color2, gdouble mix_factor) { CairoColor composite; @@ -84,7 +89,7 @@ clearlooks_set_mixed_color (cairo_t *cr, } static void -clearlooks_gummy_draw_highlight_and_shade (cairo_t *cr, +clearlooks_gummy_draw_highlight_and_shade (cairo_t *cr, const CairoColor *bg_color, const ShadowParameters *params, int width, int height, gdouble radius) @@ -118,7 +123,7 @@ clearlooks_gummy_draw_highlight_and_shade (cairo_t *cr, cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); else cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.5); - + cairo_stroke (cr); /* Bottom/Right highlight -- this includes the corners */ @@ -138,6 +143,28 @@ clearlooks_gummy_draw_highlight_and_shade (cairo_t *cr, } static void +clearlooks_gummy_draw_top_left_highlight (cairo_t *cr, const CairoColor *color, + const WidgetParameters *params, + int width, int height, gdouble radius) +{ + CairoColor hilight; + + double light_top = params->ythickness-1, + light_bottom = height - params->ythickness - 1, + light_left = params->xthickness-1, + light_right = width - params->xthickness - 1; + + ge_shade_color (color, TOPLEFT_HIGHLIGHT_SHADE, &hilight); + cairo_move_to (cr, light_left, light_bottom - (int)radius/2); + + ge_cairo_rounded_corner (cr, light_left, light_top, radius, params->corners & CR_CORNER_TOPLEFT); + + cairo_line_to (cr, light_right - (int)radius/2, light_top); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, TOPLEFT_HIGHLIGHT_ALPHA); + cairo_stroke (cr); +} + +static void clearlooks_gummy_draw_button (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *params, @@ -155,27 +182,33 @@ clearlooks_gummy_draw_button (cairo_t *cr, cairo_translate (cr, x, y); cairo_set_line_width (cr, 1.0); - if (params->xthickness == 3) - xoffset = 1; - if (params->ythickness == 3) - yoffset = 1; + /* Shadows and Glow */ + if (params->xthickness == 3 || params->ythickness == 3) + { + if (params->xthickness == 3) + xoffset = 1; + if (params->ythickness == 3) + yoffset = 1; + } radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0, (height - 2.0 - 2*yoffset) / 2.0)); if (params->xthickness == 3 || params->ythickness == 3) { - if (params->enable_shadow && !params->active && !params->disabled && !params->is_default) + cairo_translate (cr, 0.5, 0.5); + + if (params->enable_glow && !params->active && !params->disabled && !params->is_default) { CairoColor shadow; radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0)); - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius+1, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius+1, params->corners); ge_shade_color (¶ms->parentbg, 0.97, &shadow); ge_cairo_set_color (cr, &shadow); cairo_stroke (cr); - ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-1, height-1, radius+1, params->corners); + ge_cairo_rounded_rectangle (cr, 1, 1, width-2, height-2, radius+1, params->corners); ge_shade_color (¶ms->parentbg, 0.93, &shadow); ge_cairo_set_color (cr, &shadow); cairo_stroke (cr); @@ -187,18 +220,19 @@ clearlooks_gummy_draw_button (cairo_t *cr, radius = MIN (params->radius, MIN ((width - 2.0 - 2*xoffset) / 2.0 - 1.0, (height - 2.0 - 2*yoffset) / 2.0 - 1.0)); - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius+1, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius+1, params->corners); clearlooks_set_mixed_color (cr, ¶ms->parentbg, &shadow, 0.5); cairo_stroke (cr); } - if (!(params->enable_shadow && !params->active && !params->disabled)) - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, params->radius+1, params->corners); + if (!(params->enable_glow && !params->active && !params->disabled)) + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, params->radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); } - clearlooks_draw_gummy_gradient (cr, xoffset+1, yoffset+1, - width-(xoffset*2)-2, height-(yoffset*2)-2, - &fill, params->disabled, radius, params->corners); + clearlooks_draw_gummy_gradient (cr, xoffset+1, yoffset+1, + width-(xoffset*2)-2, height-(yoffset*2)-2, + &fill, params->disabled, radius, params->corners); /* Pressed button shadow */ if (params->active) @@ -208,7 +242,7 @@ clearlooks_gummy_draw_button (cairo_t *cr, cairo_save (cr); - ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius, + ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, height, radius, params->corners & (CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMLEFT)); cairo_clip (cr); cairo_rectangle (cr, xoffset+1, yoffset+1, width-(xoffset*2)-2, 3); @@ -233,22 +267,21 @@ clearlooks_gummy_draw_button (cairo_t *cr, } /* Border */ - if (params->is_default) /* || (params->prelight && params->enable_shadow)) */ + if (params->is_default) /* || (params->prelight && params->enable_glow)) */ border_normal = colors->spot[2]; if (params->disabled) ge_cairo_set_color (cr, &border_disabled); else clearlooks_set_mixed_color (cr, &border_normal, &fill, 0.2); ge_cairo_rounded_rectangle (cr, xoffset + 0.5, yoffset + 0.5, - width-(xoffset*2)-1, height-(yoffset*2)-1, - radius, params->corners); + width-(xoffset*2)-1, height-(yoffset*2)-1, + radius, params->corners); cairo_stroke (cr); if (!params->active) { - params->style_functions->draw_top_left_highlight (cr, &fill, params, 1+xoffset, 1+xoffset, - width-(1+xoffset)*2, height-(1+xoffset)*2, - radius, params->corners); + cairo_translate (cr, 0.5, 0.5); + clearlooks_gummy_draw_top_left_highlight (cr, &fill, params, width, height, radius); } cairo_restore (cr); } @@ -266,44 +299,48 @@ clearlooks_gummy_draw_entry (cairo_t *cr, if (params->focus) border = colors->spot[2]; - cairo_save (cr); - - cairo_translate (cr, x, y); + cairo_translate (cr, x+0.5, y+0.5); cairo_set_line_width (cr, 1.0); - /* Now fill the area we want to be base[NORMAL]. */ - ge_cairo_rounded_rectangle (cr, 2, 2, width-4, height-4, MAX(0, radius-1), params->corners); + /* Fill the background to get the correct corners. */ + cairo_rectangle (cr, -0.5, -0.5, width, height); + ge_cairo_set_color (cr, ¶ms->parentbg); + cairo_fill (cr); + + /* Fill with the base color, because it was just cleared above */ + cairo_rectangle (cr, 1.5, 1.5, width-4, height-4); ge_cairo_set_color (cr, base); cairo_fill (cr); - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, radius+1, params->corners); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); /* Draw the inner shadow */ if (params->focus) { - clearlooks_set_mixed_color (cr, base, &colors->spot[1], 0.5); - ge_cairo_inner_rounded_rectangle (cr, 2, 2, width-4, height-4, MAX(0, radius-1), params->corners); - cairo_stroke (cr); + /* ge_cairo_rounded_rectangle (cr, 2, 2, width-5, height-5, RADIUS-1, params->corners); */ + ge_cairo_set_color (cr, &colors->spot[0]); + ge_cairo_stroke_rectangle (cr, 2, 2, width-5, height-5); } else { - CairoColor shadow; + CairoColor shadow; ge_shade_color (&border, 0.92, &shadow); cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, params->disabled ? 0.09 : 0.18); - - cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT); - cairo_move_to (cr, 2.5, height-radius); - cairo_arc (cr, 2.5+MAX(0, radius-1), 2.5+MAX(0, radius-1), MAX(0, radius-1), G_PI, 270*(G_PI/180)); - cairo_line_to (cr, width-radius, 2.5); + /* + cairo_move_to (cr, 2, height-3); + cairo_arc (cr, params->xthickness+RADIUS-1, params->ythickness+RADIUS-1, RADIUS, G_PI, 270*(G_PI/180)); + cairo_line_to (cr, width-3, 2); + */ + cairo_move_to (cr, 2, height-3); + cairo_line_to (cr, 2, 2); + cairo_line_to (cr, width-3, 2); cairo_stroke (cr); } - ge_cairo_inner_rounded_rectangle (cr, 1, 1, width-2, height-2, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 1, 1, width-3, height-3, radius, params->corners); ge_cairo_set_color (cr, &border); cairo_stroke (cr); - - cairo_restore (cr); } static void @@ -321,6 +358,12 @@ clearlooks_gummy_draw_progressbar_trough (cairo_t *cr, cairo_set_line_width (cr, 1.0); + /* Fill with bg color */ + ge_cairo_set_color (cr, &colors->bg[params->state_type]); + + cairo_rectangle (cr, x, y, width, height); + cairo_fill (cr); + /* Create trough box */ ge_cairo_rounded_rectangle (cr, x+1, y+1, width-2, height-2, radius, params->corners); ge_cairo_set_color (cr, &colors->shade[2]); @@ -365,11 +408,11 @@ clearlooks_gummy_draw_progressbar_fill (cairo_t *cr, const ProgressBarParameters *progressbar, int x, int y, int width, int height, gint offset) { - boolean is_horizontal = progressbar->orientation < 2; - double tile_pos = 0; - double stroke_width; - double radius; - int x_step; + boolean is_horizontal = progressbar->orientation < 2; + double tile_pos = 0; + double stroke_width; + double radius; + int x_step; cairo_pattern_t *pattern; CairoColor shade1, shade2, shade3; @@ -415,14 +458,14 @@ clearlooks_gummy_draw_progressbar_fill (cairo_t *cr, cairo_paint (cr); cairo_pattern_destroy (pattern); - /* Draw the strokes */ + /* Draw the Strokes */ while (tile_pos <= width+x_step) { cairo_move_to (cr, stroke_width/2-x_step, 0); cairo_line_to (cr, stroke_width-x_step, 0); cairo_line_to (cr, stroke_width/2-x_step, height); cairo_line_to (cr, -x_step, height); - + cairo_translate (cr, stroke_width, 0); tile_pos += stroke_width; } @@ -529,21 +572,20 @@ clearlooks_gummy_scale_draw_gradient (cairo_t *cr, ge_shade_color (fill, in? 0.95 : 1.1, &f1); ge_shade_color (fill, in? 1.05 : 0.9, &f2); - pattern = cairo_pattern_create_linear (0.5, 0.5, horizontal ? 0.5 : width + 1.0, horizontal ? height + 1.0 : 0.5); + pattern = cairo_pattern_create_linear (0, 0, horizontal ? 0 : width, horizontal ? height : 0); cairo_pattern_add_color_stop_rgba (pattern, 0.0, f1.r, f1.g, f1.b, f1.a); cairo_pattern_add_color_stop_rgba (pattern, 1.0, f2.r, f2.g, f2.b, f2.a); - cairo_rectangle (cr, x, y, width, height); + cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); clearlooks_set_mixed_color (cr, border, fill, 0.2); - ge_cairo_inner_rectangle (cr, x, y, width, height); - cairo_stroke (cr); + ge_cairo_stroke_rectangle (cr, x, y, width, height); } -#define TROUGH_SIZE 7 +#define TROUGH_SIZE 6 static void clearlooks_gummy_draw_scale_trough (cairo_t *cr, const ClearlooksColors *colors, @@ -551,66 +593,60 @@ clearlooks_gummy_draw_scale_trough (cairo_t *cr, const SliderParameters *slider, int x, int y, int width, int height) { - int trough_width, trough_height; - double translate_x, translate_y; - CairoColor fill, border; - gboolean in; - - cairo_save (cr); + int trough_width, trough_height; + double translate_x, translate_y; if (slider->horizontal) { - trough_width = width; - trough_height = TROUGH_SIZE; + trough_width = width-3; + trough_height = TROUGH_SIZE-2; - translate_x = x; - translate_y = y + (height/2) - (TROUGH_SIZE/2); + translate_x = x + 0.5; + translate_y = y + 0.5 + (height/2) - (TROUGH_SIZE/2); } else { - trough_width = TROUGH_SIZE; - trough_height = height; + trough_width = TROUGH_SIZE-2; + trough_height = height-3; - translate_x = x + (width/2) - (TROUGH_SIZE/2); - translate_y = y; + translate_x = x + 0.5 + (width/2) - (TROUGH_SIZE/2); + translate_y = y + 0.5; } cairo_set_line_width (cr, 1.0); cairo_translate (cr, translate_x, translate_y); if (!slider->fill_level) - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width, trough_height, 0, 0); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, trough_width+2, trough_height+2, 0, 0); + + cairo_translate (cr, 1, 1); if (!slider->lower && !slider->fill_level) - { - ge_shade_color (¶ms->parentbg, 0.896, &fill); - border = colors->shade[6]; - in = TRUE; - } + clearlooks_gummy_scale_draw_gradient (cr, + &colors->shade[2], /* bottom */ + &colors->shade[6], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal, TRUE); else if (!slider->fill_level) - { - fill = colors->spot[1]; - border = colors->spot[2]; - in = FALSE; + clearlooks_gummy_scale_draw_gradient (cr, + &colors->spot[1], /* bottom */ + &colors->spot[2], /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal, FALSE); + else { + CairoColor c1 = colors->spot[1]; + CairoColor c2 = colors->spot[2]; + + c1.a = 0.25; + c2.a = 0.25; + + clearlooks_gummy_scale_draw_gradient (cr, + &c1, /* bottom */ + &c2, /* border */ + 0, 0, trough_width, trough_height, + slider->horizontal, FALSE); } - else - { - fill = colors->spot[1]; - border = colors->spot[2]; - fill.a = 0.25; - border.a = 0.25; - - in = FALSE; - } - - clearlooks_gummy_scale_draw_gradient (cr, - &fill, - &border, - 1, 1, trough_width - 2, trough_height - 2, - slider->horizontal, in); - - cairo_restore (cr); } static void @@ -620,19 +656,16 @@ clearlooks_gummy_draw_tab (cairo_t *cr, const TabParameters *tab, int x, int y, int width, int height) { - const CairoColor *border = &colors->shade[5]; - const CairoColor *stripe_fill = &colors->spot[1]; - const CairoColor *stripe_border = &colors->spot[2]; - const CairoColor *fill; - cairo_pattern_t *pattern = NULL; + const CairoColor *border = &colors->shade[5]; + const CairoColor *stripe_fill = &colors->spot[1]; + const CairoColor *stripe_border = &colors->spot[2]; + const CairoColor *fill; - double radius; - double stripe_size = 2.0; - double stripe_fill_size; - double stripe_border_pos; + cairo_pattern_t *pattern; - gboolean horizontal = FALSE; + double radius; + double strip_size; radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); @@ -649,28 +682,18 @@ clearlooks_gummy_draw_tab (cairo_t *cr, /* And calculate the strip size too, while you're at it */ if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) { - if (params->ythickness == 3) - stripe_size = 3.0; - height += 3.0; - stripe_fill_size = (tab->gap_side == CL_GAP_TOP ? stripe_size/height : stripe_size/(height-2)); - stripe_border_pos = (tab->gap_side == CL_GAP_TOP ? (stripe_size+1.0)/height : (stripe_size+1.0)/(height-2)); - - horizontal = TRUE; + strip_size = 2.0/height; /* 2 pixel high strip */ if (tab->gap_side == CL_GAP_TOP) cairo_translate (cr, 0.0, -3.0); /* gap at the other side */ } else { - if (params->xthickness == 3) - stripe_size = 3.0; - width += 3.0; - stripe_fill_size = (tab->gap_side == CL_GAP_LEFT ? stripe_size/width : stripe_size/(width-2)); - stripe_border_pos = (tab->gap_side == CL_GAP_LEFT ? (stripe_size+1.0)/width : (stripe_size+1.0)/(width-2)); + strip_size = 2.0/width; - if (tab->gap_side == CL_GAP_LEFT) + if (tab->gap_side == CL_GAP_LEFT) cairo_translate (cr, -3.0, 0.0); /* gap at the other side */ } @@ -694,7 +717,7 @@ clearlooks_gummy_draw_tab (cairo_t *cr, shadow.corners = params->corners; clearlooks_gummy_draw_highlight_and_shade (cr, &colors->bg[0], &shadow, - width, height, radius); + width, height, radius); } if (params->active) @@ -702,70 +725,39 @@ clearlooks_gummy_draw_tab (cairo_t *cr, CairoColor hilight; CairoColor shade1, shade2, shade3; - ge_shade_color (fill, 1.15, &hilight); + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); + + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); + + ge_shade_color (fill, 1.14, &hilight); ge_shade_color (fill, SHADE_TOP, &shade1); ge_shade_color (fill, SHADE_CENTER_TOP, &shade2); ge_shade_color (fill, SHADE_BOTTOM, &shade3); - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0, height-2, 0, 0); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0, 1, 0, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 0, 1, 0); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (1, 0, width-2, 0); - break; - } - - ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); - - cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0/(horizontal ? height : width), hilight.r, hilight.g, hilight.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0/(horizontal ? height : width), shade1.r, shade1.g, shade1.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.45, shade2.r, shade2.g, shade2.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.0, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, hilight.r, hilight.g, hilight.b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0/height, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.45, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb (pattern, 0.45, fill->r, fill->g, fill->b); + cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); } else { - CairoColor shade1; - - ge_shade_color (fill, SHADE_TOP, &shade1); - - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0, height-2, 0, 0); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0, 0, 0, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 0, 0, 0); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (0, 0, width, 0); - break; - } + /* Draw shade */ + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0); ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.6); - /* cairo_pattern_add_color_stop_rgba (pattern, 1.0/(horizontal ? height : width), stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.34); - cairo_pattern_add_color_stop_rgba (pattern, 1.0/(horizontal ? height : width), stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5); */ - cairo_pattern_add_color_stop_rgb (pattern, stripe_fill_size, stripe_fill->r, stripe_fill->g, stripe_fill->b); - cairo_pattern_add_color_stop_rgba (pattern, stripe_fill_size, stripe_border->r, stripe_border->g, stripe_border->b, 0.72); - cairo_pattern_add_color_stop_rgba (pattern, stripe_border_pos, stripe_border->r, stripe_border->g, stripe_border->b, 0.72); - cairo_pattern_add_color_stop_rgb (pattern, stripe_border_pos, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgba (pattern, 0.0, stripe_fill->r, stripe_fill->g, stripe_fill->b, 0.5); cairo_pattern_add_color_stop_rgba (pattern, 0.8, fill->r, fill->g, fill->b, 0.0); cairo_set_source (cr, pattern); cairo_fill (cr); @@ -781,21 +773,10 @@ clearlooks_gummy_draw_tab (cairo_t *cr, } else { - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (2, height-2, 2, 2); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (2, 2, 2, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 2, 2, 2); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (2, 2, width, 2); - break; - } + pattern = cairo_pattern_create_linear (tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2); cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); cairo_pattern_add_color_stop_rgb (pattern, 0.8, border->r, border->g, border->b); @@ -803,39 +784,6 @@ clearlooks_gummy_draw_tab (cairo_t *cr, cairo_stroke (cr); cairo_pattern_destroy (pattern); } - - /* In current GTK+ focus and active cannot happen together, but we are robust against it. */ - if (params->focus && !params->active) - { - CairoColor focus_fill = tab->focus.color; - CairoColor fill_shade1, fill_shade2, fill_shade3; - CairoColor focus_border; - - double focus_inset_x = ((tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) ? 4 : stripe_size + 3); - double focus_inset_y = ((tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) ? stripe_size + 3 : 4); - double border_alpha = 0.54; - double fill_alpha = 0.17; - - ge_shade_color (&focus_fill, 0.65, &focus_border); - ge_shade_color (&focus_fill, 1.18, &fill_shade1); - ge_shade_color (&focus_fill, 1.02, &fill_shade2); - ge_shade_color (&focus_fill, 0.84, &fill_shade3); - - ge_cairo_rounded_rectangle (cr, focus_inset_x, focus_inset_y, width-focus_inset_x*2-1, height-focus_inset_y*2-1, radius-1, CR_CORNER_ALL); - pattern = cairo_pattern_create_linear (0, 0, 0, height); - - cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill_shade1.r, fill_shade1.g, fill_shade1.b, fill_alpha); - cairo_pattern_add_color_stop_rgba (pattern, 0.5, fill_shade2.r, fill_shade2.g, fill_shade2.b, fill_alpha); - cairo_pattern_add_color_stop_rgba (pattern, 0.5, focus_fill.r, focus_fill.g, focus_fill.b, fill_alpha); - cairo_pattern_add_color_stop_rgba (pattern, 1.0, fill_shade3.r, fill_shade3.g, fill_shade3.b, fill_alpha); - cairo_set_source (cr, pattern); - cairo_fill_preserve (cr); - - cairo_pattern_destroy (pattern); - - clearlooks_set_mixed_color (cr, ¶ms->parentbg, &focus_border, border_alpha); - cairo_stroke (cr); - } } static void @@ -854,33 +802,33 @@ clearlooks_gummy_draw_separator (cairo_t *cr, if (separator->horizontal) { - cairo_set_line_width (cr, 1.0); - cairo_translate (cr, x, y+0.5); - - cairo_move_to (cr, 0.0, 0.0); - cairo_line_to (cr, width, 0.0); - ge_cairo_set_color (cr, &color); - cairo_stroke (cr); - - cairo_move_to (cr, 0.0, 1.0); - cairo_line_to (cr, width, 1.0); - ge_cairo_set_color (cr, &hilight); - cairo_stroke (cr); + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x, y+0.5); + + cairo_move_to (cr, 0.0, 0.0); + cairo_line_to (cr, width, 0.0); + ge_cairo_set_color (cr, &color); + cairo_stroke (cr); + + cairo_move_to (cr, 0.0, 1.0); + cairo_line_to (cr, width, 1.0); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); } else { - cairo_set_line_width (cr, 1.0); - cairo_translate (cr, x+0.5, y); - - cairo_move_to (cr, 0.0, 0.0); - cairo_line_to (cr, 0.0, height); - ge_cairo_set_color (cr, &color); - cairo_stroke (cr); - - cairo_move_to (cr, 1.0, 0.0); - cairo_line_to (cr, 1.0, height); - ge_cairo_set_color (cr, &hilight); - cairo_stroke (cr); + cairo_set_line_width (cr, 1.0); + cairo_translate (cr, x+0.5, y); + + cairo_move_to (cr, 0.0, 0.0); + cairo_line_to (cr, 0.0, height); + ge_cairo_set_color (cr, &color); + cairo_stroke (cr); + + cairo_move_to (cr, 1.0, 0.0); + cairo_line_to (cr, 1.0, height); + ge_cairo_set_color (cr, &hilight); + cairo_stroke (cr); } cairo_restore (cr); @@ -893,15 +841,17 @@ clearlooks_gummy_draw_slider (cairo_t *cr, int x, int y, int width, int height) { const CairoColor *border = &colors->shade[7]; - CairoColor fill; - CairoColor shade1, shade2, shade3; + CairoColor fill; + CairoColor shade1, shade2, shade3; cairo_pattern_t *pattern; int bar_x, i; int shift_x; - cairo_set_line_width (cr, 1.0); + cairo_set_line_width (cr, 1.0); cairo_translate (cr, x, y); + cairo_translate (cr, -0.5, -0.5); + ge_shade_color (&colors->bg[params->state_type], 1.0, &fill); if (params->prelight) ge_shade_color (&fill, 1.04, &fill); @@ -911,10 +861,10 @@ clearlooks_gummy_draw_slider (cairo_t *cr, ge_shade_color (&fill, SHADE_BOTTOM, &shade3); pattern = cairo_pattern_create_linear (1, 1, 1, height-2); - cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + cairo_pattern_add_color_stop_rgb(pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, shade3.r, shade3.g, shade3.b); cairo_rectangle (cr, 1, 1, width-2, height-2); cairo_set_source (cr, pattern); cairo_fill (cr); @@ -939,7 +889,7 @@ clearlooks_gummy_draw_slider (cairo_t *cr, } cairo_stroke (cr); - params->style_functions->draw_top_left_highlight (cr, &fill, params, 1, 1, width-2, height-2, 2.0, params->corners); + clearlooks_gummy_draw_top_left_highlight (cr, &fill, params, width, height, 2.0); } static void @@ -956,9 +906,9 @@ clearlooks_gummy_draw_slider_button (cairo_t *cr, if (!slider->horizontal) ge_cairo_exchange_axis (cr, &x, &y, &width, &height); - cairo_translate (cr, x, y); + cairo_translate (cr, x+0.5, y+0.5); - params->style_functions->draw_shadow (cr, colors, radius, width, height); + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); } @@ -975,6 +925,7 @@ clearlooks_gummy_draw_scrollbar_stepper (cairo_t *cr, CairoColor fill; CairoColor shade1, shade2, shade3; cairo_pattern_t *pattern; + ShadowParameters shadow; double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); if (scrollbar->horizontal) @@ -1003,24 +954,29 @@ clearlooks_gummy_draw_scrollbar_stepper (cairo_t *cr, pattern = cairo_pattern_create_linear (0, 0, width, 0); fill = colors->bg[widget->state_type]; - ge_shade_color (&fill, SHADE_TOP, &shade1); - ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2); - ge_shade_color (&fill, SHADE_BOTTOM, &shade3); - - cairo_pattern_add_color_stop_rgb (pattern, 0, shade1.r, shade1.g, shade1.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.5, shade2.r, shade2.g, shade2.b); - cairo_pattern_add_color_stop_rgb (pattern, 0.5, fill.r, fill.g, fill.b); - cairo_pattern_add_color_stop_rgb (pattern, 1.0, shade3.r, shade3.g, shade3.b); + ge_shade_color(&fill, SHADE_TOP, &shade1); + ge_shade_color(&fill, SHADE_CENTER_TOP, &shade2); + ge_shade_color(&fill, SHADE_BOTTOM, &shade3); + + cairo_pattern_add_color_stop_rgb(pattern, 0, shade1.r, shade1.g, shade1.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, shade2.r, shade2.g, shade2.b); + cairo_pattern_add_color_stop_rgb(pattern, 0.5, fill.r, fill.g, fill.b); + cairo_pattern_add_color_stop_rgb(pattern, 1.0, shade3.r, shade3.g, shade3.b); cairo_set_source (cr, pattern); cairo_fill (cr); cairo_pattern_destroy (pattern); - widget->style_functions->draw_top_left_highlight (cr, &fill, widget, 1, 1, width - 2, height - 2, - radius, corners); + cairo_translate (cr, 0.5, 0.5); + clearlooks_gummy_draw_top_left_highlight (cr, &fill, widget, width, height, (stepper->stepper == CL_STEPPER_A) ? radius : 0); + cairo_translate (cr, -0.5, -0.5); ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); clearlooks_set_mixed_color (cr, border, &fill, 0.2); cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; } static void @@ -1088,7 +1044,7 @@ clearlooks_gummy_draw_scrollbar_slider (cairo_t *cr, cairo_set_line_width (cr, 1); - ge_shade_color (&fill, widget->style_constants->topleft_highlight_shade, &hilight); + ge_shade_color (&fill, TOPLEFT_HIGHLIGHT_SHADE, &hilight); ge_shade_color (&fill, SHADE_TOP, &shade1); ge_shade_color (&fill, SHADE_CENTER_TOP, &shade2); ge_shade_color (&fill, SHADE_BOTTOM, &shade3); @@ -1103,7 +1059,7 @@ clearlooks_gummy_draw_scrollbar_slider (cairo_t *cr, cairo_fill (cr); cairo_pattern_destroy (pattern); - if (scrollbar->has_color) + if (scrollbar->has_color) { cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.2); ge_cairo_stroke_rectangle (cr, 1.5, 1.5, width-3, height-3); @@ -1113,8 +1069,8 @@ clearlooks_gummy_draw_scrollbar_slider (cairo_t *cr, cairo_move_to (cr, 1.5, height-1.5); cairo_line_to (cr, 1.5, 1.5); cairo_line_to (cr, width-1.5, 1.5); - cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, widget->style_constants->topleft_highlight_alpha); - cairo_stroke (cr); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, TOPLEFT_HIGHLIGHT_ALPHA); + cairo_stroke(cr); } ge_cairo_set_color (cr, &border); @@ -1174,7 +1130,7 @@ clearlooks_gummy_draw_list_view_header (cairo_t *cr, cairo_pattern_destroy (pattern); /* Draw highlight */ - if (header->order & CL_ORDER_FIRST) + if (header->order == CL_ORDER_FIRST) { cairo_move_to (cr, 0.5, height-1.5); cairo_line_to (cr, 0.5, 0.5); @@ -1188,8 +1144,8 @@ clearlooks_gummy_draw_list_view_header (cairo_t *cr, cairo_stroke (cr); /* Draw resize grip */ - if ((params->ltr && !(header->order & CL_ORDER_LAST)) || - (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable) + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) { SeparatorParameters separator; separator.horizontal = FALSE; @@ -1250,14 +1206,14 @@ clearlooks_gummy_draw_toolbar (cairo_t *cr, { /* Draw highlight */ cairo_move_to (cr, 0, 0.5); - cairo_line_to (cr, width-0.5, 0.5); + cairo_line_to (cr, width-1, 0.5); ge_cairo_set_color (cr, &light); cairo_stroke (cr); } /* Draw shadow */ cairo_move_to (cr, 0, height-0.5); - cairo_line_to (cr, width-0.5, height-0.5); + cairo_line_to (cr, width-1, height-0.5); ge_cairo_set_color (cr, dark); cairo_stroke (cr); } @@ -1287,7 +1243,7 @@ clearlooks_gummy_draw_menuitem (cairo_t *cr, cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); cairo_set_source (cr, pattern); - cairo_fill_preserve (cr); + cairo_fill_preserve (cr); cairo_pattern_destroy (pattern); ge_cairo_set_color (cr, border); @@ -1319,7 +1275,7 @@ clearlooks_gummy_draw_menubaritem (cairo_t *cr, cairo_pattern_add_color_stop_rgb (pattern, 1, shade3.r, shade3.g, shade3.b); cairo_set_source (cr, pattern); - cairo_fill_preserve (cr); + cairo_fill_preserve (cr); cairo_pattern_destroy (pattern); ge_cairo_set_color (cr, border); @@ -1381,13 +1337,6 @@ clearlooks_gummy_draw_radiobutton (cairo_t *cr, cairo_pattern_t *pt; gboolean inconsistent; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); - gdouble w, h, cx, cy, radius; - - w = (gdouble) width; - h = (gdouble) height; - cx = width / 2.0; - cy = height / 2.0; - radius = MIN (width, height) / 2.0; inconsistent = (checkbox->shadow_type == GTK_SHADOW_ETCHED_IN); draw_bullet |= inconsistent; @@ -1409,7 +1358,7 @@ clearlooks_gummy_draw_radiobutton (cairo_t *cr, ge_shade_color (&widget->parentbg, 0.9, &shadow); ge_shade_color (&widget->parentbg, 1.1, &highlight); - pt = cairo_pattern_create_linear (0, 0, radius * 2.0, radius * 2.0); + pt = cairo_pattern_create_linear (0, 0, 13, 13); cairo_pattern_add_color_stop_rgb (pt, 0.0, shadow.r, shadow.b, shadow.g); cairo_pattern_add_color_stop_rgba (pt, 0.5, shadow.r, shadow.b, shadow.g, 0.5); cairo_pattern_add_color_stop_rgba (pt, 0.5, highlight.r, highlight.g, highlight.b, 0.5); @@ -1417,15 +1366,15 @@ clearlooks_gummy_draw_radiobutton (cairo_t *cr, cairo_translate (cr, x, y); - cairo_set_line_width (cr, MAX (1.0, floor (radius/3))); - cairo_arc (cr, ceil (cx), ceil (cy), floor (radius - 0.1), 0, G_PI*2); + cairo_set_line_width (cr, 2); + cairo_arc (cr, 7, 7, 6, 0, G_PI*2); cairo_set_source (cr, pt); cairo_stroke (cr); cairo_pattern_destroy (pt); - cairo_set_line_width (cr, MAX (1.0, floor (radius/6))); + cairo_set_line_width (cr, 1); - cairo_arc (cr, ceil (cx), ceil (cy), MAX (1.0, ceil (radius) - 1.5), 0, G_PI*2); + cairo_arc (cr, 7, 7, 5.5, 0, G_PI*2); if (!widget->disabled) { @@ -1444,21 +1393,21 @@ clearlooks_gummy_draw_radiobutton (cairo_t *cr, if (inconsistent) { cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_width (cr, ceil (radius * 2 / 3)); + cairo_set_line_width (cr, 4); - cairo_move_to (cr, ceil (cx - radius/3.0), ceil (cy)); - cairo_line_to (cr, ceil (cx + radius/3.0), ceil (cy)); + cairo_move_to(cr, 5, 7); + cairo_line_to(cr, 9, 7); ge_cairo_set_color (cr, dot); cairo_stroke (cr); } else { - cairo_arc (cr, ceil (cx), ceil (cy), floor (radius/2.0), 0, G_PI*2); + cairo_arc (cr, 7, 7, 3, 0, G_PI*2); ge_cairo_set_color (cr, dot); cairo_fill (cr); - cairo_arc (cr, floor (cx - radius/10.0), floor (cy - radius/10.0), floor (radius/6.0), 0, G_PI*2); + cairo_arc (cr, 6, 6, 1, 0, G_PI*2); cairo_set_source_rgba (cr, highlight.r, highlight.g, highlight.b, 0.5); cairo_fill (cr); } @@ -1473,7 +1422,7 @@ clearlooks_gummy_draw_checkbox (cairo_t *cr, int x, int y, int width, int height) { const CairoColor *border; - const CairoColor *dot; + const CairoColor *dot; gboolean inconsistent = FALSE; gboolean draw_bullet = (checkbox->shadow_type == GTK_SHADOW_IN); @@ -1489,7 +1438,7 @@ clearlooks_gummy_draw_checkbox (cairo_t *cr, { if (widget->prelight) border = &colors->spot[2]; - else + else border = &colors->shade[6]; dot = &colors->text[GTK_STATE_NORMAL]; } @@ -1499,25 +1448,25 @@ clearlooks_gummy_draw_checkbox (cairo_t *cr, if (widget->xthickness > 2 && widget->ythickness > 2) { - widget->style_functions->draw_inset (cr, &widget->parentbg, 0, 0, - width, height, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); - + widget->style_functions->draw_inset (cr, &widget->parentbg, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + /* Draw the rectangle for the checkbox itself */ - ge_cairo_rounded_rectangle (cr, 1.5, 1.5, - width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + ge_cairo_rounded_rectangle (cr, 1.5, 1.5, + width-3, height-3, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); } else { /* Draw the rectangle for the checkbox itself */ - ge_cairo_rounded_rectangle (cr, 0.5, 0.5, - width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, + width-1, height-1, (widget->radius > 0)? 1 : 0, CR_CORNER_ALL); } - + if (!widget->disabled) - { + { if (widget->prelight) clearlooks_set_mixed_color (cr, &colors->base[0], &colors->spot[1], 0.5); - else + else ge_cairo_set_color (cr, &colors->base[0]); cairo_fill_preserve (cr); } @@ -1542,6 +1491,7 @@ clearlooks_gummy_draw_checkbox (cairo_t *cr, cairo_curve_to (cr, 0.5 + (width*0.4), (height*0.7), 0.5 + (width*0.5), (height*0.4), 0.5 + (width*0.70), (height*0.25)); + } ge_cairo_set_color (cr, dot); @@ -1549,160 +1499,26 @@ clearlooks_gummy_draw_checkbox (cairo_t *cr, } } -static void -clearlooks_gummy_draw_focus (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const FocusParameters *focus, - int x, int y, int width, int height) -{ - CairoColor fill = focus->color; - CairoColor fill_shade1, fill_shade2, fill_shade3; - CairoColor border; - CairoColor parentbg = widget->parentbg; - - /* Default values */ - double xoffset = 1.5; - double yoffset = 1.5; - double radius = widget->radius-1.0; - double border_alpha = 0.64; - double fill_alpha = 0.18; - double shadow_alpha = 0.5; - boolean focus_fill = TRUE; - boolean focus_border = TRUE; - boolean focus_shadow = FALSE; - - ge_shade_color (&fill, 0.65, &border); - ge_shade_color (&fill, 1.18, &fill_shade1); - ge_shade_color (&fill, 1.02, &fill_shade2); - ge_shade_color (&fill, 0.84, &fill_shade3); - - /* Do some useful things to adjust focus */ - switch (focus->type) - { - case CL_FOCUS_BUTTON: - xoffset = -1.5-(focus->padding); - yoffset = -1.5-(focus->padding); - radius++; - border_alpha = 0.9; - fill_alpha = 0.12; - if (!widget->active) - focus_shadow = TRUE; - break; - case CL_FOCUS_BUTTON_FLAT: - xoffset = -1.5-(focus->padding); - yoffset = -1.5-(focus->padding); - radius++; - if (widget->active || widget->prelight) - { - border_alpha = 0.9; - fill_alpha = 0.12; - if (!widget->active) - focus_shadow = TRUE; - } - break; - case CL_FOCUS_LABEL: - xoffset = 0.5; - yoffset = 0.5; - break; - case CL_FOCUS_TREEVIEW: - parentbg = colors->base[widget->state_type]; - xoffset = -1.5; - yoffset = -1.5; - fill_alpha = 0.08; - focus_border = FALSE; - break; - case CL_FOCUS_TREEVIEW_DND: - parentbg = colors->base[widget->state_type]; - break; - case CL_FOCUS_TREEVIEW_HEADER: - cairo_translate (cr, -1, 0); - break; - case CL_FOCUS_TREEVIEW_ROW: - parentbg = colors->base[widget->state_type]; - xoffset = -2.5; /* hack to hide vertical lines */ - yoffset = 0.5; - radius = CLAMP (radius, 0.0, 2.0); - border_alpha = 0.7; - focus_fill = FALSE; - break; - case CL_FOCUS_TAB: - /* In current GTK+ focus and active cannot happen together, but we are robust against it. - * IF the application sets the state to ACTIVE while drawing the tabs focus. */ - if (widget->focus && !widget->active) - return; - break; - case CL_FOCUS_SCALE: - break; - case CL_FOCUS_UNKNOWN: - /* Fallback to classic function, dots */ - clearlooks_draw_focus (cr, colors, widget, focus, x, y, width, height); - return; - break; - default: - break; - }; - - cairo_translate (cr, x, y); - cairo_set_line_width (cr, focus->line_width); - - ge_cairo_rounded_rectangle (cr, xoffset, yoffset, width-(xoffset*2), height-(yoffset*2), radius, widget->corners); - - if (focus_fill) - { - cairo_pattern_t *pattern; - - pattern = cairo_pattern_create_linear (0, 0, 0, height); - cairo_pattern_add_color_stop_rgba (pattern, 0.0, fill_shade1.r, fill_shade1.g, fill_shade1.b, fill_alpha); - cairo_pattern_add_color_stop_rgba (pattern, 0.5, fill_shade2.r, fill_shade2.g, fill_shade2.b, fill_alpha); - cairo_pattern_add_color_stop_rgba (pattern, 0.5, fill.r, fill.g, fill.b, fill_alpha); - cairo_pattern_add_color_stop_rgba (pattern, 1.0, fill_shade3.r, fill_shade3.g, fill_shade3.b, fill_alpha); - cairo_set_source (cr, pattern); - cairo_fill_preserve (cr); - - cairo_pattern_destroy (pattern); - } - - if (focus_border) - { - clearlooks_set_mixed_color (cr, &parentbg, &border, border_alpha); - cairo_stroke (cr); - } - - if (focus_shadow) - { - if (radius > 0) - radius++; - ge_cairo_rounded_rectangle (cr, xoffset-1, yoffset-1, width-(xoffset*2)+2, height-(yoffset*2)+2, radius, widget->corners); - clearlooks_set_mixed_color (cr, &parentbg, &fill, shadow_alpha); - cairo_stroke (cr); - } -} - void -clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants) +clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions) { - functions->draw_button = clearlooks_gummy_draw_button; - functions->draw_entry = clearlooks_gummy_draw_entry; - functions->draw_progressbar_trough = clearlooks_gummy_draw_progressbar_trough; - functions->draw_progressbar_fill = clearlooks_gummy_draw_progressbar_fill; - functions->draw_scale_trough = clearlooks_gummy_draw_scale_trough; - functions->draw_tab = clearlooks_gummy_draw_tab; - functions->draw_separator = clearlooks_gummy_draw_separator; - functions->draw_slider = clearlooks_gummy_draw_slider; - functions->draw_slider_button = clearlooks_gummy_draw_slider_button; - functions->draw_scrollbar_stepper = clearlooks_gummy_draw_scrollbar_stepper; - functions->draw_scrollbar_slider = clearlooks_gummy_draw_scrollbar_slider; - functions->draw_list_view_header = clearlooks_gummy_draw_list_view_header; - functions->draw_toolbar = clearlooks_gummy_draw_toolbar; - functions->draw_menuitem = clearlooks_gummy_draw_menuitem; - functions->draw_menubaritem = clearlooks_gummy_draw_menubaritem; - functions->draw_selected_cell = clearlooks_gummy_draw_selected_cell; - functions->draw_statusbar = clearlooks_gummy_draw_statusbar; - functions->draw_checkbox = clearlooks_gummy_draw_checkbox; - functions->draw_radiobutton = clearlooks_gummy_draw_radiobutton; - functions->draw_focus = clearlooks_gummy_draw_focus; - - constants->topleft_highlight_shade = 1.3; - constants->topleft_highlight_alpha = 0.4; + functions->draw_button = clearlooks_gummy_draw_button; + functions->draw_entry = clearlooks_gummy_draw_entry; + functions->draw_progressbar_trough = clearlooks_gummy_draw_progressbar_trough; + functions->draw_progressbar_fill = clearlooks_gummy_draw_progressbar_fill; + functions->draw_scale_trough = clearlooks_gummy_draw_scale_trough; + functions->draw_tab = clearlooks_gummy_draw_tab; + functions->draw_separator = clearlooks_gummy_draw_separator; + functions->draw_slider = clearlooks_gummy_draw_slider; + functions->draw_slider_button = clearlooks_gummy_draw_slider_button; + functions->draw_scrollbar_stepper = clearlooks_gummy_draw_scrollbar_stepper; + functions->draw_scrollbar_slider = clearlooks_gummy_draw_scrollbar_slider; + functions->draw_list_view_header = clearlooks_gummy_draw_list_view_header; + functions->draw_toolbar = clearlooks_gummy_draw_toolbar; + functions->draw_menuitem = clearlooks_gummy_draw_menuitem; + functions->draw_menubaritem = clearlooks_gummy_draw_menubaritem; + functions->draw_selected_cell = clearlooks_gummy_draw_selected_cell; + functions->draw_statusbar = clearlooks_gummy_draw_statusbar; + functions->draw_checkbox = clearlooks_gummy_draw_checkbox; + functions->draw_radiobutton = clearlooks_gummy_draw_radiobutton; } diff --git a/libs/clearlooks/clearlooks_draw_inverted.c b/libs/clearlooks-newer/clearlooks_draw_inverted.c index 1bfff6d206..2e8ee3bcd7 100644 --- a/libs/clearlooks/clearlooks_draw_inverted.c +++ b/libs/clearlooks-newer/clearlooks_draw_inverted.c @@ -30,6 +30,29 @@ static void +clearlooks_draw_top_left_highlight (cairo_t *cr, + const CairoColor *color, + const WidgetParameters *params, + int width, int height, gdouble radius) +{ + CairoColor hilight; + + double light_top = params->ythickness-1, + light_bottom = height - params->ythickness - 1, + light_left = params->xthickness-1, + light_right = width - params->xthickness - 1; + + ge_shade_color (color, 1.3, &hilight); + cairo_move_to (cr, light_left, light_bottom - (int)radius/2); + + ge_cairo_rounded_corner (cr, light_left, light_top, radius, params->corners & CR_CORNER_TOPLEFT); + + cairo_line_to (cr, light_right - (int)radius/2, light_top); + cairo_set_source_rgba (cr, hilight.r, hilight.g, hilight.b, 0.7); + cairo_stroke (cr); +} + +static void clearlooks_set_border_gradient (cairo_t *cr, const CairoColor *color, double hilight, int width, int height) { cairo_pattern_t *pattern; @@ -78,7 +101,9 @@ clearlooks_inverted_draw_button (cairo_t *cr, if (params->xthickness == 3 || params->ythickness == 3) { - params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width, height, radius+1, params->corners); + cairo_translate (cr, 0.5, 0.5); + params->style_functions->draw_inset (cr, ¶ms->parentbg, 0, 0, width-1, height-1, radius+1, params->corners); + cairo_translate (cr, -0.5, -0.5); } ge_cairo_rounded_rectangle (cr, xoffset+1, yoffset+1, @@ -160,17 +185,15 @@ clearlooks_inverted_draw_button (cairo_t *cr, /* Draw the "shadow" */ if (!params->active) { + cairo_translate (cr, 0.5, 0.5); /* Draw right shadow */ - cairo_move_to (cr, width-xoffset-1.5, yoffset + radius); - cairo_line_to (cr, width-xoffset-1.5, height - yoffset - radius); + cairo_move_to (cr, width-params->xthickness, params->ythickness - 1); + cairo_line_to (cr, width-params->xthickness, height - params->ythickness - 1); cairo_set_source_rgba (cr, shadow.r, shadow.g, shadow.b, 0.1); cairo_stroke (cr); /* Draw topleft shadow */ - params->style_functions->draw_top_left_highlight (cr, fill, params, - xoffset+1, yoffset+1, - width-2*(xoffset+1), height-2*(yoffset+1), - radius, params->corners); + clearlooks_draw_top_left_highlight (cr, fill, params, width, height, radius); } cairo_restore (cr); } @@ -413,7 +436,6 @@ clearlooks_inverted_draw_tab (cairo_t *cr, double radius; double strip_size; - double length; radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); @@ -432,7 +454,6 @@ clearlooks_inverted_draw_tab (cairo_t *cr, if (tab->gap_side == CL_GAP_TOP || tab->gap_side == CL_GAP_BOTTOM) { height += 3.0; - length = height; strip_size = 2.0/height; /* 2 pixel high strip */ if (tab->gap_side == CL_GAP_TOP) @@ -441,7 +462,6 @@ clearlooks_inverted_draw_tab (cairo_t *cr, else { width += 3.0; - length = width; strip_size = 2.0/width; if (tab->gap_side == CL_GAP_LEFT) @@ -476,23 +496,10 @@ clearlooks_inverted_draw_tab (cairo_t *cr, if (params->active) { - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0, height-2, 0, 0); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0, 1, 0, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 0, 1, 0); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (1, 0, width-2, 0); - break; - default: - pattern = NULL; - } + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-1 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 1, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); @@ -509,23 +516,10 @@ clearlooks_inverted_draw_tab (cairo_t *cr, else { /* Draw shade */ - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (0, height-2, 0, 0); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (0, 0, 0, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 0, 0, 0); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (0, 0, width, 0); - break; - default: - pattern = NULL; - } + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 0, + tab->gap_side == CL_GAP_TOP ? height-2 : 0, + tab->gap_side == CL_GAP_RIGHT ? width : 0, + tab->gap_side == CL_GAP_BOTTOM ? height : 0 ); ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); @@ -548,23 +542,10 @@ clearlooks_inverted_draw_tab (cairo_t *cr, } else { - switch (tab->gap_side) - { - case CL_GAP_TOP: - pattern = cairo_pattern_create_linear (2, height-2, 2, 2); - break; - case CL_GAP_BOTTOM: - pattern = cairo_pattern_create_linear (2, 2, 2, height); - break; - case CL_GAP_LEFT: - pattern = cairo_pattern_create_linear (width-2, 2, 2, 2); - break; - case CL_GAP_RIGHT: - pattern = cairo_pattern_create_linear (2, 2, width, 2); - break; - default: - pattern = NULL; - } + pattern = cairo_pattern_create_linear ( tab->gap_side == CL_GAP_LEFT ? width-2 : 2, + tab->gap_side == CL_GAP_TOP ? height-2 : 2, + tab->gap_side == CL_GAP_RIGHT ? width : 2, + tab->gap_side == CL_GAP_BOTTOM ? height : 2 ); cairo_pattern_add_color_stop_rgb (pattern, 0.0, stripe_border->r, stripe_border->g, stripe_border->b); cairo_pattern_add_color_stop_rgb (pattern, strip_size, stripe_border->r, stripe_border->g, stripe_border->b); @@ -600,7 +581,7 @@ clearlooks_inverted_draw_slider (cairo_t *cr, border = &colors->shade[6]; /* fill the widget */ - cairo_rectangle (cr, 1.0, 1.0, width-2, height-2); + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); /* Fake light */ if (!params->disabled) @@ -618,20 +599,20 @@ clearlooks_inverted_draw_slider (cairo_t *cr, else { ge_cairo_set_color (cr, fill); - cairo_rectangle (cr, 1.0, 1.0, width-2, height-2); + cairo_rectangle (cr, 0.5, 0.5, width-2, height-2); cairo_fill (cr); } /* Set the clip */ cairo_save (cr); - cairo_rectangle (cr, 1.0, 1.0, 6, height-2); - cairo_rectangle (cr, width-7.0, 1.0, 6, height-2); + cairo_rectangle (cr, 0.5, 0.5, 6, height-2); + cairo_rectangle (cr, width-7.5, 0.5, 6 , height-2); cairo_clip_preserve (cr); cairo_new_path (cr); /* Draw the handles */ - ge_cairo_rounded_rectangle (cr, 1.0, 1.0, width-1, height-1, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, params->corners); pattern = cairo_pattern_create_linear (0.5, 0.5, 0.5, 0.5+height); if (params->prelight) @@ -654,7 +635,7 @@ clearlooks_inverted_draw_slider (cairo_t *cr, cairo_restore (cr); /* Draw the border */ - ge_cairo_inner_rounded_rectangle (cr, 0, 0, width, height, radius, params->corners); + ge_cairo_rounded_rectangle (cr, 0, 0, width-1, height-1, radius, params->corners); if (params->prelight || params->disabled) ge_cairo_set_color (cr, border); else @@ -664,11 +645,11 @@ clearlooks_inverted_draw_slider (cairo_t *cr, /* Draw handle lines */ if (width > 14) { - cairo_move_to (cr, 6.5, 1.0); - cairo_line_to (cr, 6.5, height-1); + cairo_move_to (cr, 6, 0.5); + cairo_line_to (cr, 6, height-1); - cairo_move_to (cr, width-6.5, 1.0); - cairo_line_to (cr, width-6.5, height-1); + cairo_move_to (cr, width-7, 0.5); + cairo_line_to (cr, width-7, height-1); cairo_set_line_width (cr, 1.0); cairo_set_source_rgba (cr, border->r, @@ -680,6 +661,27 @@ clearlooks_inverted_draw_slider (cairo_t *cr, } static void +clearlooks_inverted_draw_slider_button (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *params, + const SliderParameters *slider, + int x, int y, int width, int height) +{ + double radius = MIN (params->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); + cairo_set_line_width (cr, 1.0); + + if (!slider->horizontal) + ge_cairo_exchange_axis (cr, &x, &y, &width, &height); + cairo_translate (cr, x+0.5, y+0.5); + + params->style_functions->draw_shadow (cr, colors, radius, width-1, height-1); + params->style_functions->draw_slider (cr, colors, params, 1, 1, width-2, height-2); + + if (width > 24) + params->style_functions->draw_gripdots (cr, colors, 0, 0, width-2, height-2, 3, 3, 0); +} + +static void clearlooks_inverted_draw_list_view_header (cairo_t *cr, const ClearlooksColors *colors, const WidgetParameters *params, @@ -701,7 +703,7 @@ clearlooks_inverted_draw_list_view_header (cairo_t *cr, cairo_set_line_width (cr, 1.0); /* Draw highlight */ - if (header->order & CL_ORDER_FIRST) + if (header->order == CL_ORDER_FIRST) { cairo_move_to (cr, 0.5, height-1); cairo_line_to (cr, 0.5, 0.5); @@ -731,8 +733,8 @@ clearlooks_inverted_draw_list_view_header (cairo_t *cr, cairo_pattern_destroy (pattern); /* Draw resize grip */ - if ((params->ltr && !(header->order & CL_ORDER_LAST)) || - (!params->ltr && !(header->order & CL_ORDER_FIRST)) || header->resizable) + if ((params->ltr && header->order != CL_ORDER_LAST) || + (!params->ltr && header->order != CL_ORDER_FIRST) || header->resizable) { SeparatorParameters separator; separator.horizontal = FALSE; @@ -759,6 +761,7 @@ clearlooks_inverted_draw_scrollbar_stepper (cairo_t *cr, CairoColor border; CairoColor s1, s2, s3; cairo_pattern_t *pattern; + ShadowParameters shadow; double radius = MIN (widget->radius, MIN ((width - 2.0) / 2.0, (height - 2.0) / 2.0)); ge_shade_color(&colors->shade[6], 1.05, &border); @@ -798,11 +801,19 @@ clearlooks_inverted_draw_scrollbar_stepper (cairo_t *cr, cairo_fill (cr); cairo_pattern_destroy (pattern); - widget->style_functions->draw_top_left_highlight (cr, &s1, widget, 1, 1, width-2, height-2, radius, corners); + clearlooks_draw_top_left_highlight (cr, &s1, widget, width, height, radius); ge_cairo_rounded_rectangle (cr, 0.5, 0.5, width-1, height-1, radius, corners); clearlooks_set_border_gradient (cr, &border, 1.2, (scrollbar->horizontal ? 0 : width), (scrollbar->horizontal ? height: 0)); cairo_stroke (cr); + + cairo_translate (cr, 0.5, 0.5); + shadow.shadow = CL_SHADOW_OUT; + shadow.corners = corners; + /* + clearlooks_draw_highlight_and_shade (cr, &shadow, + width, + height, params->radius);*/ } static void @@ -898,7 +909,7 @@ clearlooks_inverted_draw_scrollbar_slider (cairo_t *cr, cairo_fill(cr); cairo_pattern_destroy(pattern); - widget->style_functions->draw_top_left_highlight (cr, &s2, widget, 1, 1, width-2, height-2, 0, widget->corners); + clearlooks_draw_top_left_highlight (cr, &s2, widget, width, height, 0); clearlooks_set_border_gradient (cr, &border, 1.2, 0, height); ge_cairo_stroke_rectangle (cr, 0.5, 0.5, width-1, height-1); @@ -974,10 +985,11 @@ clearlooks_inverted_draw_selected_cell (cairo_t *cr, } void -clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants) +clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions) { functions->draw_button = clearlooks_inverted_draw_button; functions->draw_slider = clearlooks_inverted_draw_slider; + functions->draw_slider_button = clearlooks_inverted_draw_slider_button; functions->draw_progressbar_fill = clearlooks_inverted_draw_progressbar_fill; functions->draw_menuitem = clearlooks_inverted_draw_menuitem; functions->draw_menubaritem = clearlooks_inverted_draw_menubaritem; @@ -986,8 +998,5 @@ clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions, Clearlo functions->draw_scrollbar_stepper = clearlooks_inverted_draw_scrollbar_stepper; functions->draw_scrollbar_slider = clearlooks_inverted_draw_scrollbar_slider; functions->draw_selected_cell = clearlooks_inverted_draw_selected_cell; - - constants->topleft_highlight_shade = 1.3; - constants->topleft_highlight_alpha = 0.7; } diff --git a/libs/clearlooks/clearlooks_rc_style.c b/libs/clearlooks-newer/clearlooks_rc_style.c index 14d405286f..f486453339 100644 --- a/libs/clearlooks/clearlooks_rc_style.c +++ b/libs/clearlooks-newer/clearlooks_rc_style.c @@ -1,7 +1,5 @@ /* Clearlooks theme engine - * Copyright (C) 2005 Richard Stellingwerff - * Copyright (C) 2007 Benjamin Berg - * Copyright (C) 2007 Andrea Cimitan + * Copyright (C) 2005 Richard Stellingwerff. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -24,32 +22,35 @@ * Modified by Kulyk Nazar <schamane@myeburg.net> */ -#include <string.h> -#include <widget-information.h> #include "clearlooks_style.h" #include "clearlooks_rc_style.h" #include "animation.h" +static void clearlooks_rc_style_init (ClearlooksRcStyle *style); #ifdef HAVE_ANIMATION static void clearlooks_rc_style_finalize (GObject *object); #endif +static void clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass); static GtkStyle *clearlooks_rc_style_create_style (GtkRcStyle *rc_style); static guint clearlooks_rc_style_parse (GtkRcStyle *rc_style, - GtkSettings *settings, - GScanner *scanner); + GtkSettings *settings, + GScanner *scanner); static void clearlooks_rc_style_merge (GtkRcStyle *dest, - GtkRcStyle *src); + GtkRcStyle *src); + + +static GtkRcStyleClass *clearlooks_parent_rc_class; + +GType clearlooks_type_rc_style = 0; enum { - TOKEN_FOCUSCOLOR = G_TOKEN_LAST + 1, - TOKEN_SCROLLBARCOLOR, + TOKEN_SCROLLBARCOLOR = G_TOKEN_LAST + 1, TOKEN_COLORIZESCROLLBAR, TOKEN_CONTRAST, TOKEN_SUNKENMENU, TOKEN_PROGRESSBARSTYLE, - TOKEN_RELIEFSTYLE, TOKEN_MENUBARSTYLE, TOKEN_TOOLBARSTYLE, TOKEN_MENUITEMSTYLE, @@ -57,7 +58,6 @@ enum TOKEN_ANIMATION, TOKEN_STYLE, TOKEN_RADIUS, - TOKEN_HINT, TOKEN_CLASSIC, TOKEN_GLOSSY, @@ -65,42 +65,60 @@ enum TOKEN_GUMMY, TOKEN_TRUE, - TOKEN_FALSE, + TOKEN_FALSE +}; - TOKEN_LAST +static struct +{ + const gchar *name; + guint token; +} +clearlooks_gtk2_rc_symbols[] = +{ + { "scrollbar_color", TOKEN_SCROLLBARCOLOR }, + { "colorize_scrollbar", TOKEN_COLORIZESCROLLBAR }, + { "contrast", TOKEN_CONTRAST }, + { "sunkenmenubar", TOKEN_SUNKENMENU }, + { "progressbarstyle", TOKEN_PROGRESSBARSTYLE }, + { "menubarstyle", TOKEN_MENUBARSTYLE }, + { "toolbarstyle", TOKEN_TOOLBARSTYLE }, + { "menuitemstyle", TOKEN_MENUITEMSTYLE }, + { "listviewitemstyle", TOKEN_LISTVIEWITEMSTYLE }, + { "animation", TOKEN_ANIMATION }, + { "style", TOKEN_STYLE }, + { "radius", TOKEN_RADIUS }, + + { "CLASSIC", TOKEN_CLASSIC }, + { "GLOSSY", TOKEN_GLOSSY }, + { "INVERTED", TOKEN_INVERTED }, + { "GUMMY", TOKEN_GUMMY }, + + { "TRUE", TOKEN_TRUE }, + { "FALSE", TOKEN_FALSE } }; -static gchar* clearlooks_rc_symbols = - "focus_color\0" - "scrollbar_color\0" - "colorize_scrollbar\0" - "contrast\0" - "sunkenmenubar\0" - "progressbarstyle\0" - "reliefstyle\0" - "menubarstyle\0" - "toolbarstyle\0" - "menuitemstyle\0" - "listviewitemstyle\0" - "animation\0" - "style\0" - "radius\0" - "hint\0" - - "CLASSIC\0" - "GLOSSY\0" - "INVERTED\0" - "GUMMY\0" - - "TRUE\0" - "FALSE\0"; - -G_DEFINE_DYNAMIC_TYPE (ClearlooksRcStyle, clearlooks_rc_style, GTK_TYPE_RC_STYLE) void -clearlooks_rc_style_register_types (GTypeModule *module) +clearlooks_rc_style_register_type (GTypeModule *module) { - clearlooks_rc_style_register_type (module); + static const GTypeInfo object_info = + { + sizeof (ClearlooksRcStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_rc_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksRcStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_rc_style_init, + NULL + }; + + clearlooks_type_rc_style = g_type_module_register_type (module, + GTK_TYPE_RC_STYLE, + "ClearlooksRcStyle", + &object_info, 0); } static void @@ -111,13 +129,11 @@ clearlooks_rc_style_init (ClearlooksRcStyle *clearlooks_rc) clearlooks_rc->flags = 0; clearlooks_rc->contrast = 1.0; - clearlooks_rc->reliefstyle = 0; clearlooks_rc->menubarstyle = 0; clearlooks_rc->toolbarstyle = 0; clearlooks_rc->animation = FALSE; clearlooks_rc->colorize_scrollbar = FALSE; clearlooks_rc->radius = 3.0; - clearlooks_rc->hint = 0; } #ifdef HAVE_ANIMATION @@ -127,8 +143,8 @@ clearlooks_rc_style_finalize (GObject *object) /* cleanup all the animation stuff */ clearlooks_animation_cleanup (); - if (G_OBJECT_CLASS (clearlooks_rc_style_parent_class)->finalize != NULL) - G_OBJECT_CLASS (clearlooks_rc_style_parent_class)->finalize (object); + if (G_OBJECT_CLASS (clearlooks_parent_rc_class)->finalize != NULL) + G_OBJECT_CLASS (clearlooks_parent_rc_class)->finalize(object); } #endif @@ -141,6 +157,8 @@ clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass) GObjectClass *g_object_class = G_OBJECT_CLASS (klass); #endif + clearlooks_parent_rc_class = g_type_class_peek_parent (klass); + rc_style_class->parse = clearlooks_rc_style_parse; rc_style_class->create_style = clearlooks_rc_style_create_style; rc_style_class->merge = clearlooks_rc_style_merge; @@ -150,15 +168,10 @@ clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass) #endif } -static void -clearlooks_rc_style_class_finalize (ClearlooksRcStyleClass *klass) -{ -} - static guint clearlooks_gtk2_rc_parse_boolean (GtkSettings *settings, - GScanner *scanner, - gboolean *retval) + GScanner *scanner, + gboolean *retval) { guint token; token = g_scanner_get_next_token(scanner); @@ -180,9 +193,8 @@ clearlooks_gtk2_rc_parse_boolean (GtkSettings *settings, static guint clearlooks_gtk2_rc_parse_color(GtkSettings *settings, - GScanner *scanner, - GtkRcStyle *style, - GdkColor *color) + GScanner *scanner, + GdkColor *color) { guint token; @@ -193,7 +205,7 @@ clearlooks_gtk2_rc_parse_color(GtkSettings *settings, if (token != G_TOKEN_EQUAL_SIGN) return G_TOKEN_EQUAL_SIGN; - return gtk_rc_parse_color_full (scanner, style, color); + return gtk_rc_parse_color (scanner, color); } static guint @@ -221,12 +233,12 @@ clearlooks_gtk2_rc_parse_double (GtkSettings *settings, static guint clearlooks_gtk2_rc_parse_int (GtkSettings *settings, - GScanner *scanner, - guint8 *progressbarstyle) + GScanner *scanner, + guint8 *progressbarstyle) { guint token; - /* Skip option name */ + /* Skip 'sunkenmenubar' */ token = g_scanner_get_next_token(scanner); token = g_scanner_get_next_token(scanner); @@ -259,7 +271,7 @@ clearlooks_gtk2_rc_parse_style (GtkSettings *settings, return G_TOKEN_EQUAL_SIGN; token = g_scanner_get_next_token (scanner); - + switch (token) { case TOKEN_CLASSIC: @@ -307,14 +319,16 @@ clearlooks_gtk2_rc_parse_dummy (GtkSettings *settings, static guint clearlooks_rc_style_parse (GtkRcStyle *rc_style, - GtkSettings *settings, - GScanner *scanner) + GtkSettings *settings, + GScanner *scanner) + { static GQuark scope_id = 0; ClearlooksRcStyle *clearlooks_style = CLEARLOOKS_RC_STYLE (rc_style); guint old_scope; guint token; + guint i; /* Set up a new scope in this scanner. */ @@ -330,18 +344,13 @@ clearlooks_rc_style_parse (GtkRcStyle *rc_style, * (in some previous call to clearlooks_rc_style_parse for the * same scanner. */ - if (!g_scanner_lookup_symbol(scanner, clearlooks_rc_symbols)) { - gchar *current_symbol = clearlooks_rc_symbols; - gint i = G_TOKEN_LAST + 1; - - /* Add our symbols */ - while ((current_symbol[0] != '\0') && (i < TOKEN_LAST)) { - g_scanner_scope_add_symbol(scanner, scope_id, current_symbol, GINT_TO_POINTER (i)); - current_symbol += strlen(current_symbol) + 1; - i++; - } - g_assert (i == TOKEN_LAST && current_symbol[0] == '\0'); + if (!g_scanner_lookup_symbol(scanner, clearlooks_gtk2_rc_symbols[0].name)) + { + for (i = 0; i < G_N_ELEMENTS (clearlooks_gtk2_rc_symbols); i++) + g_scanner_scope_add_symbol(scanner, scope_id, + clearlooks_gtk2_rc_symbols[i].name, + GINT_TO_POINTER(clearlooks_gtk2_rc_symbols[i].token)); } /* We're ready to go, now parse the top level */ @@ -351,12 +360,8 @@ clearlooks_rc_style_parse (GtkRcStyle *rc_style, { switch (token) { - case TOKEN_FOCUSCOLOR: - token = clearlooks_gtk2_rc_parse_color (settings, scanner, rc_style, &clearlooks_style->focus_color); - clearlooks_style->flags |= CL_FLAG_FOCUS_COLOR; - break; case TOKEN_SCROLLBARCOLOR: - token = clearlooks_gtk2_rc_parse_color (settings, scanner, rc_style, &clearlooks_style->scrollbar_color); + token = clearlooks_gtk2_rc_parse_color (settings, scanner, &clearlooks_style->scrollbar_color); clearlooks_style->flags |= CL_FLAG_SCROLLBAR_COLOR; break; case TOKEN_COLORIZESCROLLBAR: @@ -367,10 +372,6 @@ clearlooks_rc_style_parse (GtkRcStyle *rc_style, token = clearlooks_gtk2_rc_parse_double (settings, scanner, &clearlooks_style->contrast); clearlooks_style->flags |= CL_FLAG_CONTRAST; break; - case TOKEN_RELIEFSTYLE: - token = clearlooks_gtk2_rc_parse_int (settings, scanner, &clearlooks_style->reliefstyle); - clearlooks_style->flags |= CL_FLAG_RELIEFSTYLE; - break; case TOKEN_MENUBARSTYLE: token = clearlooks_gtk2_rc_parse_int (settings, scanner, &clearlooks_style->menubarstyle); clearlooks_style->flags |= CL_FLAG_MENUBARSTYLE; @@ -391,10 +392,6 @@ clearlooks_rc_style_parse (GtkRcStyle *rc_style, token = clearlooks_gtk2_rc_parse_double (settings, scanner, &clearlooks_style->radius); clearlooks_style->flags |= CL_FLAG_RADIUS; break; - case TOKEN_HINT: - token = ge_rc_parse_hint (scanner, &clearlooks_style->hint); - clearlooks_style->flags |= CL_FLAG_HINT; - break; /* stuff to ignore */ case TOKEN_SUNKENMENU: @@ -431,12 +428,12 @@ clearlooks_rc_style_parse (GtkRcStyle *rc_style, static void clearlooks_rc_style_merge (GtkRcStyle *dest, - GtkRcStyle *src) + GtkRcStyle *src) { ClearlooksRcStyle *dest_w, *src_w; ClearlooksRcFlags flags; - GTK_RC_STYLE_CLASS (clearlooks_rc_style_parent_class)->merge (dest, src); + clearlooks_parent_rc_class->merge (dest, src); if (!CLEARLOOKS_IS_RC_STYLE (src)) return; @@ -450,14 +447,10 @@ clearlooks_rc_style_merge (GtkRcStyle *dest, dest_w->style = src_w->style; if (flags & CL_FLAG_CONTRAST) dest_w->contrast = src_w->contrast; - if (flags & CL_FLAG_RELIEFSTYLE) - dest_w->reliefstyle = src_w->reliefstyle; if (flags & CL_FLAG_MENUBARSTYLE) dest_w->menubarstyle = src_w->menubarstyle; if (flags & CL_FLAG_TOOLBARSTYLE) dest_w->toolbarstyle = src_w->toolbarstyle; - if (flags & CL_FLAG_FOCUS_COLOR) - dest_w->focus_color = src_w->focus_color; if (flags & CL_FLAG_SCROLLBAR_COLOR) dest_w->scrollbar_color = src_w->scrollbar_color; if (flags & CL_FLAG_COLORIZE_SCROLLBAR) @@ -466,8 +459,6 @@ clearlooks_rc_style_merge (GtkRcStyle *dest, dest_w->animation = src_w->animation; if (flags & CL_FLAG_RADIUS) dest_w->radius = src_w->radius; - if (flags & CL_FLAG_HINT) - dest_w->hint = src_w->hint; dest_w->flags |= src_w->flags; } diff --git a/libs/clearlooks/clearlooks_rc_style.h b/libs/clearlooks-newer/clearlooks_rc_style.h index e48143bf40..a80a846000 100644 --- a/libs/clearlooks/clearlooks_rc_style.h +++ b/libs/clearlooks-newer/clearlooks_rc_style.h @@ -1,7 +1,5 @@ -/* Clearlooks theme engine - * Copyright (C) 2005 Richard Stellingwerff - * Copyright (C) 2007 Benjamin Berg - * Copyright (C) 2007 Andrea Cimitan +/* Clearlooks Theme Engine + * Copyright (C) 2005 Richard Stellingwerff. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -27,13 +25,12 @@ #include <gtk/gtkrc.h> #include "clearlooks_types.h" -#ifndef CLEARLOOKS_RC_STYLE_H -#define CLEARLOOKS_RC_STYLE_H - typedef struct _ClearlooksRcStyle ClearlooksRcStyle; typedef struct _ClearlooksRcStyleClass ClearlooksRcStyleClass; -#define CLEARLOOKS_TYPE_RC_STYLE (clearlooks_rc_style_get_type ()) +GE_INTERNAL extern GType clearlooks_type_rc_style; + +#define CLEARLOOKS_TYPE_RC_STYLE clearlooks_type_rc_style #define CLEARLOOKS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyle)) #define CLEARLOOKS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) #define CLEARLOOKS_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_RC_STYLE)) @@ -43,19 +40,15 @@ typedef struct _ClearlooksRcStyleClass ClearlooksRcStyleClass; /* XXX: needs fixing! */ typedef enum { CL_FLAG_STYLE = 1 << 0, - CL_FLAG_FOCUS_COLOR = 1 << 1, - CL_FLAG_SCROLLBAR_COLOR = 1 << 2, - CL_FLAG_COLORIZE_SCROLLBAR = 1 << 3, - CL_FLAG_CONTRAST = 1 << 4, - CL_FLAG_RELIEFSTYLE = 1 << 5, - CL_FLAG_MENUBARSTYLE = 1 << 6, - CL_FLAG_TOOLBARSTYLE = 1 << 7, - CL_FLAG_ANIMATION = 1 << 8, - CL_FLAG_RADIUS = 1 << 9, - CL_FLAG_HINT = 1 << 10 + CL_FLAG_SCROLLBAR_COLOR = 1 << 1, + CL_FLAG_COLORIZE_SCROLLBAR = 1 << 2, + CL_FLAG_CONTRAST = 1 << 3, + CL_FLAG_MENUBARSTYLE = 1 << 4, + CL_FLAG_TOOLBARSTYLE = 1 << 5, + CL_FLAG_ANIMATION = 1 << 6, + CL_FLAG_RADIUS = 1 << 7 } ClearlooksRcFlags; - struct _ClearlooksRcStyle { GtkRcStyle parent_instance; @@ -64,24 +57,18 @@ struct _ClearlooksRcStyle ClearlooksStyles style; - GdkColor focus_color; GdkColor scrollbar_color; gboolean colorize_scrollbar; double contrast; - guint8 reliefstyle; guint8 menubarstyle; guint8 toolbarstyle; gboolean animation; double radius; - GQuark hint; }; struct _ClearlooksRcStyleClass { - GtkRcStyleClass parent_class; + GtkRcStyleClass parent_class; }; -GE_INTERNAL void clearlooks_rc_style_register_types (GTypeModule *module); -GE_INTERNAL GType clearlooks_rc_style_get_type (void); - -#endif /* CLEARLOOKS_RC_STYLE_H */ +GE_INTERNAL void clearlooks_rc_style_register_type (GTypeModule *module); diff --git a/libs/clearlooks/clearlooks_style.c b/libs/clearlooks-newer/clearlooks_style.c index 4a7a75e072..48b6647df3 100644 --- a/libs/clearlooks/clearlooks_style.c +++ b/libs/clearlooks-newer/clearlooks_style.c @@ -1,7 +1,6 @@ /* Clearlooks theme engine - * Copyright (C) 2005 Richard Stellingwerff - * Copyright (C) 2007 Benjamin Berg - * Copyright (C) 2007 Andrea Cimitan + * Copyright (C) 2005 Richard Stellingwerff. + * Copyright (C) 2007 Benjamin Berg <benjamin@sipsolutions.net>. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,7 +33,6 @@ /* #define DEBUG 1 */ #define DETAIL(xx) ((detail) && (!strcmp(xx, detail))) -#define CHECK_HINT(xx) (ge_check_hint ((xx), CLEARLOOKS_RC_STYLE ((style)->rc_style)->hint, widget)) #define DRAW_ARGS GtkStyle *style, \ GdkWindow *window, \ @@ -52,9 +50,10 @@ #include "animation.h" #endif -#define STYLE_FUNCTION(function) (CLEARLOOKS_STYLE_GET_CLASS (style)->style_functions[CLEARLOOKS_STYLE (style)->style].function) +#define STYLE_FUNCTION(function) (clearlooks_style_class->style_functions[CLEARLOOKS_STYLE (style)->style].function) -G_DEFINE_DYNAMIC_TYPE (ClearlooksStyle, clearlooks_style, GTK_TYPE_STYLE) +static ClearlooksStyleClass *clearlooks_style_class; +static GtkStyleClass *clearlooks_parent_class; static void clearlooks_set_widget_parameters (const GtkWidget *widget, @@ -62,23 +61,25 @@ clearlooks_set_widget_parameters (const GtkWidget *widget, GtkStateType state_type, WidgetParameters *params) { - params->style_functions = &(CLEARLOOKS_STYLE_GET_CLASS (style)->style_functions[CLEARLOOKS_STYLE (style)->style]); - params->style_constants = &(CLEARLOOKS_STYLE_GET_CLASS (style)->style_constants[CLEARLOOKS_STYLE (style)->style]); - - params->active = (state_type == GTK_STATE_ACTIVE); - params->prelight = (state_type == GTK_STATE_PRELIGHT); - params->disabled = (state_type == GTK_STATE_INSENSITIVE); - params->state_type = (ClearlooksStateType)state_type; - params->corners = CR_CORNER_ALL; - params->ltr = ge_widget_is_ltr ((GtkWidget*)widget); - params->focus = widget && GTK_WIDGET_HAS_FOCUS (widget); - params->is_default = widget && GE_WIDGET_HAS_DEFAULT (widget); - params->enable_shadow = FALSE; - params->radius = CLEARLOOKS_STYLE (style)->radius; - - params->xthickness = style->xthickness; - params->ythickness = style->ythickness; - + params->style_functions = &(clearlooks_style_class->style_functions[CLEARLOOKS_STYLE (style)->style]); + + params->active = (state_type == GTK_STATE_ACTIVE); + params->prelight = (state_type == GTK_STATE_PRELIGHT); + params->disabled = (state_type == GTK_STATE_INSENSITIVE); + params->state_type = (ClearlooksStateType)state_type; + params->corners = CR_CORNER_ALL; + params->ltr = ge_widget_is_ltr ((GtkWidget*)widget); + params->focus = widget && GTK_WIDGET_HAS_FOCUS (widget); + params->is_default = widget && GE_WIDGET_HAS_DEFAULT (widget); + params->enable_glow = FALSE; + params->radius = CLEARLOOKS_STYLE (style)->radius; + + if (!params->active && widget && GE_IS_TOGGLE_BUTTON (widget)) + params->active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + params->xthickness = style->xthickness; + params->ythickness = style->ythickness; + /* This is used in GtkEntry to fake transparency. The reason to do this * is that the entry has it's entire background filled with base[STATE]. * This is not a very good solution as it will eg. fail if one changes @@ -90,7 +91,7 @@ clearlooks_set_widget_parameters (const GtkWidget *widget, static void clearlooks_style_draw_flat_box (DRAW_ARGS) { - if (detail && + if (detail && state_type == GTK_STATE_SELECTED && ( !strncmp ("cell_even", detail, 9) || !strncmp ("cell_odd", detail, 8))) @@ -140,10 +141,10 @@ clearlooks_style_draw_flat_box (DRAW_ARGS) } else { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_flat_box (style, window, state_type, - shadow_type, - area, widget, detail, - x, y, width, height); + clearlooks_parent_class->draw_flat_box (style, window, state_type, + shadow_type, + area, widget, detail, + x, y, width, height); } } @@ -157,83 +158,65 @@ clearlooks_style_draw_shadow (DRAW_ARGS) CHECK_ARGS SANITIZE_SIZE - /* The "frame" thing is a hack because of GtkCombo. */ - if ((DETAIL ("entry") && !CHECK_HINT (GE_HINT_TREEVIEW)) || - (DETAIL ("frame") && CHECK_HINT (GE_HINT_COMBOBOX_ENTRY))) + if ((DETAIL ("entry") && !(widget && widget->parent && GE_IS_TREE_VIEW (widget->parent))) || + (DETAIL ("frame") && ge_is_in_combo_box (widget))) { WidgetParameters params; + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); /* Override the entries state type, because we are too lame to handle this via * the focus ring, and GtkEntry doesn't even set the INSENSITIVE state ... */ if (state_type == GTK_STATE_NORMAL && widget && GE_IS_ENTRY (widget)) - state_type = GTK_WIDGET_STATE (widget); + params.state_type = GTK_WIDGET_STATE (widget); - clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - - if (CHECK_HINT (GE_HINT_COMBOBOX_ENTRY) || CHECK_HINT (GE_HINT_SPINBUTTON)) + if (widget && (ge_is_in_combo_box (widget) || GE_IS_SPIN_BUTTON (widget))) { width += style->xthickness; if (!params.ltr) x -= style->xthickness; - + if (params.ltr) params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; else params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; } - /* Fill the background as it is initilized to base[NORMAL]. - * Relevant GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=513471 - * The fill only happens if no hint has been added by some application - * that is faking GTK+ widgets. */ - if (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint")) - { - cairo_rectangle (cr, 0, 0, width, height); - ge_cairo_set_color (cr, ¶ms.parentbg); - cairo_fill (cr); - } - STYLE_FUNCTION (draw_entry) (cr, &clearlooks_style->colors, ¶ms, - x, y, width, height); + x, y, width, height); } - else if (DETAIL ("frame") && CHECK_HINT (GE_HINT_STATUSBAR)) + else if (DETAIL ("frame") && widget && GE_IS_STATUSBAR (widget->parent)) { WidgetParameters params; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); gtk_style_apply_default_background (style, window, TRUE, state_type, area, x, y, width, height); - if (shadow_type != GTK_SHADOW_NONE) - STYLE_FUNCTION (draw_statusbar) (cr, colors, ¶ms, - x, y, width, height); + + STYLE_FUNCTION (draw_statusbar) (cr, colors, ¶ms, + x, y, width, height); } - else if (DETAIL ("frame") || DETAIL ("calendar")) + else if (DETAIL ("frame")) { WidgetParameters params; FrameParameters frame; frame.shadow = shadow_type; - frame.gap_x = -1; /* No gap will be drawn */ + frame.gap_x = -1; /* No gap will be drawn */ frame.border = &colors->shade[4]; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); params.corners = CR_CORNER_NONE; - + if (widget && !g_str_equal ("XfcePanelWindow", gtk_widget_get_name (gtk_widget_get_toplevel (widget)))) STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, - x, y, width, height); + x, y, width, height); } else if (DETAIL ("scrolled_window") || DETAIL ("viewport") || detail == NULL) { - CairoColor border; - - if (CLEARLOOKS_STYLE (style)->style == CL_STYLE_CLASSIC) - ge_shade_color ((CairoColor*)&colors->bg[0], 0.78, &border); - else - border = colors->shade[5]; - + CairoColor *border = (CairoColor*)&colors->shade[5]; cairo_rectangle (cr, x+0.5, y+0.5, width-1, height-1); - ge_cairo_set_color (cr, &border); + ge_cairo_set_color (cr, border); cairo_set_line_width (cr, 1); cairo_stroke (cr); } @@ -247,18 +230,18 @@ clearlooks_style_draw_shadow (DRAW_ARGS) frame.border = &colors->shade[5]; clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); params.corners = CR_CORNER_ALL; - + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, x, y, width, height); } - + cairo_destroy (cr); } -static void +static void clearlooks_style_draw_box_gap (DRAW_ARGS, - GtkPositionType gap_side, - gint gap_x, - gint gap_width) + GtkPositionType gap_side, + gint gap_x, + gint gap_width) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); ClearlooksColors *colors = &clearlooks_style->colors; @@ -274,30 +257,38 @@ clearlooks_style_draw_box_gap (DRAW_ARGS, WidgetParameters params; FrameParameters frame; gboolean start, end; - + frame.shadow = shadow_type; frame.gap_side = gap_side; frame.gap_x = gap_x; frame.gap_width = gap_width; frame.border = &colors->shade[5]; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); clearlooks_get_notebook_tab_position (widget, &start, &end); params.corners = CR_CORNER_ALL; - switch (gap_side) - { + switch (gap_side) { + case GTK_POS_LEFT: + if (start) + params.corners ^= CR_CORNER_TOPLEFT; + if (end) + params.corners ^= CR_CORNER_BOTTOMLEFT; + break; + case GTK_POS_RIGHT: + if (start) + params.corners ^= CR_CORNER_TOPRIGHT; + if (end) + params.corners ^= CR_CORNER_BOTTOMRIGHT; + break; case GTK_POS_TOP: - if (ge_widget_is_ltr (widget)) - { + if (ge_widget_is_ltr (widget)) { if (start) params.corners ^= CR_CORNER_TOPLEFT; if (end) params.corners ^= CR_CORNER_TOPRIGHT; - } - else - { + } else { if (start) params.corners ^= CR_CORNER_TOPRIGHT; if (end) @@ -305,52 +296,37 @@ clearlooks_style_draw_box_gap (DRAW_ARGS, } break; case GTK_POS_BOTTOM: - if (ge_widget_is_ltr (widget)) - { + if (ge_widget_is_ltr (widget)) { if (start) params.corners ^= CR_CORNER_BOTTOMLEFT; if (end) params.corners ^= CR_CORNER_BOTTOMRIGHT; - } - else - { + } else { if (start) params.corners ^= CR_CORNER_BOTTOMRIGHT; if (end) params.corners ^= CR_CORNER_BOTTOMLEFT; } break; - case GTK_POS_LEFT: - if (start) - params.corners ^= CR_CORNER_TOPLEFT; - if (end) - params.corners ^= CR_CORNER_BOTTOMLEFT; - break; - case GTK_POS_RIGHT: - if (start) - params.corners ^= CR_CORNER_TOPRIGHT; - if (end) - params.corners ^= CR_CORNER_BOTTOMRIGHT; - break; } /* Fill the background with bg[NORMAL] */ ge_cairo_rounded_rectangle (cr, x, y, width, height, params.radius, params.corners); ge_cairo_set_color (cr, &colors->bg[GTK_STATE_NORMAL]); cairo_fill (cr); - + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, - x, y, width, height); + x, y, width, height); } else { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_box_gap (style, window, state_type, shadow_type, - area, widget, detail, - x, y, width, height, - gap_side, gap_x, gap_width); + clearlooks_parent_class->draw_box_gap (style, window, state_type, shadow_type, + area, widget, detail, + x, y, width, height, + gap_side, gap_x, gap_width); } - - cairo_destroy (cr); + + cairo_destroy (cr); } static void @@ -364,69 +340,61 @@ clearlooks_style_draw_extension (DRAW_ARGS, GtkPositionType gap_side) SANITIZE_SIZE cr = ge_gdk_drawable_to_cairo (window, area); - + if (DETAIL ("tab")) { WidgetParameters params; TabParameters tab; - FocusParameters focus; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + tab.gap_side = (ClearlooksGapSide)gap_side; - + switch (gap_side) { - case CL_GAP_TOP: - params.corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; - break; case CL_GAP_BOTTOM: params.corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; break; - case CL_GAP_LEFT: - params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; + case CL_GAP_TOP: + params.corners = CR_CORNER_BOTTOMLEFT | CR_CORNER_BOTTOMRIGHT; break; case CL_GAP_RIGHT: params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; break; + case CL_GAP_LEFT: + params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; } - - /* Focus color */ - if (clearlooks_style->has_focus_color) - { - ge_gdk_color_to_cairo (&clearlooks_style->focus_color, &focus.color); - focus.has_color = TRUE; - } - else - focus.color = colors->bg[GTK_STATE_SELECTED]; - - tab.focus = focus; - + STYLE_FUNCTION(draw_tab) (cr, colors, ¶ms, &tab, - x, y, width, height); + x, y, width, height); } else { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_extension (style, window, state_type, shadow_type, area, - widget, detail, x, y, width, height, - gap_side); - } + clearlooks_parent_class->draw_extension (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, + gap_side); + } + cairo_destroy (cr); } -static void +static void clearlooks_style_draw_handle (DRAW_ARGS, GtkOrientation orientation) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); ClearlooksColors *colors = &clearlooks_style->colors; cairo_t *cr; - + gboolean is_horizontal; + CHECK_ARGS SANITIZE_SIZE - + cr = ge_gdk_drawable_to_cairo (window, area); - + + /* Evil hack to work around broken orientation for toolbars */ + is_horizontal = (width > height); + if (DETAIL ("handlebox")) { WidgetParameters params; @@ -434,10 +402,24 @@ clearlooks_style_draw_handle (DRAW_ARGS, GtkOrientation orientation) clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); handle.type = CL_HANDLE_TOOLBAR; - handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); + handle.horizontal = is_horizontal; + + /* Is this ever true? -Daniel */ + if (GE_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE) + { + ToolbarParameters toolbar; + clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y); + + toolbar.style = clearlooks_style->toolbarstyle; + + cairo_save (cr); + STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height); + cairo_restore (cr); + } + STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, - x, y, width, height); + x, y, width, height); } else if (DETAIL ("paned")) { @@ -446,10 +428,10 @@ clearlooks_style_draw_handle (DRAW_ARGS, GtkOrientation orientation) clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); handle.type = CL_HANDLE_SPLITTER; - handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); - + handle.horizontal = orientation == GTK_ORIENTATION_HORIZONTAL; + STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, - x, y, width, height); + x, y, width, height); } else { @@ -458,10 +440,24 @@ clearlooks_style_draw_handle (DRAW_ARGS, GtkOrientation orientation) clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); handle.type = CL_HANDLE_TOOLBAR; - handle.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); + handle.horizontal = is_horizontal; + + /* Is this ever true? -Daniel */ + if (GE_IS_TOOLBAR (widget) && shadow_type != GTK_SHADOW_NONE) + { + ToolbarParameters toolbar; + clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y); + + toolbar.style = clearlooks_style->toolbarstyle; + + cairo_save (cr); + STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height); + cairo_restore (cr); + } + STYLE_FUNCTION(draw_handle) (cr, colors, ¶ms, &handle, - x, y, width, height); + x, y, width, height); } cairo_destroy (cr); @@ -480,77 +476,76 @@ clearlooks_style_draw_box (DRAW_ARGS) CHECK_ARGS SANITIZE_SIZE - if (DETAIL ("menubar")) + if (DETAIL ("menubar") && !ge_is_panel_widget_item(widget)) { WidgetParameters params; MenuBarParameters menubar; - gboolean horizontal; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); menubar.style = clearlooks_style->menubarstyle; - horizontal = height < 2*width; - /* This is not that great. Ideally we would have a nice vertical menubar. */ - if ((shadow_type != GTK_SHADOW_NONE) && horizontal) - STYLE_FUNCTION(draw_menubar) (cr, colors, ¶ms, &menubar, - x, y, width, height); + STYLE_FUNCTION(draw_menubar) (cr, colors, ¶ms, &menubar, + x, y, width, height); } - else if (DETAIL ("button") && CHECK_HINT (GE_HINT_TREEVIEW_HEADER)) + else if (DETAIL ("button") && widget && widget->parent && + (GE_IS_TREE_VIEW(widget->parent) || + GE_IS_CLIST (widget->parent) || + ge_object_is_a (G_OBJECT(widget->parent), "ETree"))) /* ECanvas inside ETree */ { WidgetParameters params; ListViewHeaderParameters header; - + gint columns, column_index; gboolean resizable = TRUE; - - /* XXX: This makes unknown treeview header "middle", in need for something nicer */ + + /* XXX: This makes unknown treeview header CL_ORDER_MIDDLE, in need for something nicer */ columns = 3; column_index = 1; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + params.corners = CR_CORNER_NONE; - + if (GE_IS_TREE_VIEW (widget->parent)) { clearlooks_treeview_get_header_index (GTK_TREE_VIEW(widget->parent), - widget, &column_index, &columns, - &resizable); + widget, &column_index, &columns, + &resizable); } else if (GE_IS_CLIST (widget->parent)) { clearlooks_clist_get_header_index (GTK_CLIST(widget->parent), - widget, &column_index, &columns); + widget, &column_index, &columns); } - + header.resizable = resizable; - - header.order = 0; + if (column_index == 0) - header.order |= params.ltr ? CL_ORDER_FIRST : CL_ORDER_LAST; - if (column_index == columns-1) - header.order |= params.ltr ? CL_ORDER_LAST : CL_ORDER_FIRST; - + header.order = params.ltr ? CL_ORDER_FIRST : CL_ORDER_LAST; + else if (column_index == columns-1) + header.order = params.ltr ? CL_ORDER_LAST : CL_ORDER_FIRST; + else + header.order = CL_ORDER_MIDDLE; + gtk_style_apply_default_background (style, window, FALSE, state_type, area, x, y, width, height); - + STYLE_FUNCTION(draw_list_view_header) (cr, colors, ¶ms, &header, - x, y, width, height); + x, y, width, height); } else if (DETAIL ("button") || DETAIL ("buttondefault")) { WidgetParameters params; ShadowParameters shadow = { CR_CORNER_ALL, CL_SHADOW_NONE } ; clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - params.active = shadow_type == GTK_SHADOW_IN; - if (CHECK_HINT (GE_HINT_COMBOBOX_ENTRY)) + if (ge_is_in_combo_box(widget)) { if (params.ltr) params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; else params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; - + shadow.shadow = CL_SHADOW_IN; if (params.xthickness > 2) @@ -558,15 +553,19 @@ clearlooks_style_draw_box (DRAW_ARGS) if (params.ltr) x--; width++; - } + } } else { - params.corners = CR_CORNER_ALL; - if (clearlooks_style->reliefstyle != 0) - params.enable_shadow = TRUE; - } - + params.corners = CR_CORNER_ALL; + /* if (!(ge_is_combo_box (widget, FALSE))) */ + params.enable_glow = TRUE; + } + + if (GE_IS_TOGGLE_BUTTON (widget) && + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) + params.active = TRUE; + STYLE_FUNCTION(draw_button) (cr, &clearlooks_style->colors, ¶ms, x, y, width, height); } @@ -576,14 +575,14 @@ clearlooks_style_draw_box (DRAW_ARGS) { WidgetParameters params; clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + if (style->xthickness == 3) { width++; if (params.ltr) x--; } - + if (DETAIL ("spinbutton_up")) { height+=2; @@ -599,139 +598,84 @@ clearlooks_style_draw_box (DRAW_ARGS) else params.corners = CR_CORNER_BOTTOMLEFT; } - + STYLE_FUNCTION(draw_spinbutton_down) (cr, &clearlooks_style->colors, ¶ms, x, y, width, height); } } else if (DETAIL ("spinbutton")) { WidgetParameters params; - - /* The "spinbutton" box is always drawn with state NORMAL, even if it is insensitive. - * So work around this here. */ - if (state_type == GTK_STATE_NORMAL && widget && GE_IS_ENTRY (widget)) - state_type = GTK_WIDGET_STATE (widget); - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + if (params.ltr) params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; else params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; - + if (style->xthickness == 3) { if (params.ltr) x--; width++; } - + STYLE_FUNCTION(draw_spinbutton) (cr, &clearlooks_style->colors, ¶ms, - x, y, width, height); + x, y, width, height); } - else if (detail && g_str_has_prefix (detail, "trough") && CHECK_HINT (GE_HINT_SCALE)) + else if (detail && g_str_has_prefix (detail, "trough") && GE_IS_SCALE (widget)) { WidgetParameters params; SliderParameters slider; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); params.corners = CR_CORNER_NONE; - + slider.lower = DETAIL ("trough-lower"); slider.fill_level = DETAIL ("trough-fill-level") || DETAIL ("trough-fill-level-full"); - if (CHECK_HINT (GE_HINT_HSCALE)) - slider.horizontal = TRUE; - else if (CHECK_HINT (GE_HINT_VSCALE)) - slider.horizontal = FALSE; - else /* Fallback based on the size... */ - slider.horizontal = width >= height; - + slider.horizontal = (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL); + STYLE_FUNCTION(draw_scale_trough) (cr, &clearlooks_style->colors, - ¶ms, &slider, - x, y, width, height); + ¶ms, &slider, + x, y, width, height); } - else if (DETAIL ("trough") && CHECK_HINT (GE_HINT_PROGRESSBAR)) + else if (DETAIL ("trough") && widget && GE_IS_PROGRESS_BAR (widget)) { WidgetParameters params; - - clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - - /* Fill the background as it is initilized to base[NORMAL]. - * Relevant GTK+ bug: http://bugzilla.gnome.org/show_bug.cgi?id=513476 - * The fill only happens if no hint has been added by some application - * that is faking GTK+ widgets. */ - if (!widget || !g_object_get_data(G_OBJECT (widget), "transparent-bg-hint")) - { - cairo_rectangle (cr, 0, 0, width, height); - ge_cairo_set_color (cr, ¶ms.parentbg); - cairo_fill (cr); - } - STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, ¶ms, - x, y, width, height); + + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + + STYLE_FUNCTION(draw_progressbar_trough) (cr, colors, ¶ms, + x, y, width, height); } - else if (DETAIL ("trough") && CHECK_HINT (GE_HINT_SCROLLBAR)) + else if (DETAIL ("trough") && widget && (GE_IS_VSCROLLBAR (widget) || GE_IS_HSCROLLBAR (widget))) { WidgetParameters params; ScrollBarParameters scrollbar; - gboolean trough_under_steppers = TRUE; - ClearlooksStepper steppers; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - params.corners = CR_CORNER_ALL; - + params.corners = CR_CORNER_NONE; + scrollbar.horizontal = TRUE; scrollbar.junction = clearlooks_scrollbar_get_junction (widget); - steppers = clearlooks_scrollbar_visible_steppers (widget); - - if (CHECK_HINT (GE_HINT_HSCROLLBAR)) - scrollbar.horizontal = TRUE; - else if (CHECK_HINT (GE_HINT_VSCROLLBAR)) - scrollbar.horizontal = FALSE; - else /* Fallback based on the size ... */ - scrollbar.horizontal = width >= height; - - if (widget) - gtk_widget_style_get (widget, - "trough-under-steppers", &trough_under_steppers, - NULL); - - if (trough_under_steppers) + if (GE_IS_RANGE (widget)) + scrollbar.horizontal = GTK_RANGE (widget)->orientation == GTK_ORIENTATION_HORIZONTAL; + + if (scrollbar.horizontal) { - /* If trough under steppers is set, then we decrease the size - * slightly. The size is decreased so that the trough is not - * visible underneath the steppers. This is not really needed - * as one can use the trough-under-steppers style property, - * but it needs to exist for backward compatibility. */ - if (scrollbar.horizontal) - { - if (steppers & (CL_STEPPER_A | CL_STEPPER_B)) - { - x += 2; - width -= 2; - } - if (steppers & (CL_STEPPER_C | CL_STEPPER_D)) - { - width -= 2; - } - } - else - { - if (steppers & (CL_STEPPER_A | CL_STEPPER_B)) - { - y += 2; - height -= 2; - } - if (steppers & (CL_STEPPER_C | CL_STEPPER_D)) - { - height -= 2; - } - } + x += 2; + width -= 4; } - + else + { + y += 2; + height -= 4; + } + STYLE_FUNCTION(draw_scrollbar_trough) (cr, colors, ¶ms, &scrollbar, - x, y, width, height); + x, y, width, height); } else if (DETAIL ("bar")) { @@ -741,10 +685,10 @@ clearlooks_style_draw_box (DRAW_ARGS) #ifdef HAVE_ANIMATION if(clearlooks_style->animation && CL_IS_PROGRESS_BAR (widget)) - { + { gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode; - - if (!activity_mode) + + if (!activity_mode) clearlooks_animation_progressbar_add ((gpointer)widget); } @@ -765,7 +709,7 @@ clearlooks_style_draw_box (DRAW_ARGS) progressbar.value = 0; progressbar.pulsing = FALSE; } - + if (!params.ltr) { if (progressbar.orientation == GTK_PROGRESS_LEFT_TO_RIGHT) @@ -809,52 +753,51 @@ clearlooks_style_draw_box (DRAW_ARGS) tmp.height += 2; } } - + cairo_reset_clip (cr); gdk_cairo_rectangle (cr, &tmp); cairo_clip (cr); } - + STYLE_FUNCTION(draw_progressbar_fill) (cr, colors, ¶ms, &progressbar, - x, y, width, height, - 10 - (int)(elapsed * 10.0) % 10); + x, y, width, height, + 10 - (int)(elapsed * 10.0) % 10); } else if (DETAIL ("optionmenu")) { WidgetParameters params; OptionMenuParameters optionmenu; - + GtkRequisition indicator_size; GtkBorder indicator_spacing; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - - if (clearlooks_style->reliefstyle != 0) - params.enable_shadow = TRUE; + + params.enable_glow = TRUE; ge_option_menu_get_props (widget, &indicator_size, &indicator_spacing); - + if (ge_widget_is_ltr (widget)) optionmenu.linepos = width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - 1; else optionmenu.linepos = (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + 1; - + STYLE_FUNCTION(draw_optionmenu) (cr, colors, ¶ms, &optionmenu, - x, y, width, height); + x, y, width, height); } else if (DETAIL ("menuitem")) { WidgetParameters params; clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - - if (CHECK_HINT (GE_HINT_MENUBAR)) + + if (widget && GE_IS_MENU_BAR (widget->parent)) { params.corners = CR_CORNER_TOPLEFT | CR_CORNER_TOPRIGHT; height += 1; STYLE_FUNCTION(draw_menubaritem) (cr, colors, ¶ms, x, y, width, height); } else - { + { params.corners = CR_CORNER_ALL; STYLE_FUNCTION(draw_menuitem) (cr, colors, ¶ms, x, y, width, height); } @@ -865,70 +808,59 @@ clearlooks_style_draw_box (DRAW_ARGS) ScrollBarParameters scrollbar; ScrollBarStepperParameters stepper; GdkRectangle this_rectangle; - + this_rectangle.x = x; this_rectangle.y = y; this_rectangle.width = width; this_rectangle.height = height; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); params.corners = CR_CORNER_NONE; - + scrollbar.has_color = FALSE; scrollbar.horizontal = TRUE; scrollbar.junction = clearlooks_scrollbar_get_junction (widget); - if (clearlooks_style->colorize_scrollbar || clearlooks_style->has_scrollbar_color) + if (clearlooks_style->colorize_scrollbar || clearlooks_style->has_scrollbar_color) { scrollbar.has_color = TRUE; + } scrollbar.horizontal = DETAIL ("hscrollbar"); - + stepper.stepper = clearlooks_scrollbar_get_stepper (widget, &this_rectangle); STYLE_FUNCTION(draw_scrollbar_stepper) (cr, colors, ¶ms, &scrollbar, &stepper, - x, y, width, height); + x, y, width, height); } else if (DETAIL ("toolbar") || DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin")) { WidgetParameters params; ToolbarParameters toolbar; - gboolean horizontal; clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); clearlooks_set_toolbar_parameters (&toolbar, widget, window, x, y); toolbar.style = clearlooks_style->toolbarstyle; - if ((DETAIL ("handlebox_bin") || DETAIL ("dockitem_bin")) && GE_IS_BIN (widget)) - { - GtkWidget* child = gtk_bin_get_child ((GtkBin*) widget); - /* This is to draw the correct shadow on the handlebox. - * We need to draw it here, as otherwise the handle will not get the - * background. */ - if (GE_IS_TOOLBAR (child)) - gtk_widget_style_get (child, "shadow-type", &shadow_type, NULL); - } - - horizontal = height < 2*width; - /* This is not that great. Ideally we would have a nice vertical toolbar. */ - if ((shadow_type != GTK_SHADOW_NONE) && horizontal) + /* Only draw the shadows on horizontal toolbars */ + if (shadow_type != GTK_SHADOW_NONE && height < 2*width ) STYLE_FUNCTION(draw_toolbar) (cr, colors, ¶ms, &toolbar, x, y, width, height); } else if (DETAIL ("trough")) { - /* Nothing? Why benjamin? */ + } else if (DETAIL ("menu")) { WidgetParameters params; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + STYLE_FUNCTION(draw_menu_frame) (cr, colors, ¶ms, x, y, width, height); } else if (DETAIL ("hseparator") || DETAIL ("vseparator")) { - gchar *new_detail = (gchar*) detail; + const gchar *new_detail = detail; /* Draw a normal separator, we just use this because it gives more control * over sizing (currently). */ @@ -937,21 +869,19 @@ clearlooks_style_draw_box (DRAW_ARGS) if (GE_IS_MENU_ITEM (widget)) new_detail = "menuitem"; - if (DETAIL ("hseparator")) - { + if (DETAIL ("hseparator")) { gtk_paint_hline (style, window, state_type, area, widget, new_detail, x, x + width - 1, y + height/2); - } - else + } else gtk_paint_vline (style, window, state_type, area, widget, new_detail, y, y + height - 1, x + width/2); } else { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_box (style, window, state_type, shadow_type, area, - widget, detail, x, y, width, height); + clearlooks_parent_class->draw_box (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); } - + cairo_destroy (cr); } @@ -967,24 +897,24 @@ clearlooks_style_draw_slider (DRAW_ARGS, GtkOrientation orientation) CHECK_ARGS SANITIZE_SIZE - + if (DETAIL ("hscale") || DETAIL ("vscale")) { WidgetParameters params; SliderParameters slider; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + slider.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); slider.lower = FALSE; slider.fill_level = FALSE; - + if (clearlooks_style->style == CL_STYLE_GLOSSY) /* XXX! */ params.corners = CR_CORNER_ALL; - + STYLE_FUNCTION(draw_slider_button) (cr, &clearlooks_style->colors, - ¶ms, &slider, - x, y, width, height); + ¶ms, &slider, + x, y, width, height); } else if (DETAIL ("slider")) { @@ -998,8 +928,7 @@ clearlooks_style_draw_slider (DRAW_ARGS, GtkOrientation orientation) scrollbar.horizontal = (orientation == GTK_ORIENTATION_HORIZONTAL); scrollbar.junction = clearlooks_scrollbar_get_junction (widget); - if (clearlooks_style->colorize_scrollbar) - { + if (clearlooks_style->colorize_scrollbar) { scrollbar.color = colors->spot[1]; scrollbar.has_color = TRUE; } @@ -1014,14 +943,14 @@ clearlooks_style_draw_slider (DRAW_ARGS, GtkOrientation orientation) if ((clearlooks_style->style == CL_STYLE_GLOSSY || clearlooks_style->style == CL_STYLE_GUMMY) && !scrollbar.has_color) scrollbar.color = colors->bg[0]; - + STYLE_FUNCTION(draw_scrollbar_slider) (cr, colors, ¶ms, &scrollbar, x, y, width, height); } else { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_slider (style, window, state_type, shadow_type, area, - widget, detail, x, y, width, height, orientation); + clearlooks_parent_class->draw_slider (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, orientation); } cairo_destroy (cr); @@ -1035,18 +964,18 @@ clearlooks_style_draw_option (DRAW_ARGS) WidgetParameters params; CheckboxParameters checkbox; cairo_t *cr; - + CHECK_ARGS SANITIZE_SIZE cr = ge_gdk_drawable_to_cairo (window, area); colors = &clearlooks_style->colors; - + checkbox.shadow_type = shadow_type; checkbox.in_menu = (widget && GTK_IS_MENU(widget->parent)); - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + STYLE_FUNCTION(draw_radiobutton) (cr, colors, ¶ms, &checkbox, x, y, width, height); cairo_destroy (cr); @@ -1064,19 +993,19 @@ clearlooks_style_draw_check (DRAW_ARGS) SANITIZE_SIZE cr = ge_gdk_drawable_to_cairo (window, area); - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); - + params.corners = CR_CORNER_ALL; - + checkbox.shadow_type = shadow_type; checkbox.in_cell = DETAIL("cellcheck"); checkbox.in_menu = (widget && widget->parent && GTK_IS_MENU(widget->parent)); STYLE_FUNCTION(draw_checkbox) (cr, &clearlooks_style->colors, ¶ms, &checkbox, - x, y, width, height); - + x, y, width, height); + cairo_destroy (cr); } @@ -1106,7 +1035,7 @@ clearlooks_style_draw_vline (GtkStyle *style, * (and even if, a normal one should be better on menu bars) */ STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, x, y1, 2, y2-y1+1); - + cairo_destroy (cr); } @@ -1131,24 +1060,24 @@ clearlooks_style_draw_hline (GtkStyle *style, colors = &clearlooks_style->colors; cr = ge_gdk_drawable_to_cairo (window, area); - + separator.horizontal = TRUE; - + if (!DETAIL ("menuitem")) STYLE_FUNCTION(draw_separator) (cr, colors, NULL, &separator, x1, y, x2-x1+1, 2); else STYLE_FUNCTION(draw_menu_item_separator) (cr, colors, NULL, &separator, - x1, y, x2-x1+1, 2); - + x1, y, x2-x1+1, 2); + cairo_destroy (cr); } -static void +static void clearlooks_style_draw_shadow_gap (DRAW_ARGS, - GtkPositionType gap_side, - gint gap_x, - gint gap_width) + GtkPositionType gap_side, + gint gap_x, + gint gap_width) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); const ClearlooksColors *colors; @@ -1159,47 +1088,47 @@ clearlooks_style_draw_shadow_gap (DRAW_ARGS, cr = ge_gdk_drawable_to_cairo (window, area); colors = &clearlooks_style->colors; - + if (DETAIL ("frame")) { WidgetParameters params; FrameParameters frame; - + frame.shadow = shadow_type; frame.gap_side = gap_side; frame.gap_x = gap_x; frame.gap_width = gap_width; frame.border = &colors->shade[5]; - + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); params.corners = CR_CORNER_ALL; - + STYLE_FUNCTION(draw_frame) (cr, colors, ¶ms, &frame, - x, y, width, height); + x, y, width, height); } else { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->draw_shadow_gap (style, window, state_type, shadow_type, area, - widget, detail, x, y, width, height, - gap_side, gap_x, gap_width); + clearlooks_parent_class->draw_shadow_gap (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, + gap_side, gap_x, gap_width); } - + cairo_destroy (cr); } static void clearlooks_style_draw_resize_grip (GtkStyle *style, - GdkWindow *window, - GtkStateType state_type, - GdkRectangle *area, - GtkWidget *widget, - const gchar *detail, - GdkWindowEdge edge, - gint x, - gint y, - gint width, - gint height) + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GdkWindowEdge edge, + gint x, + gint y, + gint width, + gint height) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); ClearlooksColors *colors = &clearlooks_style->colors; @@ -1216,10 +1145,10 @@ clearlooks_style_draw_resize_grip (GtkStyle *style, cr = ge_gdk_drawable_to_cairo (window, area); - clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); STYLE_FUNCTION(draw_resize_grip) (cr, colors, ¶ms, &grip, - x, y, width, height); + x, y, width, height); cairo_destroy (cr); } @@ -1230,17 +1159,17 @@ clearlooks_style_draw_tab (DRAW_ARGS) ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); ClearlooksColors *colors = &clearlooks_style->colors; WidgetParameters params; - ArrowParameters arrow; + ArrowParameters arrow; cairo_t *cr; CHECK_ARGS SANITIZE_SIZE - + cr = ge_gdk_drawable_to_cairo (window, area); clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); arrow.type = CL_ARROW_COMBO; - arrow.direction = CL_DIRECTION_DOWN; + arrow.direction = CL_DIRECTION_DOWN; STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height); @@ -1249,18 +1178,18 @@ clearlooks_style_draw_tab (DRAW_ARGS) static void clearlooks_style_draw_arrow (GtkStyle *style, - GdkWindow *window, - GtkStateType state_type, - GtkShadowType shadow, - GdkRectangle *area, - GtkWidget *widget, - const gchar *detail, - GtkArrowType arrow_type, - gboolean fill, - gint x, - gint y, - gint width, - gint height) + GdkWindow *window, + GtkStateType state_type, + GtkShadowType shadow, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GtkArrowType arrow_type, + gboolean fill, + gint x, + gint y, + gint width, + gint height) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); ClearlooksColors *colors = &clearlooks_style->colors; @@ -1271,8 +1200,7 @@ clearlooks_style_draw_arrow (GtkStyle *style, CHECK_ARGS SANITIZE_SIZE - if (arrow_type == GTK_ARROW_NONE) - { + if (arrow_type == GTK_ARROW_NONE) { cairo_destroy (cr); return; } @@ -1280,12 +1208,12 @@ clearlooks_style_draw_arrow (GtkStyle *style, clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); arrow.type = CL_ARROW_NORMAL; arrow.direction = (ClearlooksDirection)arrow_type; - + if (ge_is_combo_box (widget, FALSE) && !ge_is_combo_box_entry (widget)) { arrow.type = CL_ARROW_COMBO; } - + /* I have no idea why, but the arrow of GtkCombo is larger than in other places. * Subtracting 3 seems to fix this. */ if (widget && widget->parent && GE_IS_COMBO (widget->parent->parent)) @@ -1296,34 +1224,30 @@ clearlooks_style_draw_arrow (GtkStyle *style, x += 2; width -= 3; } - + STYLE_FUNCTION(draw_arrow) (cr, colors, ¶ms, &arrow, x, y, width, height); - + cairo_destroy (cr); } static void clearlooks_style_init_from_rc (GtkStyle * style, - GtkRcStyle * rc_style) + GtkRcStyle * rc_style) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); - - GTK_STYLE_CLASS (clearlooks_style_parent_class)->init_from_rc (style, rc_style); - + + clearlooks_parent_class->init_from_rc (style, rc_style); + g_assert ((CLEARLOOKS_RC_STYLE (rc_style)->style >= 0) && (CLEARLOOKS_RC_STYLE (rc_style)->style < CL_NUM_STYLES)); - clearlooks_style->style = CLEARLOOKS_RC_STYLE (rc_style)->style; - - clearlooks_style->reliefstyle = CLEARLOOKS_RC_STYLE (rc_style)->reliefstyle; - clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle; - clearlooks_style->toolbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->toolbarstyle; - clearlooks_style->has_focus_color = CLEARLOOKS_RC_STYLE (rc_style)->flags & CL_FLAG_FOCUS_COLOR; + clearlooks_style->style = CLEARLOOKS_RC_STYLE (rc_style)->style; + + clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle; + clearlooks_style->toolbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->toolbarstyle; clearlooks_style->has_scrollbar_color = CLEARLOOKS_RC_STYLE (rc_style)->flags & CL_FLAG_SCROLLBAR_COLOR; - clearlooks_style->colorize_scrollbar = CLEARLOOKS_RC_STYLE (rc_style)->colorize_scrollbar; - clearlooks_style->animation = CLEARLOOKS_RC_STYLE (rc_style)->animation; - clearlooks_style->radius = CLAMP (CLEARLOOKS_RC_STYLE (rc_style)->radius, 0.0, 10.0); + clearlooks_style->colorize_scrollbar = CLEARLOOKS_RC_STYLE (rc_style)->colorize_scrollbar; + clearlooks_style->animation = CLEARLOOKS_RC_STYLE (rc_style)->animation; + clearlooks_style->radius = CLAMP (CLEARLOOKS_RC_STYLE (rc_style)->radius, 0.0, 10.0); - if (clearlooks_style->has_focus_color) - clearlooks_style->focus_color = CLEARLOOKS_RC_STYLE (rc_style)->focus_color; if (clearlooks_style->has_scrollbar_color) clearlooks_style->scrollbar_color = CLEARLOOKS_RC_STYLE (rc_style)->scrollbar_color; } @@ -1337,37 +1261,25 @@ clearlooks_style_realize (GtkStyle * style) CairoColor bg_normal; double contrast; int i; - - GTK_STYLE_CLASS (clearlooks_style_parent_class)->realize (style); + + clearlooks_parent_class->realize (style); contrast = CLEARLOOKS_RC_STYLE (style->rc_style)->contrast; - + /* Lighter to darker */ ge_gdk_color_to_cairo (&style->bg[GTK_STATE_NORMAL], &bg_normal); for (i = 0; i < 9; i++) { - ge_shade_color (&bg_normal, (shades[i] < 1.0) ? - (shades[i]/contrast) : (shades[i]*contrast), - &clearlooks_style->colors.shade[i]); + ge_shade_color(&bg_normal, (shades[i]-0.7) * contrast + 0.7, &clearlooks_style->colors.shade[i]); } - + ge_gdk_color_to_cairo (&style->bg[GTK_STATE_SELECTED], &spot_color); - - /* Andrea Cimitan wants something like the following to handle dark themes. - * However, these two lines are broken currently, as ge_hsb_from_color expects - * a CairoColor and not GdkColor - * ge_hsb_from_color (&style->bg[GTK_STATE_SELECTED], &hue_spot, &saturation_spot, &brightness_spot); - * ge_hsb_from_color (&style->bg[GTK_STATE_NORMAL], &hue_bg, &saturation_bg, &brightness_bg); - */ - - /* Here to place some checks for dark themes. - * We should use a different shade value for spot[2]. */ - - ge_shade_color (&spot_color, 1.25, &clearlooks_style->colors.spot[0]); - ge_shade_color (&spot_color, 1.05, &clearlooks_style->colors.spot[1]); - ge_shade_color (&spot_color, 0.65, &clearlooks_style->colors.spot[2]); - + + ge_shade_color(&spot_color, 1.42, &clearlooks_style->colors.spot[0]); + ge_shade_color(&spot_color, 1.05, &clearlooks_style->colors.spot[1]); + ge_shade_color(&spot_color, 0.65, &clearlooks_style->colors.spot[2]); + for (i=0; i<5; i++) { ge_gdk_color_to_cairo (&style->fg[i], &clearlooks_style->colors.fg[i]); @@ -1379,170 +1291,90 @@ clearlooks_style_realize (GtkStyle * style) static void clearlooks_style_draw_focus (GtkStyle *style, GdkWindow *window, GtkStateType state_type, - GdkRectangle *area, GtkWidget *widget, const gchar *detail, - gint x, gint y, gint width, gint height) + GdkRectangle *area, GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) { - ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); - ClearlooksColors *colors = &clearlooks_style->colors; - WidgetParameters params; - FocusParameters focus; - guint8* dash_list; - cairo_t *cr; + gboolean free_dash_list = FALSE; + gint line_width = 1; + gint8 *dash_list = (gint8 *)"\1\1"; - CHECK_ARGS - SANITIZE_SIZE - - cr = gdk_cairo_create (window); + if (widget) + { + gtk_widget_style_get (widget, + "focus-line-width", &line_width, + "focus-line-pattern", + (gchar *) & dash_list, NULL); - clearlooks_set_widget_parameters (widget, style, state_type, ¶ms); + free_dash_list = TRUE; + } - /* Corners */ - params.corners = CR_CORNER_ALL; - if (CHECK_HINT (GE_HINT_COMBOBOX_ENTRY)) + if (detail && !strcmp (detail, "add-mode")) { - if (params.ltr) - params.corners = CR_CORNER_TOPRIGHT | CR_CORNER_BOTTOMRIGHT; - else - params.corners = CR_CORNER_TOPLEFT | CR_CORNER_BOTTOMLEFT; + if (free_dash_list) + g_free (dash_list); - if (params.xthickness > 2) - { - if (params.ltr) - x--; - width++; - } + dash_list = (gint8 *)"\4\4"; + free_dash_list = FALSE; } - focus.has_color = FALSE; - focus.interior = FALSE; - focus.line_width = 1; - focus.padding = 1; - dash_list = NULL; + CHECK_ARGS + SANITIZE_SIZE + + cr = gdk_cairo_create (window); - if (widget) - { - gtk_widget_style_get (widget, - "focus-line-width", &focus.line_width, - "focus-line-pattern", &dash_list, - "focus-padding", &focus.padding, - "interior-focus", &focus.interior, - NULL); - } - if (dash_list) - focus.dash_list = dash_list; + if (detail && !strcmp (detail, "colorwheel_light")) + cairo_set_source_rgb (cr, 0., 0., 0.); + else if (detail && !strcmp (detail, "colorwheel_dark")) + cairo_set_source_rgb (cr, 1., 1., 1.); else - focus.dash_list = (guint8*) g_strdup ("\1\1"); + ge_cairo_set_gdk_color_with_alpha (cr, &style->fg[state_type], + 0.7); - /* Focus type */ - if (DETAIL("button")) - { - if (CHECK_HINT (GE_HINT_TREEVIEW_HEADER)) - { - focus.type = CL_FOCUS_TREEVIEW_HEADER; - } - else - { - GtkReliefStyle relief = GTK_RELIEF_NORMAL; - /* Check for the shadow type. */ - if (widget && GTK_IS_BUTTON (widget)) - g_object_get (G_OBJECT (widget), "relief", &relief, NULL); + cairo_set_line_width (cr, line_width); - if (relief == GTK_RELIEF_NORMAL) - focus.type = CL_FOCUS_BUTTON; - else - focus.type = CL_FOCUS_BUTTON_FLAT; - - /* This is a workaround for the bogus focus handling that - * clearlooks has currently. - * I truely dislike putting it here, but I guess it is better - * then having such a visible bug. It should be removed in the - * next unstable release cycle. -- Benjamin */ - if (ge_object_is_a (G_OBJECT (widget), "ButtonWidget")) - focus.type = CL_FOCUS_LABEL; - } - } - else if (detail && g_str_has_prefix (detail, "treeview")) + if (dash_list[0]) { - /* Focus in a treeview, and that means a lot of different detail strings. */ - if (g_str_has_prefix (detail, "treeview-drop-indicator")) - focus.type = CL_FOCUS_TREEVIEW_DND; - else - focus.type = CL_FOCUS_TREEVIEW_ROW; + gint n_dashes = strlen ((gchar *)dash_list); + gdouble *dashes = g_new (gdouble, n_dashes); + gdouble total_length = 0; + gdouble dash_offset; + gint i; - if (g_str_has_suffix (detail, "left")) - { - focus.continue_side = CL_CONT_RIGHT; - } - else if (g_str_has_suffix (detail, "right")) - { - focus.continue_side = CL_CONT_LEFT; - } - else if (g_str_has_suffix (detail, "middle")) + for (i = 0; i < n_dashes; i++) { - focus.continue_side = CL_CONT_LEFT | CL_CONT_RIGHT; - } - else - { - /* This may either mean no continuation, or unknown ... - * if it is unknown we assume it continues on both sides */ - gboolean row_ending_details = FALSE; - - /* Try to get the style property. */ - if (widget) - gtk_widget_style_get (widget, - "row-ending-details", &row_ending_details, - NULL); - - if (row_ending_details) - focus.continue_side = CL_CONT_NONE; - else - focus.continue_side = CL_CONT_LEFT | CL_CONT_RIGHT; + dashes[i] = dash_list[i]; + total_length += dash_list[i]; } - } - else if (detail && g_str_has_prefix (detail, "trough") && CHECK_HINT (GE_HINT_SCALE)) - { - focus.type = CL_FOCUS_SCALE; - } - else if (DETAIL("tab")) - { - focus.type = CL_FOCUS_TAB; - } - else if (detail && g_str_has_prefix (detail, "colorwheel")) - { - if (DETAIL ("colorwheel_dark")) - focus.type = CL_FOCUS_COLOR_WHEEL_DARK; - else - focus.type = CL_FOCUS_COLOR_WHEEL_LIGHT; - } - else if (DETAIL("checkbutton") || DETAIL("radiobutton")) - { - focus.type = CL_FOCUS_LABEL; /* Let's call it "LABEL" :) */ - } - else if (CHECK_HINT (GE_HINT_TREEVIEW)) - { - focus.type = CL_FOCUS_TREEVIEW; /* Treeview without content is focused. */ - } - else - { - focus.type = CL_FOCUS_UNKNOWN; /* Custom widgets (Beagle) and something unknown */ + /* The dash offset here aligns the pattern to integer pixels + * by starting the dash at the right side of the left border + * Negative dash offsets in cairo don't work + * (https://bugs.freedesktop.org/show_bug.cgi?id=2729) + */ + dash_offset = -line_width / 2.; + while (dash_offset < 0) + dash_offset += total_length; + + cairo_set_dash (cr, dashes, n_dashes, dash_offset); + g_free (dashes); } - /* Focus color */ - if (clearlooks_style->has_focus_color) + if (area) { - ge_gdk_color_to_cairo (&clearlooks_style->focus_color, &focus.color); - focus.has_color = TRUE; + gdk_cairo_rectangle (cr, area); + cairo_clip (cr); } - else - focus.color = colors->bg[GTK_STATE_SELECTED]; - - STYLE_FUNCTION(draw_focus) (cr, colors, ¶ms, &focus, x, y, width, height); - - g_free (focus.dash_list); + cairo_rectangle (cr, + x + line_width / 2., + y + line_width / 2., + width - line_width, height - line_width); + cairo_stroke (cr); cairo_destroy (cr); + + if (free_dash_list) + g_free (dash_list); } static void @@ -1550,27 +1382,24 @@ clearlooks_style_copy (GtkStyle * style, GtkStyle * src) { ClearlooksStyle * cl_style = CLEARLOOKS_STYLE (style); ClearlooksStyle * cl_src = CLEARLOOKS_STYLE (src); - + cl_style->colors = cl_src->colors; - cl_style->reliefstyle = cl_src->reliefstyle; cl_style->menubarstyle = cl_src->menubarstyle; cl_style->toolbarstyle = cl_src->toolbarstyle; - cl_style->focus_color = cl_src->focus_color; - cl_style->has_focus_color = cl_src->has_focus_color; cl_style->scrollbar_color = cl_src->scrollbar_color; cl_style->has_scrollbar_color = cl_src->has_scrollbar_color; cl_style->colorize_scrollbar = cl_src->colorize_scrollbar; cl_style->animation = cl_src->animation; cl_style->radius = cl_src->radius; cl_style->style = cl_src->style; - - GTK_STYLE_CLASS (clearlooks_style_parent_class)->copy (style, src); + + clearlooks_parent_class->copy (style, src); } static void clearlooks_style_unrealize (GtkStyle * style) { - GTK_STYLE_CLASS (clearlooks_style_parent_class)->unrealize (style); + clearlooks_parent_class->unrealize (style); } static GdkPixbuf * @@ -1595,13 +1424,11 @@ set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent) rowstride = gdk_pixbuf_get_rowstride (target); data = gdk_pixbuf_get_pixels (target); - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { /* The "4" is the number of chars per pixel, in this case, RGBA, the 3 means "skip to the alpha" */ - current = data + (y * rowstride) + (x * 4) + 3; + current = data + (y * rowstride) + (x * 4) + 3; *(current) = (guchar) (*(current) * alpha_percent); } } @@ -1615,26 +1442,23 @@ scale_or_ref (GdkPixbuf *src, int height) { if (width == gdk_pixbuf_get_width (src) && - height == gdk_pixbuf_get_height (src)) - { + height == gdk_pixbuf_get_height (src)) { return g_object_ref (src); - } - else - { + } else { return gdk_pixbuf_scale_simple (src, - width, height, - GDK_INTERP_BILINEAR); + width, height, + GDK_INTERP_BILINEAR); } } static void clearlooks_style_draw_layout (GtkStyle * style, - GdkWindow * window, - GtkStateType state_type, - gboolean use_text, - GdkRectangle * area, - GtkWidget * widget, - const gchar * detail, gint x, gint y, PangoLayout * layout) + GdkWindow * window, + GtkStateType state_type, + gboolean use_text, + GdkRectangle * area, + GtkWidget * widget, + const gchar * detail, gint x, gint y, PangoLayout * layout) { GdkGC *gc; @@ -1646,8 +1470,7 @@ clearlooks_style_draw_layout (GtkStyle * style, if (area) gdk_gc_set_clip_rectangle (gc, area); - if (state_type == GTK_STATE_INSENSITIVE) - { + if (state_type == GTK_STATE_INSENSITIVE) { ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); ClearlooksColors *colors = &clearlooks_style->colors; @@ -1661,7 +1484,7 @@ clearlooks_style_draw_layout (GtkStyle * style, ge_shade_color (¶ms.parentbg, 1.2, &temp); else ge_shade_color (&colors->bg[widget->state], 1.2, &temp); - + etched.red = (int) (temp.r * 65535); etched.green = (int) (temp.g * 65535); etched.blue = (int) (temp.b * 65535); @@ -1678,12 +1501,12 @@ clearlooks_style_draw_layout (GtkStyle * style, static GdkPixbuf * clearlooks_style_draw_render_icon (GtkStyle *style, - const GtkIconSource *source, - GtkTextDirection direction, - GtkStateType state, - GtkIconSize size, - GtkWidget *widget, - const char *detail) + const GtkIconSource *source, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail) { int width = 1; int height = 1; @@ -1692,35 +1515,30 @@ clearlooks_style_draw_render_icon (GtkStyle *style, GdkPixbuf *base_pixbuf; GdkScreen *screen; GtkSettings *settings; - + /* Oddly, style can be NULL in this function, because * GtkIconSet can be used without a style and if so * it uses this function. */ - + base_pixbuf = gtk_icon_source_get_pixbuf (source); - + g_return_val_if_fail (base_pixbuf != NULL, NULL); - - if (widget && gtk_widget_has_screen (widget)) - { + + if (widget && gtk_widget_has_screen (widget)) { screen = gtk_widget_get_screen (widget); settings = gtk_settings_get_for_screen (screen); - } - else if (style->colormap) - { + } else if (style->colormap) { screen = gdk_colormap_get_screen (style->colormap); settings = gtk_settings_get_for_screen (screen); - } - else - { + } else { settings = gtk_settings_get_default (); GTK_NOTE (MULTIHEAD, g_warning ("Using the default screen for gtk_default_render_icon()")); } - - if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) - { + + + if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) { g_warning (G_STRLOC ": invalid icon size '%d'", size); return NULL; } @@ -1732,40 +1550,30 @@ clearlooks_style_draw_render_icon (GtkStyle *style, scaled = scale_or_ref (base_pixbuf, width, height); else scaled = g_object_ref (base_pixbuf); - + /* If the state was wildcarded, then generate a state. */ - if (gtk_icon_source_get_state_wildcarded (source)) - { - if (state == GTK_STATE_INSENSITIVE) - { + if (gtk_icon_source_get_state_wildcarded (source)) { + if (state == GTK_STATE_INSENSITIVE) { stated = set_transparency (scaled, 0.3); - gdk_pixbuf_saturate_and_pixelate (stated, stated, 0.1, FALSE); - + gdk_pixbuf_saturate_and_pixelate (stated, stated, + 0.1, FALSE); + g_object_unref (scaled); - } - else if (state == GTK_STATE_PRELIGHT) - { - stated = gdk_pixbuf_copy (scaled); - - gdk_pixbuf_saturate_and_pixelate (scaled, stated, 1.2, FALSE); - + } else if (state == GTK_STATE_PRELIGHT) { + stated = gdk_pixbuf_copy (scaled); + + gdk_pixbuf_saturate_and_pixelate (scaled, stated, + 1.2, FALSE); + g_object_unref (scaled); - } - else - { + } else { stated = scaled; } } else stated = scaled; - - return stated; -} - -void -clearlooks_style_register_types (GTypeModule *module) -{ - clearlooks_style_register_type (module); + + return stated; } static void @@ -1777,6 +1585,9 @@ static void clearlooks_style_class_init (ClearlooksStyleClass * klass) { GtkStyleClass *style_class = GTK_STYLE_CLASS (klass); + + clearlooks_style_class = CLEARLOOKS_STYLE_CLASS (klass); + clearlooks_parent_class = g_type_class_peek_parent (klass); style_class->copy = clearlooks_style_copy; style_class->realize = clearlooks_style_realize; @@ -1801,26 +1612,36 @@ clearlooks_style_class_init (ClearlooksStyleClass * klass) style_class->draw_layout = clearlooks_style_draw_layout; style_class->render_icon = clearlooks_style_draw_render_icon; - clearlooks_register_style_classic (&klass->style_functions[CL_STYLE_CLASSIC], - &klass->style_constants[CL_STYLE_CLASSIC]); - - klass->style_functions[CL_STYLE_GLOSSY] = klass->style_functions[CL_STYLE_CLASSIC]; - klass->style_constants[CL_STYLE_GLOSSY] = klass->style_constants[CL_STYLE_CLASSIC]; - clearlooks_register_style_glossy (&klass->style_functions[CL_STYLE_GLOSSY], - &klass->style_constants[CL_STYLE_GLOSSY]); - - klass->style_functions[CL_STYLE_INVERTED] = klass->style_functions[CL_STYLE_CLASSIC]; - klass->style_constants[CL_STYLE_INVERTED] = klass->style_constants[CL_STYLE_CLASSIC]; - clearlooks_register_style_inverted (&klass->style_functions[CL_STYLE_INVERTED], - &klass->style_constants[CL_STYLE_INVERTED]); - - klass->style_functions[CL_STYLE_GUMMY] = klass->style_functions[CL_STYLE_CLASSIC]; - klass->style_constants[CL_STYLE_GUMMY] = klass->style_constants[CL_STYLE_CLASSIC]; - clearlooks_register_style_gummy (&klass->style_functions[CL_STYLE_GUMMY], - &klass->style_constants[CL_STYLE_GUMMY]); + clearlooks_register_style_classic (&clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]); + clearlooks_style_class->style_functions[CL_STYLE_GLOSSY] = clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]; + clearlooks_register_style_glossy (&clearlooks_style_class->style_functions[CL_STYLE_GLOSSY]); + clearlooks_style_class->style_functions[CL_STYLE_INVERTED] = clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]; + clearlooks_register_style_inverted (&clearlooks_style_class->style_functions[CL_STYLE_INVERTED]); + clearlooks_style_class->style_functions[CL_STYLE_GUMMY] = clearlooks_style_class->style_functions[CL_STYLE_CLASSIC]; + clearlooks_register_style_gummy (&clearlooks_style_class->style_functions[CL_STYLE_GUMMY]); } -static void -clearlooks_style_class_finalize (ClearlooksStyleClass *klass) +GType clearlooks_type_style = 0; + +void +clearlooks_style_register_type (GTypeModule * module) { + static const GTypeInfo object_info = + { + sizeof (ClearlooksStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_style_init, + NULL + }; + + clearlooks_type_style = g_type_module_register_type (module, + GTK_TYPE_STYLE, + "ClearlooksStyle", + &object_info, 0); } diff --git a/libs/clearlooks/clearlooks_style.h b/libs/clearlooks-newer/clearlooks_style.h index d524df5ddf..78f3ca1675 100644 --- a/libs/clearlooks/clearlooks_style.h +++ b/libs/clearlooks-newer/clearlooks_style.h @@ -1,7 +1,6 @@ -/* Clearlooks theme engine +/* Clearlooks Engine * Copyright (C) 2005 Richard Stellingwerff. - * Copyright (C) 2007 Benjamin Berg - * Copyright (C) 2007 Andrea Cimitan + * Copyright (C) 2006 Benjamin Berg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -22,7 +21,6 @@ * and by Alexander Larsson <alexl@redhat.com> * Modified by Richard Stellingwerff <remenic@gmail.com> */ - #include <gtk/gtkstyle.h> #ifndef CLEARLOOKS_STYLE_H @@ -34,7 +32,9 @@ typedef struct _ClearlooksStyle ClearlooksStyle; typedef struct _ClearlooksStyleClass ClearlooksStyleClass; -#define CLEARLOOKS_TYPE_STYLE (clearlooks_style_get_type ()) +GE_INTERNAL extern GType clearlooks_type_style; + +#define CLEARLOOKS_TYPE_STYLE clearlooks_type_style #define CLEARLOOKS_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_STYLE, ClearlooksStyle)) #define CLEARLOOKS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) #define CLEARLOOKS_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_STYLE)) @@ -48,12 +48,9 @@ struct _ClearlooksStyle ClearlooksColors colors; ClearlooksStyles style; - - guint8 reliefstyle; + guint8 menubarstyle; guint8 toolbarstyle; - GdkColor focus_color; - gboolean has_focus_color; GdkColor scrollbar_color; gboolean colorize_scrollbar; gboolean has_scrollbar_color; @@ -66,10 +63,8 @@ struct _ClearlooksStyleClass GtkStyleClass parent_class; ClearlooksStyleFunctions style_functions[CL_NUM_STYLES]; - ClearlooksStyleConstants style_constants[CL_NUM_STYLES]; }; -GE_INTERNAL void clearlooks_style_register_types (GTypeModule *module); -GE_INTERNAL GType clearlooks_style_get_type (void); +GE_INTERNAL void clearlooks_style_register_type (GTypeModule *module); #endif /* CLEARLOOKS_STYLE_H */ diff --git a/libs/clearlooks/clearlooks_theme_main.c b/libs/clearlooks-newer/clearlooks_theme_main.c index b68cfe4119..c042fdbac0 100644 --- a/libs/clearlooks/clearlooks_theme_main.c +++ b/libs/clearlooks-newer/clearlooks_theme_main.c @@ -7,8 +7,8 @@ GE_EXPORT void theme_init (GTypeModule *module) { - clearlooks_rc_style_register_types (module); - clearlooks_style_register_types (module); + clearlooks_rc_style_register_type (module); + clearlooks_style_register_type (module); } GE_EXPORT void diff --git a/libs/clearlooks-newer/clearlooks_types.h b/libs/clearlooks-newer/clearlooks_types.h new file mode 100644 index 0000000000..7caf8a3208 --- /dev/null +++ b/libs/clearlooks-newer/clearlooks_types.h @@ -0,0 +1,455 @@ +#ifndef CLEARLOOKS_TYPES_H +#define CLEARLOOKS_TYPES_H + +#include <ge-support.h> + +typedef unsigned char boolean; +typedef unsigned char uint8; +typedef struct _ClearlooksStyleFunctions ClearlooksStyleFunctions; + +typedef enum +{ + CL_STYLE_CLASSIC = 0, + CL_STYLE_GLOSSY = 1, + CL_STYLE_INVERTED = 2, + CL_STYLE_GUMMY = 3, + CL_NUM_STYLES = 4 +} ClearlooksStyles; + + +typedef enum +{ + CL_STATE_NORMAL, + CL_STATE_ACTIVE, + CL_STATE_SELECTED, + CL_STATE_INSENSITIVE +} ClearlooksStateType; + +typedef enum +{ + CL_JUNCTION_NONE = 0, + CL_JUNCTION_BEGIN = 1, + CL_JUNCTION_END = 2 +} ClearlooksJunction; + +typedef enum +{ + CL_STEPPER_UNKNOWN = 0, + CL_STEPPER_A = 1, + CL_STEPPER_B = 2, + CL_STEPPER_C = 4, + CL_STEPPER_D = 8 +} ClearlooksStepper; + +typedef enum +{ + CL_ORDER_FIRST, + CL_ORDER_MIDDLE, + CL_ORDER_LAST +} ClearlooksOrder; + +typedef enum +{ + CL_ORIENTATION_LEFT_TO_RIGHT, + CL_ORIENTATION_RIGHT_TO_LEFT, + CL_ORIENTATION_BOTTOM_TO_TOP, + CL_ORIENTATION_TOP_TO_BOTTOM +} ClearlooksOrientation; + +typedef enum +{ + CL_GAP_LEFT, + CL_GAP_RIGHT, + CL_GAP_TOP, + CL_GAP_BOTTOM +} ClearlooksGapSide; + +typedef enum +{ + CL_SHADOW_NONE, + CL_SHADOW_IN, + CL_SHADOW_OUT, + CL_SHADOW_ETCHED_IN, + CL_SHADOW_ETCHED_OUT +} ClearlooksShadowType; + +typedef enum +{ + CL_HANDLE_TOOLBAR, + CL_HANDLE_SPLITTER +} ClearlooksHandleType; + +typedef enum +{ + CL_ARROW_NORMAL, + CL_ARROW_COMBO +} ClearlooksArrowType; + +typedef enum +{ + CL_DIRECTION_UP, + CL_DIRECTION_DOWN, + CL_DIRECTION_LEFT, + CL_DIRECTION_RIGHT +} ClearlooksDirection; + +typedef enum +{ + CL_PROGRESSBAR_CONTINUOUS, + CL_PROGRESSBAR_DISCRETE +} ClearlooksProgressBarStyle; + +typedef enum +{ + CL_WINDOW_EDGE_NORTH_WEST, + CL_WINDOW_EDGE_NORTH, + CL_WINDOW_EDGE_NORTH_EAST, + CL_WINDOW_EDGE_WEST, + CL_WINDOW_EDGE_EAST, + CL_WINDOW_EDGE_SOUTH_WEST, + CL_WINDOW_EDGE_SOUTH, + CL_WINDOW_EDGE_SOUTH_EAST +} ClearlooksWindowEdge; + +typedef struct +{ + double x; + double y; + double width; + double height; +} ClearlooksRectangle; + +typedef struct +{ + CairoColor fg[5]; + CairoColor bg[5]; + CairoColor base[5]; + CairoColor text[5]; + + CairoColor shade[9]; + CairoColor spot[3]; +} ClearlooksColors; + +typedef struct +{ + boolean active; + boolean prelight; + boolean disabled; + boolean focus; + boolean is_default; + boolean ltr; + boolean enable_glow; + + gfloat radius; + + ClearlooksStateType state_type; + + uint8 corners; + uint8 xthickness; + uint8 ythickness; + + CairoColor parentbg; + + ClearlooksStyleFunctions *style_functions; +} WidgetParameters; + +typedef struct +{ + boolean lower; + boolean horizontal; + boolean fill_level; +} SliderParameters; + +typedef struct +{ + ClearlooksOrientation orientation; + boolean pulsing; + float value; +} ProgressBarParameters; + +typedef struct +{ + int linepos; +} OptionMenuParameters; + +typedef struct +{ + ClearlooksShadowType shadow; + ClearlooksGapSide gap_side; + int gap_x; + int gap_width; + const CairoColor *border; /* maybe changes this to some other hint ... */ +} FrameParameters; + +typedef struct +{ + ClearlooksGapSide gap_side; +} TabParameters; + +typedef struct +{ + CairoCorners corners; + ClearlooksShadowType shadow; +} ShadowParameters; + +typedef struct +{ + boolean horizontal; +} SeparatorParameters; + +typedef struct +{ + ClearlooksOrder order; /* XXX: rename to position */ + boolean resizable; +} ListViewHeaderParameters; + +typedef struct +{ + CairoColor color; + ClearlooksJunction junction; /* On which sides the slider junctions */ + boolean horizontal; + boolean has_color; +} ScrollBarParameters; + +typedef struct +{ + ClearlooksHandleType type; + boolean horizontal; +} HandleParameters; + +typedef struct +{ + ClearlooksStepper stepper; /* Which stepper to draw */ +} ScrollBarStepperParameters; + +typedef struct +{ + ClearlooksWindowEdge edge; +} ResizeGripParameters; + +typedef struct +{ + int style; +} MenuBarParameters; + +typedef struct +{ + ClearlooksShadowType shadow_type; + boolean in_cell; + boolean in_menu; +} CheckboxParameters; + +typedef struct +{ + ClearlooksArrowType type; + ClearlooksDirection direction; +} ArrowParameters; + +typedef struct +{ + int style; + boolean topmost; +} ToolbarParameters; + +struct _ClearlooksStyleFunctions +{ + void (*draw_button) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_scale_trough) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SliderParameters *slider, + int x, int y, int width, int height); + + void (*draw_progressbar_trough) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_progressbar_fill) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ProgressBarParameters *progressbar, + int x, int y, int width, int height, gint offset); + + void (*draw_slider_button) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SliderParameters *slider, + int x, int y, int width, int height); + + void (*draw_entry) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_spinbutton) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_spinbutton_down) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_optionmenu) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const OptionMenuParameters *optionmenu, + int x, int y, int width, int height); + + void (*draw_inset) (cairo_t *cr, + const CairoColor *bg_color, + double x, double y, double w, double h, + double radius, uint8 corners); + + void (*draw_menubar) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const MenuBarParameters *menubar, + int x, int y, int width, int height); + + void (*draw_tab) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const TabParameters *tab, + int x, int y, int width, int height); + + void (*draw_frame) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const FrameParameters *frame, + int x, int y, int width, int height); + + void (*draw_separator) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height); + + void (*draw_menu_item_separator) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const SeparatorParameters *separator, + int x, int y, int width, int height); + + void (*draw_list_view_header) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ListViewHeaderParameters *header, + int x, int y, int width, int height); + + void (*draw_toolbar) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ToolbarParameters *toolbar, + int x, int y, int width, int height); + + void (*draw_menuitem) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_menubaritem) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_selected_cell) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_scrollbar_stepper) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + const ScrollBarStepperParameters *stepper, + int x, int y, int width, int height); + + void (*draw_scrollbar_slider) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height); + + void (*draw_scrollbar_trough) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ScrollBarParameters *scrollbar, + int x, int y, int width, int height); + + void (*draw_statusbar) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_menu_frame) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_tooltip) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_handle) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const HandleParameters *handle, + int x, int y, int width, int height); + + void (*draw_resize_grip) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ResizeGripParameters *grip, + int x, int y, int width, int height); + + void (*draw_arrow) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const ArrowParameters *arrow, + int x, int y, int width, int height); + + void (*draw_checkbox) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height); + + void (*draw_radiobutton) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + const CheckboxParameters *checkbox, + int x, int y, int width, int height); + + /* Style internal functions */ + /* XXX: Only used by slider_button, inline it? */ + void (*draw_shadow) (cairo_t *cr, + const ClearlooksColors *colors, + gfloat radius, + int width, int height); + + void (*draw_slider) (cairo_t *cr, + const ClearlooksColors *colors, + const WidgetParameters *widget, + int x, int y, int width, int height); + + void (*draw_gripdots) (cairo_t *cr, + const ClearlooksColors *colors, int x, int y, + int width, int height, int xr, int yr, + float contrast); +}; + + +#define CLEARLOOKS_RECTANGLE_SET(rect, _x, _y, _w, _h) rect.x = _x; \ + rect.y = _y; \ + rect.width = _w; \ + rect.height = _h; + +#endif /* CLEARLOOKS_TYPES_H */ diff --git a/libs/clearlooks/config.h b/libs/clearlooks-newer/config.h index cfafc0134f..4326e37ec1 100644 --- a/libs/clearlooks/config.h +++ b/libs/clearlooks-newer/config.h @@ -1,13 +1,9 @@ -/* engines/support/config.h. Generated from config.h.in by configure. */ -/* engines/support/config.h.in. Generated from configure.ac by autoheader. */ +/* engines/clearlooks/src/config.h. Generated from config.h.in by configure. */ +/* engines/clearlooks/src/config.h.in. Generated from configure.ac by autoheader. */ /* always defined to indicate that i18n is enabled */ #define ENABLE_NLS 1 -/* Defines whether to enable runtime widget checks as a fallback to hints from - the theme. */ -#define ENABLE_WIDGET_CHECKS 1 - /* Gettext package */ #define GETTEXT_PACKAGE "gtk-engines" @@ -59,9 +55,6 @@ /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - /* Name of package */ #define PACKAGE "gtk-engines" @@ -72,16 +65,16 @@ #define PACKAGE_NAME "gtk-engines" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "gtk-engines 2.16.0" +#define PACKAGE_STRING "gtk-engines 2.12.2" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "gtk-engines" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2.16.0" +#define PACKAGE_VERSION "2.12.2" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "2.16.0" +#define VERSION "2.12.2" diff --git a/libs/clearlooks/cpdll.sh b/libs/clearlooks-newer/cpdll.sh index fb101d52a0..fb101d52a0 100755 --- a/libs/clearlooks/cpdll.sh +++ b/libs/clearlooks-newer/cpdll.sh diff --git a/libs/clearlooks/ge-support.h b/libs/clearlooks-newer/ge-support.h index bce9ced038..e0a42b6c3d 100644 --- a/libs/clearlooks/ge-support.h +++ b/libs/clearlooks-newer/ge-support.h @@ -5,4 +5,5 @@ #include "cairo-support.h" #include "widget-information.h" + #endif /* GE_SUPPORT_H */ diff --git a/libs/clearlooks/general-support.h b/libs/clearlooks-newer/general-support.h index 4d31946152..25999e2d31 100644 --- a/libs/clearlooks/general-support.h +++ b/libs/clearlooks-newer/general-support.h @@ -1,5 +1,3 @@ -#ifndef __GENERAL_SUPPORT_H -#define __GENERAL_SUPPORT_H #include <gmodule.h> #include <glib.h> @@ -39,5 +37,3 @@ # define GE_EXPORT __global # define GE_INTERNAL __hidden #endif - -#endif /* __GENERAL_SUPPORT_H */ diff --git a/libs/clearlooks/support.c b/libs/clearlooks-newer/support.c index ec35ef754b..6d4d8a286d 100644 --- a/libs/clearlooks/support.c +++ b/libs/clearlooks-newer/support.c @@ -66,34 +66,14 @@ clearlooks_get_parent_bg (const GtkWidget *widget, CairoColor *color) GtkStateType state_type; const GtkWidget *parent; GdkColor *gcolor; - gboolean stop; if (widget == NULL) return; parent = widget->parent; - stop = FALSE; - while (parent && !stop) - { - stop = FALSE; - - stop |= !GTK_WIDGET_NO_WINDOW (parent); - stop |= GTK_IS_NOTEBOOK (parent) && - gtk_notebook_get_show_tabs (GTK_NOTEBOOK (parent)) && - gtk_notebook_get_show_border (GTK_NOTEBOOK (parent)); - - if (GTK_IS_TOOLBAR (parent)) - { - GtkShadowType shadow = GTK_SHADOW_OUT; - gtk_widget_style_get (GTK_WIDGET (parent), "shadow-type", &shadow, NULL); - - stop |= (shadow != GTK_SHADOW_NONE); - } - - if (!stop) - parent = parent->parent; - } + while (parent && GTK_WIDGET_NO_WINDOW (parent) && !((GTK_IS_NOTEBOOK (parent)) || (GTK_IS_TOOLBAR (parent)))) + parent = parent->parent; if (parent == NULL) return; @@ -171,10 +151,8 @@ clearlooks_scrollbar_visible_steppers (GtkWidget *widget) { ClearlooksStepper steppers = 0; - /* If this is not a range widget, assume that the primary steppers - * are present. */ if (!GE_IS_RANGE (widget)) - return CL_STEPPER_A | CL_STEPPER_D; + return 0; if (GTK_RANGE (widget)->has_stepper_a) steppers |= CL_STEPPER_A; @@ -205,29 +183,20 @@ clearlooks_scrollbar_get_junction (GtkWidget *widget) if (adj->value <= adj->lower && (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b)) { - if (!gtk_range_get_inverted (GTK_RANGE (widget))) - junction |= CL_JUNCTION_BEGIN; - else - junction |= CL_JUNCTION_END; + junction |= CL_JUNCTION_BEGIN; } if (adj->value >= adj->upper - adj->page_size && (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d)) { - if (!gtk_range_get_inverted (GTK_RANGE (widget))) - junction |= CL_JUNCTION_END; - else - junction |= CL_JUNCTION_BEGIN; + junction |= CL_JUNCTION_END; } return junction; } void -clearlooks_set_toolbar_parameters (ToolbarParameters *toolbar, - GtkWidget *widget, - GdkWindow *window, - gint x, gint y) +clearlooks_set_toolbar_parameters (ToolbarParameters *toolbar, GtkWidget *widget, GdkWindow *window, gint x, gint y) { toolbar->topmost = FALSE; diff --git a/libs/clearlooks/support.h b/libs/clearlooks-newer/support.h index 23e33c58e7..23e33c58e7 100644 --- a/libs/clearlooks/support.h +++ b/libs/clearlooks-newer/support.h diff --git a/libs/clearlooks-newer/support.h.orig b/libs/clearlooks-newer/support.h.orig new file mode 100644 index 0000000000..a1430b40d0 --- /dev/null +++ b/libs/clearlooks-newer/support.h.orig @@ -0,0 +1,110 @@ +#include <gtk/gtk.h> +#include <math.h> +#include <string.h> + +/* GTK 2.2 compatibility */ +#ifndef GTK_IS_COMBO_BOX_ENTRY + #define GTK_IS_COMBO_BOX_ENTRY(x) 0 +#endif +#ifndef GTK_IS_COMBO_BOX + #define GTK_IS_COMBO_BOX(x) 0 +#endif + +#define RADIO_SIZE 13 +#define CHECK_SIZE 13 + +GtkTextDirection +get_direction (GtkWidget *widget); + +GdkPixbuf * +generate_bit (unsigned char alpha[], + GdkColor *color, + double mult); + +GdkPixbuf * +colorize_bit (unsigned char *bit, + unsigned char *alpha, + GdkColor *new_color); + +GdkPixmap * +pixbuf_to_pixmap (GtkStyle *style, + GdkPixbuf *pixbuf, + GdkScreen *screen); + +gboolean +sanitize_size (GdkWindow *window, + gint *width, + gint *height); + +void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b); + +void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s); + +void +shade (GdkColor * a, GdkColor * b, float k); + +void +draw_hgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *top_color, GdkColor *bottom_color); + +void +draw_vgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *left_color, GdkColor *right_color); + +void +arrow_draw_hline (GdkWindow *window, + GdkGC *gc, + int x1, + int x2, + int y, + gboolean last); + +void +arrow_draw_vline (GdkWindow *window, + GdkGC *gc, + int y1, + int y2, + int x, + gboolean last); + +void +draw_arrow (GdkWindow *window, + GdkGC *gc, + GdkRectangle *area, + GtkArrowType arrow_type, + gint x, + gint y, + gint width, + gint height); + +void +calculate_arrow_geometry (GtkArrowType arrow_type, + gint *x, + gint *y, + gint *width, + gint *height); + +GtkWidget *special_get_ancestor(GtkWidget * widget, + GType widget_type); + +void blend (GdkColormap *colormap, + GdkColor *a, GdkColor *b, GdkColor *c, int alpha); + +GtkWidget *get_parent_window (GtkWidget *widget); + +GdkColor *get_parent_bgcolor (GtkWidget *widget); + +gboolean is_combo_box (GtkWidget * widget); + +GtkWidget *find_combo_box_widget (GtkWidget * widget); + +void gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns); diff --git a/libs/clearlooks/widget-information.c b/libs/clearlooks-newer/widget-information.c index 8972d7a009..cbeb00e291 100644 --- a/libs/clearlooks/widget-information.c +++ b/libs/clearlooks-newer/widget-information.c @@ -2,169 +2,9 @@ #include "general-support.h" #include "widget-information.h" -#include "config.h" #include <math.h> #include <string.h> -static gchar ge_widget_hints[] = - "treeview\0" - "treeview-header\0" - "statusbar\0" - "comboboxentry\0" - "spinbutton\0" - "scale\0" - "vscale\0" - "hscale\0" - "scrollbar\0" - "vscrollbar\0" - "hscrollbar\0" - "progressbar\0" - "menubar\0"; - -gboolean -ge_check_hint (GEHint hint, - GQuark style_hint, - GtkWidget *widget) -{ - static GEHint quark_hint_lookup[GE_HINT_COUNT] = {0}; - - g_assert ((hint >= 0) && (hint < GE_HINT_COUNT)); - - /* Initilize lookup table */ - if (G_UNLIKELY (quark_hint_lookup[0] == 0)) - { - guint i = 0; - gchar *cur_hint_str = ge_widget_hints; - while ((i < GE_HINT_COUNT) && cur_hint_str[0]) - { - /* Can't use _from_static_string as the engine may be unloaded. */ - quark_hint_lookup[i] = g_quark_from_string (cur_hint_str); - cur_hint_str += strlen(cur_hint_str) + 1; - i++; - } - g_assert (i == GE_HINT_COUNT && cur_hint_str[0] == '\0'); - } - - - if (quark_hint_lookup[hint] == style_hint) - return TRUE; - - - /* Try to decide based on other hints, eg. hscale is also a scale. */ - if (hint == GE_HINT_SCALE) - if (ge_check_hint (GE_HINT_VSCALE, style_hint, widget) || - ge_check_hint (GE_HINT_HSCALE, style_hint, widget)) - return TRUE; - if (hint == GE_HINT_SCROLLBAR) - if (ge_check_hint (GE_HINT_VSCROLLBAR, style_hint, widget) || - ge_check_hint (GE_HINT_HSCROLLBAR, style_hint, widget)) - return TRUE; - if (hint == GE_HINT_TREEVIEW) - if (ge_check_hint (GE_HINT_TREEVIEW_HEADER, style_hint, widget)) - return TRUE; - - - /* These may be caused by applications so we never want to disable them. - * TODO: This does not catch the case where the theme uses appears-as-list - * and the application turns it off again. Though this case - * is even less likely. */ - switch (hint) { - case GE_HINT_COMBOBOX_ENTRY: - if (widget && ge_object_is_a (G_OBJECT (widget), "GtkComboBox")) - { - gboolean appears_as_list = FALSE; - - gtk_widget_style_get (widget, "appears-as-list", &appears_as_list, NULL); - - if (appears_as_list) - return TRUE; - } - break; - default: - break; - } - - -#ifdef ENABLE_WIDGET_CHECKS - /* If a style_hint *was* set, and nothing matched, just give up right away. - * A theme shall either support it fully, or not at all. */ - if (style_hint != 0) - return FALSE; - - /* No widget? Just give up. Nothing we can do. */ - if (widget == NULL) - return FALSE; - - /* Try to do something based on the passed in widget pointer. */ - switch (hint) { - case GE_HINT_TREEVIEW: - if (widget->parent && (ge_object_is_a (G_OBJECT (widget->parent), "GtkTreeView"))) - return TRUE; - break; - case GE_HINT_TREEVIEW_HEADER: - if (ge_object_is_a (G_OBJECT (widget), "GtkButton") && widget->parent && - (ge_object_is_a (G_OBJECT (widget->parent), "GtkTreeView") || ge_object_is_a (G_OBJECT (widget->parent), "GtkCList") || - ge_object_is_a (G_OBJECT (widget->parent), "GtkCTree"))) - return TRUE; - if (widget->parent && ge_object_is_a (G_OBJECT (widget->parent), "ETreeView")) - return TRUE; - break; - case GE_HINT_COMBOBOX_ENTRY: - if (ge_is_in_combo_box (widget)) - return TRUE; - break; - case GE_HINT_SPINBUTTON: - if (ge_object_is_a (G_OBJECT (widget), "GtkSpinButton")) - return TRUE; - break; - case GE_HINT_STATUSBAR: - if (widget->parent && ge_object_is_a (G_OBJECT (widget), "GtkStatusbar")) - return TRUE; - break; - case GE_HINT_SCALE: - if (ge_object_is_a (G_OBJECT (widget), "GtkScale")) - return TRUE; - break; - case GE_HINT_HSCALE: - if (ge_object_is_a (G_OBJECT (widget), "GtkHScale")) - return TRUE; - break; - case GE_HINT_VSCALE: - if (ge_object_is_a (G_OBJECT (widget), "GtkVScale")) - return TRUE; - break; - case GE_HINT_SCROLLBAR: - if (ge_object_is_a (G_OBJECT (widget), "GtkScrollbar")) - return TRUE; - break; - case GE_HINT_HSCROLLBAR: - if (ge_object_is_a (G_OBJECT (widget), "GtkHScrollbar")) - return TRUE; - break; - case GE_HINT_VSCROLLBAR: - if (ge_object_is_a (G_OBJECT (widget), "GtkVScrollbar")) - return TRUE; - break; - case GE_HINT_PROGRESSBAR: - if (ge_object_is_a (G_OBJECT (widget), "GtkProgressBar")) - return TRUE; - break; - case GE_HINT_MENUBAR: - if (ge_object_is_a (G_OBJECT (widget), "GtkMenuBar") || - ge_object_is_a (G_OBJECT (widget->parent), "GtkMenuBar")) - return TRUE; - break; - - default: - break; - } - -#endif - - - return FALSE; -} - /* Widget Type Lookups/Macros Based on/modified from functions in @@ -200,14 +40,21 @@ ge_is_combo_box_entry (GtkWidget * widget) } return result; } - + static gboolean ge_combo_box_is_using_list (GtkWidget * widget) { gboolean result = FALSE; if (GE_IS_COMBO_BOX (widget)) - gtk_widget_style_get (widget, "appears-as-list", &result, NULL); + { + gboolean *tmp = NULL; + + gtk_widget_style_get (widget, "appears-as-list", &result, NULL); + + if (tmp) + result = *tmp; + } return result; } @@ -395,8 +242,8 @@ ge_find_combo_box_widget_parent (GtkWidget * widget) ***********************************************/ void ge_option_menu_get_props (GtkWidget * widget, - GtkRequisition * indicator_size, - GtkBorder * indicator_spacing) + GtkRequisition * indicator_size, + GtkBorder * indicator_spacing) { GtkRequisition default_size = { 9, 5 }; GtkBorder default_spacing = { 7, 5, 2, 2 }; @@ -446,6 +293,7 @@ ge_button_get_default_border (GtkWidget *widget, } } + gboolean ge_widget_is_ltr (GtkWidget *widget) { @@ -462,26 +310,3 @@ ge_widget_is_ltr (GtkWidget *widget) else return TRUE; } - -guint -ge_rc_parse_hint (GScanner *scanner, - GQuark *quark) -{ - guint token; - - /* Skip 'hint' */ - token = g_scanner_get_next_token(scanner); - - token = g_scanner_get_next_token(scanner); - if (token != G_TOKEN_EQUAL_SIGN) - return G_TOKEN_EQUAL_SIGN; - - token = g_scanner_get_next_token(scanner); - if (token != G_TOKEN_STRING) - return G_TOKEN_STRING; - - *quark = g_quark_from_string (scanner->value.v_string); - - return G_TOKEN_NONE; -} - diff --git a/libs/clearlooks/widget-information.h b/libs/clearlooks-newer/widget-information.h index 7b9b2ab334..55da859d78 100644 --- a/libs/clearlooks/widget-information.h +++ b/libs/clearlooks-newer/widget-information.h @@ -1,45 +1,18 @@ -#ifndef WIDGET_INFORMATION_H -#define WIDGET_INFORMATION_H - -#include "general-support.h" -#include <glib.h> -#include <gtk/gtkwidget.h> - -typedef enum { - GE_HINT_TREEVIEW, - GE_HINT_TREEVIEW_HEADER, - GE_HINT_STATUSBAR, - GE_HINT_COMBOBOX_ENTRY, - GE_HINT_SPINBUTTON, - GE_HINT_SCALE, - GE_HINT_VSCALE, - GE_HINT_HSCALE, - GE_HINT_SCROLLBAR, - GE_HINT_VSCROLLBAR, - GE_HINT_HSCROLLBAR, - GE_HINT_PROGRESSBAR, - GE_HINT_MENUBAR, - GE_HINT_COUNT -} GEHint; - -/* ALL OF THE FOLLOWING SHOULD DIE ... - * instead the hint system will be used, and a huge switch ;-) */ - /* Object Type Lookups/Macros Based on/modified from functions in Smooth-Engine. */ -#define GE_IS_WIDGET(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkWidget")) -#define GE_IS_CONTAINER(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkContainer")) -#define GE_IS_BIN(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkBin")) +#define GE_IS_WIDGET(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkWidget")) +#define GE_IS_CONTAINER(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkContainer")) +#define GE_IS_BIN(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkBin")) -#define GE_IS_ARROW(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkArrow")) +#define GE_IS_ARROW(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkArrow")) -#define GE_IS_SEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkSeparator")) -#define GE_IS_VSEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVSeparator")) -#define GE_IS_HSEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHSeparator")) +#define GE_IS_SEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkSeparator")) +#define GE_IS_VSEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkVSeparator")) +#define GE_IS_HSEPARATOR(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHSeparator")) #define GE_IS_HANDLE_BOX(object) ((object) && ge_object_is_a ((GObject*)(object), "GtkHandleBox")) #define GE_IS_HANDLE_BOX_ITEM(object) ((object) && GE_IS_HANDLE_BOX(object->parent)) @@ -100,9 +73,6 @@ typedef enum { #define GE_WIDGET_HAS_DEFAULT(object) ((object) && GE_IS_WIDGET(object) && GTK_WIDGET_HAS_DEFAULT(object)) - -GE_INTERNAL gboolean ge_check_hint (GEHint hint, GQuark style_hint, GtkWidget *widget); - GE_INTERNAL gboolean ge_object_is_a (const GObject * object, const gchar * type_name); GE_INTERNAL gboolean ge_is_combo_box_entry (GtkWidget * widget); @@ -127,6 +97,3 @@ GE_INTERNAL void ge_button_get_default_border (GtkWidget *widget, GE_INTERNAL gboolean ge_widget_is_ltr (GtkWidget *widget); -GE_INTERNAL guint ge_rc_parse_hint (GScanner *scanner, GQuark *quark); - -#endif /* WIDGET_INFORMATION_H */ diff --git a/libs/clearlooks-older/SConscript b/libs/clearlooks-older/SConscript new file mode 100644 index 0000000000..4feff6db90 --- /dev/null +++ b/libs/clearlooks-older/SConscript @@ -0,0 +1,36 @@ +# -*- python -*- + +import os.path +import glob + +libclearlooks_files = [ + 'clearlooks_draw.c', + 'clearlooks_rc_style.c', + 'clearlooks_style.c', + 'clearlooks_theme_main.c', + 'support.c' ] + +Import ('env install_prefix') + +clearlooks = env.Clone() + +clearlooks.Replace(CCFLAGS = ' `pkg-config --cflags gtk+-2.0` ', + LINKFLAGS = ' `pkg-config --libs gtk+-2.0` ') + +if env['GTKOSX']: + clearlooks.Append (CCFLAGS = '-DGTKOSX') + +libclearlooks = clearlooks.SharedLibrary('clearlooks', libclearlooks_files) + +usable_libclearlooks = clearlooks.Install ('engines', libclearlooks) +Default (usable_libclearlooks) + +env.Alias('install', + env.Install(os.path.join(install_prefix,env['LIBDIR'], 'ardour2', 'engines'), + libclearlooks)) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript', 'bits.c'] + + libclearlooks_files + + glob.glob('*.h') + )) diff --git a/libs/clearlooks-older/bits.c b/libs/clearlooks-older/bits.c new file mode 100644 index 0000000000..1e871bc5d3 --- /dev/null +++ b/libs/clearlooks-older/bits.c @@ -0,0 +1,121 @@ +static unsigned char dot_intensity[] = { +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x98,0xb9,0xc6,0xb9,0x91,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0xbd,0xac,0x9e,0x65,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xc6,0xac,0x9e,0x96,0x5c,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0xb9,0x9e,0x96,0x62,0x55,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x91,0x65,0x5c,0x55,0x68,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e,0x6e, +}; +static unsigned char dot_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xc4,0xff,0xff,0xff,0xff,0xff,0xc4,0x00,0x00,0x00, +0x00,0x00,0x00,0x66,0xdf,0xff,0xff,0xff,0xdf,0x66,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0xc4,0xff,0xc4,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; + +static unsigned char circle_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x23,0x62,0x92,0xb3,0xb2,0x95,0x2b,0x00,0x00,0x00, +0x00,0x00,0x3e,0xab,0xc9,0xeb,0xf9,0xf5,0xfd,0xff,0x57,0x00,0x00, +0x00,0x1f,0xb5,0xd8,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x67,0xb9,0xf2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x9a,0xe2,0xfc,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0xba,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xc0,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe5,0x00, +0x00,0x9b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x9c,0x00, +0x00,0x2b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2b,0x00, +0x00,0x00,0x57,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x57,0x00,0x00, +0x00,0x00,0x00,0x2b,0x9c,0xe5,0xff,0xe5,0x9c,0x2b,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char outline_alpha[] = { +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe9, +0xac,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xac, +0x4a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4a, +0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00, +0x00,0x00,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x98,0x00,0x00, +0x00,0x00,0x00,0x4a,0xac,0xe9,0xff,0xe9,0xac,0x4a,0x00,0x00,0x00, +}; +static unsigned char inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, +0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_base_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 11, 137, 151,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00, 9, 183, 172, 7,0x00,0x00, +0x00,0x00, 12, 18,0x00,0x00, 3, 161, 233, 27,0x00,0x00,0x00, +0x00,0x00, 199, 239, 101,0x00, 85, 253, 108,0x00,0x00,0x00,0x00, +0x00,0x00, 83, 245, 250, 75, 206, 230, 8,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 104, 252, 243, 253, 124,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00, 2, 162, 255, 241, 28,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, 18, 228, 163,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00, 78, 62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static unsigned char check_inconsistent_alpha[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; diff --git a/libs/clearlooks-older/clearlooks_draw.c b/libs/clearlooks-older/clearlooks_draw.c new file mode 100644 index 0000000000..144be35152 --- /dev/null +++ b/libs/clearlooks-older/clearlooks_draw.c @@ -0,0 +1,1293 @@ +#include "clearlooks_draw.h" +#include "clearlooks_style.h" + +#include "support.h" + +/** WANTED: + FASTER GRADIENT FILL FUNCTION, POSSIBLY USING XRENDER. **/ + +static void cl_draw_borders (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +static void cl_draw_line (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x1, int y1, int x2, int y2, CLBorderType border, + CLRectangle *r); + +static void cl_draw_corner (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, + CLRectangle *r, CLCornerSide corner); + +static void cl_draw_fill (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +void cl_draw_rectangle (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + if (r->fillgc) + { + cl_draw_fill(window, widget, style, x, y, width, height, r); + } + + if (r->bordergc) + { + cl_draw_borders(window, widget, style, x, y, width, height, r); + } +} + + +static void cl_get_coords ( CLBorderType border, + int x, int y, int width, int height, + CLRectangle *r, int *x1, int *y1, int *x2, int *y2) +{ + switch (border) + { + case CL_BORDER_TOP: + *x1 = x + r->corners[CL_CORNER_TOPLEFT]; + *x2 = *x1 + width - r->corners[CL_CORNER_TOPLEFT] - r->corners[CL_CORNER_TOPRIGHT] - 1; + *y1 = *y2 = y; + break; + case CL_BORDER_BOTTOM: + *x1 = x + r->corners[CL_CORNER_BOTTOMLEFT]; + *x2 = *x1 + width - r->corners[CL_CORNER_BOTTOMLEFT] - r->corners[CL_CORNER_BOTTOMRIGHT] - 1; + *y1 = *y2 = y + height - 1; + break; + case CL_BORDER_LEFT: + *x1 = *x2 = x; + *y1 = y + r->corners[CL_CORNER_TOPLEFT]; + *y2 = *y1 + height - r->corners[CL_CORNER_TOPLEFT] - r->corners[CL_CORNER_BOTTOMLEFT] - 1; + break; + case CL_BORDER_RIGHT: + *x1 = *x2 = x + width - 1; + *y1 = y + r->corners[CL_CORNER_TOPRIGHT]; + *y2 = *y1 + height - r->corners[CL_CORNER_TOPRIGHT] - r->corners[CL_CORNER_BOTTOMRIGHT] - 1; + break; + } +} + +void cl_draw_borders (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + int x1, y1, x2, y2, i; + + if (r->bordergc == NULL) + return; + + for ( i=0; i<4; i++) /* draw all four borders + corners */ + { + cl_get_coords (i, x, y, width, height, r, &x1, &y1, &x2, &y2); + cl_draw_line (window, widget, style, x1, y1, x2, y2, i, r); + cl_draw_corner (window, widget, style, x, y, width, height, r, i ); + } +} + + +static GdkColor cl_gc_get_foreground(GdkGC *gc) +{ + GdkGCValues values; + gdk_gc_get_values (gc, &values); + return values.foreground; +} + +static void cl_draw_line (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x1, int y1, int x2, int y2, CLBorderType border, + CLRectangle *r) +{ + if (r->gradient_type == CL_GRADIENT_NONE || + r->border_gradient.from == NULL || r->border_gradient.to == NULL ) + { + gdk_draw_line (window, r->bordergc, x1, y1, x2, y2); + } + else if (r->gradient_type == CL_GRADIENT_HORIZONTAL && (border == CL_BORDER_TOP || border == CL_BORDER_BOTTOM)) + { + draw_vgradient (window, r->bordergc, style, + x1, y1, x2-x1+1, 1, + r->border_gradient.from, r->border_gradient.to); + } + else if (r->gradient_type == CL_GRADIENT_VERTICAL && (border == CL_BORDER_LEFT || border == CL_BORDER_RIGHT)) + { + draw_hgradient (window, r->bordergc, style, + x1, y1, 1, y2-y1+1, + r->border_gradient.from, r->border_gradient.to); + } + else + { + GdkColor tmp_color = cl_gc_get_foreground (r->bordergc); + + if (r->gradient_type == CL_GRADIENT_HORIZONTAL && border == CL_BORDER_LEFT || + r->gradient_type == CL_GRADIENT_VERTICAL && border == CL_BORDER_TOP) + gdk_gc_set_foreground (r->bordergc, r->border_gradient.from); + else + gdk_gc_set_foreground (r->bordergc, r->border_gradient.to); + + gdk_draw_line (window, r->bordergc, x1, y1, x2, y2); + + gdk_gc_set_foreground (r->bordergc, &tmp_color); + } +} + +static GdkColor *cl_get_gradient_corner_color (CLRectangle *r, CLCornerSide corner) +{ + GdkColor *color; + + if (r->border_gradient.from == NULL || r->border_gradient.to == NULL) + { + color = NULL; + } + else if ((r->gradient_type == CL_GRADIENT_HORIZONTAL && (corner == CL_CORNER_TOPLEFT || corner == CL_CORNER_BOTTOMLEFT)) || + (r->gradient_type == CL_GRADIENT_VERTICAL && (corner == CL_CORNER_TOPLEFT || corner == CL_CORNER_TOPRIGHT))) + { + color = r->border_gradient.from; + } + else /* no gradient or other corner */ + { + color = r->border_gradient.to; + } + + return color; +} + +static void cl_draw_corner (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, + CLRectangle *r, CLCornerSide corner) +{ + GdkColor *color; + GdkColor aacolor; /* anti-aliasing color */ + GdkGCValues values; + GdkColor tmp; + GdkColor *bgcolor; + + int x1; + int y1; + + if (r->corners[corner] == CL_CORNER_NONE) + return; + + color = cl_get_gradient_corner_color (r, corner); + gdk_gc_get_values (r->bordergc, &values); + + if (color == NULL) + { + tmp = values.foreground; + gdk_colormap_query_color (gtk_widget_get_colormap(widget), values.foreground.pixel, &tmp); + color = &tmp; + } + + bgcolor = get_parent_bgcolor(widget); + + if (bgcolor == NULL) + { + bgcolor = color; + } + + blend (style->colormap, bgcolor, color, &aacolor, 70); + + if (r->corners[corner] == CL_CORNER_ROUND) + { + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x+1 : x+width - 2; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y+1 : y+height - 2; + + gdk_gc_set_foreground (r->bordergc, color); + gdk_draw_point (window, r->bordergc, x1, y1); + + gdk_gc_set_foreground (r->bordergc, &aacolor); + + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x+1 : x+width-2; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y : y+height-1; + + gdk_draw_point (window, r->bordergc, x1, y1); + + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x : x+width-1; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y+1 : y+height-2; + + gdk_draw_point (window, r->bordergc, x1, y1); + + } + else if (r->corners[corner] == CL_CORNER_NARROW) + { + x1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_BOTTOMLEFT) ? x : x+width-1; + + y1 = (corner == CL_CORNER_TOPLEFT || + corner == CL_CORNER_TOPRIGHT) ? y : y+height-1; + + gdk_gc_set_foreground (r->bordergc, &aacolor); + gdk_draw_point (window, r->bordergc, x1, y1); + } + + gdk_gc_set_foreground (r->bordergc, &values.foreground); +} + +static void cl_draw_fill (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + if (r->gradient_type == CL_GRADIENT_NONE || + r->fill_gradient.from == NULL || r->fill_gradient.to == NULL) + { + gdk_draw_rectangle (window, r->fillgc, TRUE, + x+1, y+1, width-2, height-2); + } + else if (r->gradient_type == CL_GRADIENT_HORIZONTAL) + { + draw_vgradient (window, r->fillgc, gtk_widget_get_style(widget), + x+1, y+1, width-2, height-2, + r->fill_gradient.from, r->fill_gradient.to); + } + else if (r->gradient_type == CL_GRADIENT_VERTICAL) + { + draw_hgradient (window, r->fillgc, gtk_widget_get_style(widget), + x+1, y+1, width-2, height-2, + r->fill_gradient.from, r->fill_gradient.to); + } +} + +void cl_rectangle_set_button(CLRectangle *r, GtkStyle *style, + GtkStateType state_type, gboolean has_default, + gboolean has_focus, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0; + GdkGC *border_gc = clearlooks_style->border_gc[CL_BORDER_UPPER+my_state_type]; + + + cl_rectangle_init (r, style->bg_gc[state_type], + clearlooks_style->border_gc[CL_BORDER_UPPER+my_state_type], + tl, tr, bl, br); + + if (state_type != GTK_STATE_INSENSITIVE && !has_default) + { + cl_rectangle_set_gradient (&r->border_gradient, + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type], + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]); + } + else if (has_default) + r->bordergc = style->black_gc; + else + r->bordergc = clearlooks_style->shade_gc[4]; + + r->gradient_type = CL_GRADIENT_VERTICAL; + + r->topleft = (state_type != GTK_STATE_ACTIVE) ? style->light_gc[state_type] : clearlooks_style->shade_gc[4]; + r->bottomright = (state_type != GTK_STATE_ACTIVE) ? clearlooks_style->shade_gc[1] : NULL; + + shade (&style->bg[state_type], &r->tmp_color, 0.93); + + + cl_rectangle_set_gradient (&r->fill_gradient, + &style->bg[state_type], + &r->tmp_color); +} + +void cl_rectangle_set_entry (CLRectangle *r, GtkStyle *style, + GtkStateType state_type, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br, + gboolean has_focus) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *bordergc; + + if (has_focus) + bordergc = clearlooks_style->spot3_gc; + else if (state_type != GTK_STATE_INSENSITIVE) + bordergc = clearlooks_style->border_gc[CL_BORDER_LOWER]; + else + bordergc = clearlooks_style->shade_gc[3]; + + cl_rectangle_init (r, style->base_gc[state_type], bordergc, + tl, tr, bl, br); + + if (state_type != GTK_STATE_INSENSITIVE ) + r->topleft = (has_focus) ? clearlooks_style->spot1_gc + : style->bg_gc[GTK_STATE_NORMAL]; + + if (has_focus) + r->bottomright = clearlooks_style->spot1_gc; + else if (state_type == GTK_STATE_INSENSITIVE) + r->bottomright = style->base_gc[state_type]; +} + +void cl_draw_shadow(GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int x1, y1, x2, y2; + + if (r->bottomright != NULL) + { + x1 = x+1+(r->corners[CL_CORNER_BOTTOMLEFT]/2); + y1 = y2 = y+height-2; + x2 = x+width - 1 - (1+r->corners[CL_CORNER_BOTTOMRIGHT]/2); + + gdk_draw_line (window, r->bottomright, x1, y1, x2, y2); + + x1 = x2 = x+width-2; + y1 = y+1+(r->corners[CL_CORNER_TOPRIGHT]/2); + y2 = y+height - 1 - (1+r->corners[CL_CORNER_BOTTOMRIGHT]/2); + + gdk_draw_line (window, r->bottomright, x1, y1, x2, y2); + } + + if (r->topleft != NULL) + { + x1 = x+1+(r->corners[CL_CORNER_TOPLEFT]/2); + y1 = y2 = y+1; + x2 = x+width-1-(1+r->corners[CL_CORNER_TOPRIGHT]/2); + + gdk_draw_line (window, r->topleft, x1, y1, x2, y2); + + x1 = x2 = x+1; + y1 = y+1+(r->corners[CL_CORNER_TOPLEFT]/2); + y2 = y+height-1-(1+r->corners[CL_CORNER_BOTTOMLEFT]/2); + + gdk_draw_line (window, r->topleft, x1, y1, x2, y2); + } +} + +void cl_rectangle_set_color (CLGradient *g, GdkColor *color) +{ + g->from = color; + g->to = color; +} + +void cl_rectangle_set_gradient (CLGradient *g, GdkColor *from, GdkColor *to) +{ + g->from = from; + g->to = to; +} + +void cl_rectangle_init (CLRectangle *r, + GdkGC *fillgc, GdkGC *bordergc, + int tl, int tr, int bl, int br) +{ + r->gradient_type = CL_GRADIENT_NONE; + + r->border_gradient.from = r->border_gradient.to = NULL; + r->fill_gradient.from = r->fill_gradient.to = NULL; + + r->fillgc = fillgc; + r->bordergc = bordergc; + + r->topleft = NULL; + r->bottomright = NULL; + + r->corners[CL_CORNER_TOPLEFT] = tl; + r->corners[CL_CORNER_TOPRIGHT] = tr; + r->corners[CL_CORNER_BOTTOMLEFT] = bl; + r->corners[CL_CORNER_BOTTOMRIGHT] = br; +} + +void cl_rectangle_set_corners (CLRectangle *r, int tl, int tr, int bl, int br) +{ + r->corners[CL_CORNER_TOPLEFT] = tl; + r->corners[CL_CORNER_TOPRIGHT] = tr; + r->corners[CL_CORNER_BOTTOMLEFT] = bl; + r->corners[CL_CORNER_BOTTOMRIGHT] = br; +} + +void cl_set_corner_sharpness (const gchar *detail, GtkWidget *widget, CLRectangle *r) +{ + if (widget->parent && GTK_IS_COMBO_BOX_ENTRY (widget->parent) || GTK_IS_COMBO (widget->parent)) + { + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + int cl = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + int cr = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND; + + cl_rectangle_set_corners (r, cl, cr, cl, cr); + } + else if (detail && !strcmp (detail, "spinbutton_up")) + { + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + int tl = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + int tr = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND; + + cl_rectangle_set_corners (r, tl, tr, + CL_CORNER_NONE, CL_CORNER_NONE); + } + else if (detail && !strcmp (detail, "spinbutton_down")) + { + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + int bl = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + int br = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND; + + cl_rectangle_set_corners (r, CL_CORNER_NONE, CL_CORNER_NONE, + bl, br); + } + else + { + cl_rectangle_set_corners (r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + }; +} + +void cl_rectangle_set_clip_rectangle (CLRectangle *r, GdkRectangle *area) +{ + if (area == NULL) + return; + + if (r->fillgc) + gdk_gc_set_clip_rectangle (r->fillgc, area); + + if (r->bordergc) + gdk_gc_set_clip_rectangle (r->bordergc, area); + + if (r->topleft) + gdk_gc_set_clip_rectangle (r->topleft, area); + + if (r->bottomright) + gdk_gc_set_clip_rectangle (r->bottomright, area); +} + +void cl_rectangle_reset_clip_rectangle (CLRectangle *r) +{ + if (r->fillgc) + gdk_gc_set_clip_rectangle (r->fillgc, NULL); + + if (r->bordergc) + gdk_gc_set_clip_rectangle (r->bordergc, NULL); + + if (r->topleft) + gdk_gc_set_clip_rectangle (r->topleft, NULL); + + if (r->bottomright) + gdk_gc_set_clip_rectangle (r->bottomright, NULL); +} + +void cl_rectangle_reset (CLRectangle *r, GtkStyle *style) +{ + cl_rectangle_init (r, + NULL, NULL, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); +} + +static void cl_progressbar_points_transform (GdkPoint *points, int npoints, + int offset, gboolean is_horizontal) +{ + int i; + for ( i=0; i<npoints; i++) { + if ( is_horizontal ) + points[i].x += offset; + else + points[i].y += offset; + } +} + +GdkPixmap* cl_progressbar_tile_new (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, gint height, gint offset) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int width = height; + int line = 0; + int center = width/2; + int xdir = 1; + int trans; + + int stripe_width = height/2; + int topright = height + stripe_width; + int topright_div_2 = topright/2; + + double shift; + GdkPoint points[4]; + + GtkProgressBarOrientation orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget)); + gboolean is_horizontal = (orientation == GTK_PROGRESS_LEFT_TO_RIGHT || orientation == GTK_PROGRESS_RIGHT_TO_LEFT) ? 1 : 0; + + GdkPixmap *tmp = gdk_pixmap_new (widget->window, width, height, -1); + + GdkColor tmp_color; + shade (&clearlooks_style->spot2, &tmp_color, 0.90); + + if (is_horizontal) + draw_hgradient (tmp, style->black_gc, style, 0, 0, width, height, + &clearlooks_style->spot2, &tmp_color ); + else + draw_vgradient (tmp, style->black_gc, style, 0, 0, width, height, + &tmp_color, &clearlooks_style->spot2); /* TODO: swap for RTL */ + + if (orientation == GTK_PROGRESS_RIGHT_TO_LEFT || + orientation == GTK_PROGRESS_BOTTOM_TO_TOP) + { + offset = -offset; + xdir = -1; + } + + if (get_direction (widget) == GTK_TEXT_DIR_RTL) + offset = -offset; + + if (is_horizontal) + { + points[0] = (GdkPoint){xdir*(topright - stripe_width - topright_div_2), 0}; /* topleft */ + points[1] = (GdkPoint){xdir*(topright - topright_div_2), 0}; /* topright */ + points[2] = (GdkPoint){xdir*(stripe_width - topright_div_2), height}; /* bottomright */ + points[3] = (GdkPoint){xdir*(-topright_div_2), height}; /* bottomleft */ + } + else + { + points[0] = (GdkPoint){height, xdir*(topright - stripe_width - topright_div_2)}; /* topleft */ + points[1] = (GdkPoint){height, xdir*(topright - topright_div_2)}; /* topright */ + points[2] = (GdkPoint){0, xdir*(stripe_width - topright_div_2)}; /* bottomright */ + points[3] = (GdkPoint){0, xdir*(-topright_div_2)}; /* bottomleft */ + } + + + shift = (stripe_width*2)/(double)10; + cl_progressbar_points_transform (points, 4, (offset*shift), is_horizontal); + + trans = (width/2)-1-(stripe_width*2); + cl_progressbar_points_transform (points, 4, trans, is_horizontal); + gdk_draw_polygon (tmp, clearlooks_style->spot2_gc, TRUE, points, 4); + cl_progressbar_points_transform (points, 4, -trans, is_horizontal); + + trans = width/2-1; + cl_progressbar_points_transform (points, 4, trans, is_horizontal); + gdk_draw_polygon (tmp, clearlooks_style->spot2_gc, TRUE, points, 4); + cl_progressbar_points_transform (points, 4, -trans, is_horizontal); + + trans = (width/2)-1+(stripe_width*2); + cl_progressbar_points_transform (points, 4, trans, is_horizontal); + gdk_draw_polygon (tmp, clearlooks_style->spot2_gc, TRUE, points, 4); + + return tmp; +} + +/* could be improved, I think. */ +void cl_progressbar_fill (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, GdkGC *gc, + gint x, gint y, + gint width, gint height, + guint8 offset, GdkRectangle *area) +{ + GtkProgressBarOrientation orientation = gtk_progress_bar_get_orientation (GTK_PROGRESS_BAR (widget)); + gint size = (orientation == GTK_PROGRESS_LEFT_TO_RIGHT || orientation == GTK_PROGRESS_RIGHT_TO_LEFT) ? height : width; + GdkPixmap *tile = cl_progressbar_tile_new (widget->window, widget, style, size, offset); + + gint nx = x, + ny = y, + nwidth = height, + nheight = width; + + gdk_gc_set_clip_rectangle (gc, area); + + switch (orientation) + { + case GTK_PROGRESS_LEFT_TO_RIGHT: + { + while (nx <= x + width ) + { + if (nx + nwidth > x+width ) nwidth = (x+width) - nx; + gdk_draw_drawable (drawable, gc, tile, 0, 0, nx, y, nwidth, height); + if (height <= 1) + nx += 1; + else + nx += (height-1 + !(height % 2)); + } + break; + } + case GTK_PROGRESS_RIGHT_TO_LEFT: + { + gint src_x = 0, dst_x; + nx += width; + while (nx >= x ) + { + dst_x = nx - height; + if (dst_x < x ) + { + src_x = x - dst_x; + dst_x = x; + } + gdk_draw_drawable (drawable, gc, tile, src_x, 0, dst_x, y, nwidth, height); + if (height <= 1) + nx -= 1; + else + nx -= (height-1 + !(height % 2)); + } + break; + } + case GTK_PROGRESS_TOP_TO_BOTTOM: + { + while (ny <= y + height ) + { + if (ny + nheight > y+height ) nheight = (y+height) - ny; + gdk_draw_drawable (drawable, gc, tile, 0, 0, x, ny, width, nheight); + if (width <= 1) + ny += 1; + else + ny += (width-1 + !(width % 2)); + } + break; + } + case GTK_PROGRESS_BOTTOM_TO_TOP: + { + gint src_y = 0, dst_y; + ny += height; + while (ny >= y ) + { + dst_y = ny - width; + if (dst_y < y ) + { + src_y = y - dst_y; + dst_y = y; + } + gdk_draw_drawable (drawable, gc, tile, 0, src_y, x, dst_y, width, width); + if (width <= 1) + ny -= 1; + else + ny -= (width-1 + !(width % 2)); + } + break; + } + } + + gdk_gc_set_clip_rectangle (gc, NULL); + + g_object_unref (tile); +} + +GdkColor cl_gc_set_fg_color_shade (GdkGC *gc, GdkColormap *colormap, + GdkColor *from, gfloat s) +{ + GdkColor tmp_color; + GdkGCValues values; + + shade (from, &tmp_color, s); + gdk_gc_get_values (gc, &values); + gdk_rgb_find_color (colormap, &tmp_color); + gdk_gc_set_foreground (gc, &tmp_color); + + return values.foreground; +} + +/* #warning MOVE THIS TO SUPPORT.C/H SO THE DRAW_CORNER FUNCTION CAN USE IT. OR, MAKE DRAW_CORNER USE IT SOME OTHER WAY. */ + +static void cl_get_window_style_state (GtkWidget *widget, GtkStyle **style, GtkStateType *state_type) +{ + GtkStyle *windowstyle = NULL; + GtkWidget *tmpwidget = widget; + GtkStateType windowstate; + + if (widget && GTK_IS_ENTRY (widget)) + tmpwidget = tmpwidget->parent; + + while (tmpwidget && GTK_WIDGET_NO_WINDOW (tmpwidget) && !GTK_IS_NOTEBOOK(tmpwidget)) + { + tmpwidget = tmpwidget->parent; + } + + *style = tmpwidget->style; + *state_type = GTK_WIDGET_STATE(tmpwidget); +} + +static GdkGC *cl_get_window_bg_gc (GtkWidget *widget) +{ + GtkStyle *style; + GtkStateType state_type; + + cl_get_window_style_state (widget, &style, &state_type); + + return style->bg_gc[state_type]; +} + +/****************************************************************************** + * DRAW THE MIGHTY WIDGETS! * + ******************************************************************************/ + +void cl_draw_inset (GtkStyle *style, GdkWindow *window, GtkWidget *widget, + GdkRectangle *area, + gint x, gint y, gint width, gint height, + int tl, int tr, int bl, int br ) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + ClearlooksStyle *clwindowstyle; /* style of the window this widget is on */ + GtkStateType windowstate; + CLRectangle r; + + cl_rectangle_init (&r, NULL, style->black_gc, + tl, tr, bl, br); + + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_get_window_style_state(widget, (GtkStyle**)&clwindowstyle, &windowstate); + + g_assert (clwindowstyle != NULL); + + if (GTK_WIDGET_HAS_DEFAULT (widget)) + { + r.bordergc = style->mid_gc[GTK_STATE_NORMAL]; + } + else + { + cl_rectangle_set_gradient (&r.border_gradient, + &clwindowstyle->inset_dark[windowstate], + &clwindowstyle->inset_light[windowstate]); + } + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +/* Draw a normal (toggle)button. Not spinbuttons.*/ +void cl_draw_button(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0; + GdkGC *bg_gc = NULL; + gboolean is_active = FALSE; + CLRectangle r; + + /* Get the background color of the window we're on */ + bg_gc = cl_get_window_bg_gc(widget); + + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), + GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + if (state_type == GTK_STATE_ACTIVE) + is_active = TRUE; + + if (GTK_IS_TOGGLE_BUTTON(widget) && + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) && + state_type == GTK_STATE_PRELIGHT) + { + cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->shade[1], &clearlooks_style->shade[1]); + r.topleft = clearlooks_style->shade_gc[3]; + r.bottomright = clearlooks_style->shade_gc[1]; + + is_active = TRUE; + } + + if (!is_active) + r.fillgc = NULL; + + if (!GTK_IS_NOTEBOOK (widget->parent)) + { + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (style->xthickness > 2 && style->ythickness > 2) + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + } + + /* Draw "sunken" look when border thickness is more than 2 pixels.*/ + if (style->xthickness > 2 && style->ythickness > 2) + { + x++; + y++; + height-=2; + width-=2; + } + + /* Don't draw the normal gradient for normal buttons. */ + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + + if (!is_active) + { + int tmp_height = (float)height*0.25; + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+2,width-4,tmp_height, + &clearlooks_style->button_g1[state_type], + &clearlooks_style->button_g2[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2, y+2+tmp_height, width-4, height-3-tmp_height*2, + &clearlooks_style->button_g2[state_type], + &clearlooks_style->button_g3[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+height-tmp_height-1,width-4,tmp_height, + &clearlooks_style->button_g3[state_type], + &clearlooks_style->button_g4[state_type]); + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + } + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +/* Draw spinbuttons. */ +void cl_draw_spinbutton(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + CLRectangle r; + GdkRectangle new_area; + + int tl = CL_CORNER_NONE, tr = CL_CORNER_NONE, + bl = CL_CORNER_NONE, br = CL_CORNER_NONE; + + if (area == NULL) + { + new_area.x = x; + new_area.y = y; + new_area.width = width; + new_area.height = height; + area = &new_area; + } + + if (!strcmp (detail, "spinbutton")) /* draws the 'back' of the spinbutton */ + { + GdkGC *bg_gc = cl_get_window_bg_gc(widget); + + gdk_gc_set_clip_rectangle (bg_gc, area); + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + gdk_gc_set_clip_rectangle (bg_gc, NULL); + + if (style->xthickness > 2 && style->ythickness > 2) + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + + return; + } + + if (!strcmp (detail, "spinbutton_up")) + { + tr = CL_CORNER_ROUND; + + (style->xthickness > 2 && style->ythickness > 2) ? y++ : height++; + } + + if (!strcmp (detail, "spinbutton_down")) + { + br = CL_CORNER_ROUND; + + if (style->xthickness > 2 && style->ythickness > 2) + height--; + } + + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), + GTK_WIDGET_HAS_FOCUS (widget), + tl, tr, + bl, br); + width--; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +void cl_draw_combobox_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + CLRectangle r; + + gboolean rtl = get_direction (widget->parent) == GTK_TEXT_DIR_RTL; + gboolean has_focus = GTK_WIDGET_HAS_FOCUS (widget); + + int cl = rtl ? CL_CORNER_NONE : CL_CORNER_ROUND, + cr = rtl ? CL_CORNER_ROUND : CL_CORNER_NONE; + + GdkGC *bg_gc = cl_get_window_bg_gc(widget); + + if (rtl) + { + if (!has_focus) + { + x -= 1; + width +=1; + } + } + else + { + width += 2; + if (has_focus) width--; /* this gives us a 2px focus line at the right side. */ + } + + cl_rectangle_set_entry (&r, style, state_type, + cl, cr, cl, cr, + has_focus); + + gdk_gc_set_clip_rectangle (bg_gc, area); + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + gdk_gc_set_clip_rectangle (bg_gc, NULL); + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (style->xthickness > 2 && style->ythickness > 2) + { + cl_draw_inset (style, window, widget, area, x, y, width, height, + cl, cr, cl, cr); + + y++; + x++; + width-=2; + height-=2; + } + + cl_rectangle_set_clip_rectangle (&r, area); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + cl_rectangle_reset_clip_rectangle (&r); +} + +void cl_draw_combobox_button (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + gboolean is_active = FALSE; + gboolean draw_inset = FALSE; + CLRectangle r; + + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), + GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + + if (state_type == GTK_STATE_ACTIVE) + is_active = TRUE; + else + r.fillgc = NULL; + + /* Seriously, why can't non-gtk-apps at least try to be decent citizens? + Take this fscking OpenOffice.org 1.9 for example. The morons responsible + for this utter piece of crap give the clip size wrong values! :'( */ + + if (area) + { + area->x = x; + area->y = y; + area->width = width; + area->height = height; + } + + x--; + width++; + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (GTK_IS_COMBO(widget->parent)) + draw_inset = (widget->parent->style->xthickness > 2 && + widget->parent->style->ythickness > 2); + else + draw_inset = (style->xthickness > 2 && style->ythickness > 2); + + if (draw_inset) + { + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + + x++; + y++; + height-=2; + width-=2; + } + else + { + x++; + width--; + } + + if (area) + cl_rectangle_set_clip_rectangle (&r, area); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + if (!is_active) + { + int tmp_height = (float)height*0.25; + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+2,width-4,tmp_height, + &clearlooks_style->button_g1[state_type], + &clearlooks_style->button_g2[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2, y+2+tmp_height, width-4, height-3-tmp_height*2, + &clearlooks_style->button_g2[state_type], + &clearlooks_style->button_g3[state_type]); + + draw_hgradient (window, style->bg_gc[state_type], style, + x+2,y+height-tmp_height-1,width-4,tmp_height, + &clearlooks_style->button_g3[state_type], + &clearlooks_style->button_g4[state_type]); + + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + } + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + if (area) + cl_rectangle_reset_clip_rectangle (&r); +} + +/* Draw text Entry */ +void cl_draw_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + CLRectangle r; + gboolean has_focus = GTK_WIDGET_HAS_FOCUS(widget); + GdkGC *bg_gc = cl_get_window_bg_gc(widget); + + gdk_draw_rectangle (window, bg_gc, FALSE, x, y, width-1, height-1); + + gtk_style_apply_default_background (style, window, TRUE, state_type, + area, x+1, y+1, width-2, height-2); + + + cl_rectangle_set_entry (&r, style, state_type, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND, + has_focus); + + /* Draw "sunken" look when border thickness is more than 2 pixels. */ + if (style->xthickness > 2 && style->ythickness > 2) + { + cl_draw_inset (style, window, widget, area, x, y, width, height, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + x++; + y++; + width-=2; + height-=2; + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); +} + +void cl_draw_optionmenu(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, GtkWidget *widget, + const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE(style); + GtkRequisition indicator_size; + GtkBorder indicator_spacing; + int line_pos; + + option_menu_get_props (widget, &indicator_size, &indicator_spacing); + + if (get_direction (widget) == GTK_TEXT_DIR_RTL) + line_pos = x + (indicator_size.width + indicator_spacing.left + indicator_spacing.right) + style->xthickness; + else + line_pos = x + width - (indicator_size.width + indicator_spacing.left + indicator_spacing.right) - style->xthickness; + + cl_draw_button (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height); + + gdk_draw_line (window, clearlooks_style->shade_gc[3], + line_pos, y + style->ythickness - 1, line_pos, + y + height - style->ythickness); + + gdk_draw_line (window, style->light_gc[state_type], + line_pos+1, y + style->ythickness - 1, line_pos+1, + y + height - style->ythickness); +} + + +void cl_draw_menuitem_button (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = (ClearlooksStyle*)style; + gboolean menubar = (widget->parent && GTK_IS_MENU_BAR(widget->parent)) ? TRUE : FALSE; + int corner = CL_CORNER_NARROW; + GdkColor lower_color; + + shade (&style->base[GTK_STATE_SELECTED], &lower_color, 0.85); + + if (menubar) + { + height++; + corner = CL_CORNER_NONE; + r->bordergc = clearlooks_style->border_gc[CL_BORDER_UPPER]; + } + else + { + r->bordergc = clearlooks_style->spot3_gc; + } + + cl_rectangle_set_corners (r, corner, corner, corner, corner); + + cl_rectangle_set_gradient (&r->fill_gradient, + &style->base[GTK_STATE_SELECTED], &lower_color); + + r->gradient_type = CL_GRADIENT_VERTICAL; + + r->fillgc = clearlooks_style->spot2_gc; + r->topleft = clearlooks_style->spot1_gc; + + cl_rectangle_set_clip_rectangle (r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, r); + cl_draw_shadow (window, widget, style, x, y, width, height, r); + cl_rectangle_reset_clip_rectangle (r); +} + +void cl_draw_menuitem_flat (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = (ClearlooksStyle*)style; + gboolean menubar = (widget->parent && GTK_IS_MENU_BAR(widget->parent)) ? TRUE : FALSE; + GdkColor tmp; + + cl_rectangle_set_corners (r, CL_CORNER_NARROW, CL_CORNER_NARROW, + CL_CORNER_NARROW, CL_CORNER_NARROW); + + tmp = cl_gc_set_fg_color_shade (style->black_gc, style->colormap, + &style->base[GTK_STATE_PRELIGHT], 0.8); + + r->bordergc = style->black_gc; + r->fillgc = style->base_gc[GTK_STATE_PRELIGHT]; + + if (menubar) height++; + + cl_rectangle_set_clip_rectangle (r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, r); + cl_rectangle_reset_clip_rectangle (r); + + gdk_gc_set_foreground (style->black_gc, &tmp); +} + +void cl_draw_menuitem_gradient (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int width, int height, CLRectangle *r) +{ + ClearlooksStyle *clearlooks_style = (ClearlooksStyle*)style; + gboolean menubar = (widget->parent && GTK_IS_MENU_BAR(widget->parent)) ? TRUE : FALSE; + GdkColor tmp; + GdkColor lower_color; + + shade (&style->base[GTK_STATE_SELECTED], &lower_color, 0.8); + + cl_rectangle_set_corners (r, CL_CORNER_NARROW, CL_CORNER_NARROW, + CL_CORNER_NARROW, CL_CORNER_NARROW); + + cl_rectangle_set_gradient (&r->fill_gradient, + &style->base[GTK_STATE_SELECTED], &lower_color); + + r->gradient_type = CL_GRADIENT_VERTICAL; + + tmp = cl_gc_set_fg_color_shade (style->black_gc, style->colormap, + &style->base[GTK_STATE_PRELIGHT], 0.8); + + r->bordergc = style->black_gc; + r->fillgc = style->base_gc[GTK_STATE_PRELIGHT]; + + if (menubar) height++; + + cl_rectangle_set_clip_rectangle (r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, r); + cl_rectangle_reset_clip_rectangle (r); + + gdk_gc_set_foreground (style->black_gc, &tmp); +} + +void cl_draw_treeview_header (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint columns = 0, column_index = -1, fill_width = width; + gboolean is_etree = strcmp("ETree", G_OBJECT_TYPE_NAME(widget->parent)) == 0; + gboolean resizable = TRUE; + + GdkGC *bottom = clearlooks_style->shade_gc[5]; + + if ( width < 2 || height < 2 ) + return; + + if (GTK_IS_TREE_VIEW (widget->parent)) + { + gtk_treeview_get_header_index (GTK_TREE_VIEW(widget->parent), + widget, &column_index, &columns, + &resizable); + } + else if (GTK_IS_CLIST (widget->parent)) + { + gtk_clist_get_header_index (GTK_CLIST(widget->parent), + widget, &column_index, &columns); + } + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[4], area); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[5], area); + } + + if (state_type != GTK_STATE_NORMAL) + fill_width-=2; + + gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE, x, y, fill_width, height-(height/3)+1); + + draw_hgradient (window, style->bg_gc[state_type], style, + x, 1+y+height-(height/3), fill_width, height/3, + &style->bg[state_type], &clearlooks_style->inset_dark[state_type]); + + if (resizable || (column_index != columns-1)) + { + gdk_draw_line (window, clearlooks_style->shade_gc[4], x+width-2, y+4, x+width-2, y+height-5); + gdk_draw_line (window, clearlooks_style->shade_gc[0], x+width-1, y+4, x+width-1, y+height-5); + } + + /* left light line */ + if (column_index == 0) + gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y+1, x, y+height-2); + + /* top light line */ + gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y, x+width-1, y); + + /* bottom dark line */ + if (state_type == GTK_STATE_INSENSITIVE) + bottom = clearlooks_style->shade_gc[3]; + + + gdk_draw_line (window, bottom, x, y+height-1, x+width-1, y+height-1); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[4], NULL); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[5], NULL); + } +} diff --git a/libs/clearlooks-older/clearlooks_draw.h b/libs/clearlooks-older/clearlooks_draw.h new file mode 100644 index 0000000000..a8cbb3732f --- /dev/null +++ b/libs/clearlooks-older/clearlooks_draw.h @@ -0,0 +1,159 @@ +#ifndef CLEARLOOKS_DRAW_H +#define CLEARLOOKS_DRAW_H + +#include <gtk/gtk.h> +#include <gdk/gdk.h> + +typedef struct +{ + GdkColor *from; + GdkColor *to; +} CLGradient; + +typedef enum +{ + CL_GRADIENT_NONE, + CL_GRADIENT_HORIZONTAL, + CL_GRADIENT_VERTICAL +} CLGradientType; + +typedef struct +{ + CLGradient fill_gradient; + CLGradient border_gradient; + + CLGradientType gradient_type; + + GdkGC *bordergc; + GdkGC *fillgc; + + guint8 corners[4]; + + GdkGC *topleft; /* top + left shadow */ + GdkGC *bottomright; /* bottom + right shadow */ + + GdkColor tmp_color; /* used for gradient */ +} CLRectangle; + +typedef enum /* DON'T CHANGE THE ORDER! */ +{ + CL_CORNER_TOPRIGHT, + CL_CORNER_BOTTOMRIGHT, + CL_CORNER_BOTTOMLEFT, + CL_CORNER_TOPLEFT +} CLCornerSide; + +typedef enum /* DON'T CHANGE THE ORDER! */ +{ + CL_BORDER_TOP, + CL_BORDER_RIGHT, + CL_BORDER_BOTTOM, + CL_BORDER_LEFT +} CLBorderType; + +typedef enum +{ + CL_CORNER_NONE = 0, + CL_CORNER_NARROW = 1, + CL_CORNER_ROUND = 2 +} CLCornerSharpness; + + + +CLRectangle *cl_rectangle_new(GdkGC *fillgc, GdkGC *bordergc, + int tl, int tr, int bl, int br); + +void cl_draw_rectangle (GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +void cl_rectangle_set_color (CLGradient *g, GdkColor *color); +void cl_rectangle_set_gradient (CLGradient *g, GdkColor *from, GdkColor *to); + +void cl_rectangle_set_button (CLRectangle *r, GtkStyle *style, + GtkStateType state_type, gboolean hasdefault, gboolean has_focus, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br); + +void cl_rectangle_set_entry (CLRectangle *r, GtkStyle *style, + GtkStateType state_type, + CLBorderType tl, CLBorderType tr, + CLBorderType bl, CLBorderType br, + gboolean has_focus); + +void cl_draw_shadow(GdkWindow *window, GtkWidget *widget, GtkStyle *style, + int x, int y, int width, int height, CLRectangle *r); + +void cl_rectangle_set_clip_rectangle (CLRectangle *r, GdkRectangle *area); +void cl_rectangle_reset_clip_rectangle (CLRectangle *r); + +void cl_set_corner_sharpness (const gchar *detail, GtkWidget *widget, CLRectangle *r); + + +void cl_rectangle_set_corners (CLRectangle *r, int tl, int tr, int bl, int br); + +void cl_rectangle_init (CLRectangle *r, GdkGC *fillgc, GdkGC *bordergc, + int tl, int tr, int bl, int br); + +void cl_rectangle_reset (CLRectangle *r, GtkStyle *style); + + +GdkPixmap* cl_progressbar_tile_new (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, gint height, gint offset); + +void cl_progressbar_fill (GdkDrawable *drawable, GtkWidget *widget, + GtkStyle *style, GdkGC *gc, + gint x, gint y, gint width, gint height, + guint8 offset, GdkRectangle *area); + +GdkColor cl_gc_set_fg_color_shade (GdkGC *gc, GdkColormap *colormap, + GdkColor *from, gfloat s); + +void cl_draw_spinbutton(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_button(GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_combobox_entry (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_combobox_button (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +void cl_draw_menuitem_button (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int wiidth, int height, CLRectangle *r); + +void cl_draw_menuitem_flat (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int wiidth, int height, CLRectangle *r); + +void cl_draw_menuitem_gradient (GdkDrawable *window, GtkWidget *widget, GtkStyle *style, + GdkRectangle *area, GtkStateType state_type, + int x, int y, int wiidth, int height, CLRectangle *r); + +void cl_draw_treeview_header (GtkStyle *style, GdkWindow *window, + GtkStateType state_type, GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, const gchar *detail, + gint x, gint y, gint width, gint height); + +#endif /* CLEARLOOKS_DRAW_H */ diff --git a/libs/clearlooks-older/clearlooks_rc_style.c b/libs/clearlooks-older/clearlooks_rc_style.c new file mode 100644 index 0000000000..1c5f2c495e --- /dev/null +++ b/libs/clearlooks-older/clearlooks_rc_style.c @@ -0,0 +1,392 @@ +/* Clearlooks theme engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor <otaylor@redhat.com> + * and by Alexander Larsson <alexl@redhat.com> + * Modified by Richard Stellingwerff <remenic@gmail.com> + */ + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" + +static void clearlooks_rc_style_init (ClearlooksRcStyle *style); +static void clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass); +static GtkStyle *clearlooks_rc_style_create_style (GtkRcStyle *rc_style); +static guint clearlooks_rc_style_parse (GtkRcStyle *rc_style, + GtkSettings *settings, + GScanner *scanner); +static void clearlooks_rc_style_merge (GtkRcStyle *dest, + GtkRcStyle *src); + + +static GtkRcStyleClass *parent_class; + +GType clearlooks_type_rc_style = 0; + +enum +{ + TOKEN_SPOTCOLOR = G_TOKEN_LAST + 1, + TOKEN_CONTRAST, + TOKEN_SUNKENMENU, + TOKEN_PROGRESSBARSTYLE, + TOKEN_MENUBARSTYLE, + TOKEN_MENUITEMSTYLE, + TOKEN_LISTVIEWITEMSTYLE +}; + +static struct + { + const gchar *name; + guint token; + } +theme_symbols[] = +{ + { "spotcolor", TOKEN_SPOTCOLOR }, + { "contrast", TOKEN_CONTRAST }, + { "sunkenmenubar", TOKEN_SUNKENMENU }, + { "progressbarstyle", TOKEN_PROGRESSBARSTYLE }, + { "menubarstyle", TOKEN_MENUBARSTYLE }, + { "menuitemstyle", TOKEN_MENUITEMSTYLE }, + { "listviewitemstyle", TOKEN_LISTVIEWITEMSTYLE } +}; + + +void +clearlooks_rc_style_register_type (GTypeModule *module) +{ + static const GTypeInfo object_info = + { + sizeof (ClearlooksRcStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_rc_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksRcStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_rc_style_init, + NULL + }; + + clearlooks_type_rc_style = g_type_module_register_type (module, + GTK_TYPE_RC_STYLE, + "ClearlooksRcStyle", + &object_info, 0); +} + +static void +clearlooks_rc_style_init (ClearlooksRcStyle *clearlooks_rc) +{ + clearlooks_rc->has_spot_color = FALSE; + clearlooks_rc->contrast = 1.0; + clearlooks_rc->sunkenmenubar = 1; + clearlooks_rc->progressbarstyle = 0; + clearlooks_rc->menubarstyle = 0; + clearlooks_rc->menuitemstyle = 1; + clearlooks_rc->listviewitemstyle = 1; +} + +static void +clearlooks_rc_style_class_init (ClearlooksRcStyleClass *klass) +{ + GtkRcStyleClass *rc_style_class = GTK_RC_STYLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + rc_style_class->parse = clearlooks_rc_style_parse; + rc_style_class->create_style = clearlooks_rc_style_create_style; + rc_style_class->merge = clearlooks_rc_style_merge; +} + +static guint +theme_parse_color(GtkSettings *settings, + GScanner *scanner, + GdkColor *color) +{ + guint token; + + /* Skip 'blah_color' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + return gtk_rc_parse_color (scanner, color); +} + +static guint +theme_parse_contrast(GtkSettings *settings, + GScanner *scanner, + double *contrast) +{ + guint token; + + /* Skip 'contrast' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_FLOAT) + return G_TOKEN_FLOAT; + + *contrast = scanner->value.v_float; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_sunkenmenubar(GtkSettings *settings, + GScanner *scanner, + guint8 *sunken) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *sunken = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_progressbarstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *progressbarstyle) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *progressbarstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_menubarstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *menubarstyle) +{ + guint token; + + /* Skip 'menubarstyle' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *menubarstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_menuitemstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *menuitemstyle) +{ + guint token; + + /* Skip 'sunkenmenubar' */ + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *menuitemstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +theme_parse_listviewitemstyle(GtkSettings *settings, + GScanner *scanner, + guint8 *listviewitemstyle) +{ + guint token; + + token = g_scanner_get_next_token(scanner); + + token = g_scanner_get_next_token(scanner); + + if (token != G_TOKEN_EQUAL_SIGN) + return G_TOKEN_EQUAL_SIGN; + + token = g_scanner_get_next_token(scanner); + if (token != G_TOKEN_INT) + return G_TOKEN_INT; + + *listviewitemstyle = scanner->value.v_int; + + return G_TOKEN_NONE; +} + +static guint +clearlooks_rc_style_parse (GtkRcStyle *rc_style, + GtkSettings *settings, + GScanner *scanner) + +{ + static GQuark scope_id = 0; + ClearlooksRcStyle *clearlooks_style = CLEARLOOKS_RC_STYLE (rc_style); + + guint old_scope; + guint token; + guint i; + + /* Set up a new scope in this scanner. */ + + if (!scope_id) + scope_id = g_quark_from_string("clearlooks_theme_engine"); + + /* If we bail out due to errors, we *don't* reset the scope, so the + * error messaging code can make sense of our tokens. + */ + old_scope = g_scanner_set_scope(scanner, scope_id); + + /* Now check if we already added our symbols to this scope + * (in some previous call to clearlooks_rc_style_parse for the + * same scanner. + */ + + if (!g_scanner_lookup_symbol(scanner, theme_symbols[0].name)) + { + g_scanner_freeze_symbol_table(scanner); + for (i = 0; i < G_N_ELEMENTS (theme_symbols); i++) + g_scanner_scope_add_symbol(scanner, scope_id, + theme_symbols[i].name, + GINT_TO_POINTER(theme_symbols[i].token)); + g_scanner_thaw_symbol_table(scanner); + } + + /* We're ready to go, now parse the top level */ + + token = g_scanner_peek_next_token(scanner); + while (token != G_TOKEN_RIGHT_CURLY) + { + switch (token) + { + case TOKEN_SPOTCOLOR: + token = theme_parse_color(settings, scanner, &clearlooks_style->spot_color); + clearlooks_style->has_spot_color = TRUE; + break; + case TOKEN_CONTRAST: + token = theme_parse_contrast(settings, scanner, &clearlooks_style->contrast); + break; + case TOKEN_SUNKENMENU: + token = theme_parse_sunkenmenubar(settings, scanner, &clearlooks_style->sunkenmenubar); + break; + case TOKEN_PROGRESSBARSTYLE: + token = theme_parse_progressbarstyle(settings, scanner, &clearlooks_style->progressbarstyle); + break; + case TOKEN_MENUBARSTYLE: + token = theme_parse_menubarstyle(settings, scanner, &clearlooks_style->menubarstyle); + break; + case TOKEN_MENUITEMSTYLE: + token = theme_parse_menuitemstyle(settings, scanner, &clearlooks_style->menuitemstyle); + break; + case TOKEN_LISTVIEWITEMSTYLE: + token = theme_parse_listviewitemstyle(settings, scanner, &clearlooks_style->listviewitemstyle); + break; + default: + g_scanner_get_next_token(scanner); + token = G_TOKEN_RIGHT_CURLY; + break; + } + + if (token != G_TOKEN_NONE) + return token; + + token = g_scanner_peek_next_token(scanner); + } + + g_scanner_get_next_token(scanner); + + g_scanner_set_scope(scanner, old_scope); + + return G_TOKEN_NONE; +} + +static void +clearlooks_rc_style_merge (GtkRcStyle *dest, + GtkRcStyle *src) +{ + ClearlooksRcStyle *dest_w, *src_w; + + parent_class->merge (dest, src); + + if (!CLEARLOOKS_IS_RC_STYLE (src)) + return; + + src_w = CLEARLOOKS_RC_STYLE (src); + dest_w = CLEARLOOKS_RC_STYLE (dest); + + dest_w->contrast = src_w->contrast; + dest_w->sunkenmenubar = src_w->sunkenmenubar; + dest_w->progressbarstyle = src_w->progressbarstyle; + dest_w->menubarstyle = src_w->menubarstyle; + dest_w->menuitemstyle = src_w->menuitemstyle; + dest_w->listviewitemstyle = src_w->listviewitemstyle; + + if (src_w->has_spot_color) + { + dest_w->has_spot_color = TRUE; + dest_w->spot_color = src_w->spot_color; + } +} + + +/* Create an empty style suitable to this RC style + */ +static GtkStyle * +clearlooks_rc_style_create_style (GtkRcStyle *rc_style) +{ + return GTK_STYLE (g_object_new (CLEARLOOKS_TYPE_STYLE, NULL)); +} diff --git a/libs/clearlooks-older/clearlooks_rc_style.h b/libs/clearlooks-older/clearlooks_rc_style.h new file mode 100644 index 0000000000..bd8e0ca05d --- /dev/null +++ b/libs/clearlooks-older/clearlooks_rc_style.h @@ -0,0 +1,57 @@ +/* Clearlooks Theme Engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor <otaylor@redhat.com> + * and by Alexander Larsson <alexl@redhat.com> + * Modified by Richard Stellingwerff <remenic@gmail.com> + */ + +#include <gtk/gtkrc.h> + +typedef struct _ClearlooksRcStyle ClearlooksRcStyle; +typedef struct _ClearlooksRcStyleClass ClearlooksRcStyleClass; + +extern GType clearlooks_type_rc_style; + +#define CLEARLOOKS_TYPE_RC_STYLE clearlooks_type_rc_style +#define CLEARLOOKS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyle)) +#define CLEARLOOKS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) +#define CLEARLOOKS_IS_RC_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_RC_STYLE)) +#define CLEARLOOKS_IS_RC_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLEARLOOKS_TYPE_RC_STYLE)) +#define CLEARLOOKS_RC_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLEARLOOKS_TYPE_RC_STYLE, ClearlooksRcStyleClass)) + +struct _ClearlooksRcStyle +{ + GtkRcStyle parent_instance; + + GdkColor spot_color; + gboolean has_spot_color; + double contrast; + guint8 sunkenmenubar; + guint8 progressbarstyle; + guint8 menubarstyle; + guint8 menuitemstyle; + guint8 listviewitemstyle; +}; + +struct _ClearlooksRcStyleClass +{ + GtkRcStyleClass parent_class; +}; + +void clearlooks_rc_style_register_type (GTypeModule *module); diff --git a/libs/clearlooks-older/clearlooks_style.c b/libs/clearlooks-older/clearlooks_style.c new file mode 100644 index 0000000000..074f1604b1 --- /dev/null +++ b/libs/clearlooks-older/clearlooks_style.c @@ -0,0 +1,2661 @@ +#include <gtk/gtk.h> + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" +#include "clearlooks_draw.h" + +#include <math.h> +#include <string.h> + +#include "bits.c" +#include "support.h" +//#include "config.h" + +/* #define DEBUG 1 */ + +#define SCALE_SIZE 5 + +#define DETAIL(xx) ((detail) && (!strcmp(xx, detail))) +#define COMPARE_COLORS(a,b) (a.red == b.red && a.green == b.green && a.blue == b.blue) + +#define DRAW_ARGS GtkStyle *style, \ + GdkWindow *window, \ + GtkStateType state_type, \ + GtkShadowType shadow_type, \ + GdkRectangle *area, \ + GtkWidget *widget, \ + const gchar *detail, \ + gint x, \ + gint y, \ + gint width, \ + gint height + +static GdkGC *realize_color (GtkStyle * style, GdkColor * color); +static GtkStyleClass *parent_class; +static GList *progressbars = NULL; +static gint8 pboffset = 10; +static int timer_id = 0; + +static void cl_progressbar_remove (gpointer data) +{ + if (g_list_find (progressbars, data) == NULL) + return; + + progressbars = g_list_remove (progressbars, data); + g_object_unref (data); + + if (g_list_first(progressbars) == NULL) { + g_source_remove(timer_id); + timer_id = 0; + } +} + +static void update_progressbar (gpointer data, gpointer user_data) +{ + gfloat fraction; + + if (data == NULL) + return; + + fraction = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (data)); + + /* update only if not filled */ + if (fraction < 1.0) + gtk_widget_queue_resize ((GtkWidget*)data); + + if (fraction >= 1.0 || GTK_PROGRESS (data)->activity_mode) + cl_progressbar_remove (data); +} + +static gboolean timer_func (gpointer data) +{ + g_list_foreach (progressbars, update_progressbar, NULL); + if (--pboffset < 0) pboffset = 9; + return (g_list_first(progressbars) != NULL); +} + +static gboolean cl_progressbar_known(gconstpointer data) +{ + return (g_list_find (progressbars, data) != NULL); +} + + +static void cl_progressbar_add (gpointer data) +{ + if (!GTK_IS_PROGRESS_BAR (data)) + return; + + progressbars = g_list_append (progressbars, data); + + g_object_ref (data); + g_signal_connect ((GObject*)data, "unrealize", G_CALLBACK (cl_progressbar_remove), data); + + if (timer_id == 0) + timer_id = g_timeout_add (100, timer_func, NULL); +} + +static GdkColor * +clearlooks_get_spot_color (ClearlooksRcStyle *clearlooks_rc) +{ + GtkRcStyle *rc = GTK_RC_STYLE (clearlooks_rc); + + if (clearlooks_rc->has_spot_color) + return &clearlooks_rc->spot_color; + else + return &rc->base[GTK_STATE_SELECTED]; +} + +/**************************************************************************/ + +/* used for optionmenus... */ +static void +draw_tab (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GtkShadowType shadow_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height) +{ +#define ARROW_SPACE 2 +#define ARROW_LINE_HEIGHT 2 +#define ARROW_LINE_WIDTH 5 + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GtkRequisition indicator_size; + GtkBorder indicator_spacing; + gint arrow_height; + + option_menu_get_props (widget, &indicator_size, &indicator_spacing); + + indicator_size.width += (indicator_size.width % 2) - 1; + arrow_height = indicator_size.width / 2 + 2; + + x += (width - indicator_size.width) / 2; + y += height/2; + + if (state_type == GTK_STATE_INSENSITIVE) + { + draw_arrow (window, style->light_gc[state_type], area, + GTK_ARROW_UP, 1+x, 1+y-arrow_height, + indicator_size.width, arrow_height); + + draw_arrow (window, style->light_gc[state_type], area, + GTK_ARROW_DOWN, 1+x, 1+y+1, + indicator_size.width, arrow_height); + } + + draw_arrow (window, style->fg_gc[state_type], area, + GTK_ARROW_UP, x, y-arrow_height, + indicator_size.width, arrow_height); + + draw_arrow (window, style->fg_gc[state_type], area, + GTK_ARROW_DOWN, x, y+1, + indicator_size.width, arrow_height); +} + +static void +clearlooks_draw_arrow (GtkStyle *style, + GdkWindow *window, + GtkStateType state, + GtkShadowType shadow, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GtkArrowType arrow_type, + gboolean fill, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint original_width, original_x; + GdkGC *gc; + + sanitize_size (window, &width, &height); + + if (is_combo_box (widget)) + { + width = 7; + height = 5; + x+=2; + y+=4; + if (state == GTK_STATE_INSENSITIVE) + { + draw_arrow (window, style->light_gc[state], area, + GTK_ARROW_UP, 1+x, 1+y-height, + width, height); + + draw_arrow (window, style->light_gc[state], area, + GTK_ARROW_DOWN, 1+x, 1+y+1, + width, height); + } + + draw_arrow (window, style->fg_gc[state], area, + GTK_ARROW_UP, x, y-height, + width, height); + + draw_arrow (window, style->fg_gc[state], area, + GTK_ARROW_DOWN, x, y+1, + width, height); + + return; + } + + original_width = width; + original_x = x; + + /* Make spinbutton arrows and arrows in menus + * slightly larger to get the right pixels drawn */ + if (DETAIL ("spinbutton")) + height += 1; + + if (DETAIL("menuitem")) + { + width = 6; + height = 7; + } + + /* Compensate arrow position for "sunken" look */ + if (DETAIL ("spinbutton") && arrow_type == GTK_ARROW_DOWN && + style->xthickness > 2 && style->ythickness > 2) + y -= 1; + + if (widget && widget->parent && GTK_IS_COMBO (widget->parent->parent)) + { + width -= 2; + height -=2; + x++; + } + + calculate_arrow_geometry (arrow_type, &x, &y, &width, &height); + + if (DETAIL ("menuitem")) + x = original_x + original_width - width; + + if (DETAIL ("spinbutton") && (arrow_type == GTK_ARROW_DOWN)) + y += 1; + + if (state == GTK_STATE_INSENSITIVE) + draw_arrow (window, style->light_gc[state], area, arrow_type, x + 1, y + 1, width, height); + + gc = style->fg_gc[state]; + + draw_arrow (window, gc, area, arrow_type, x, y, width, height); +} + + +static void +draw_flat_box (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + if (detail && + clearlooks_style->listviewitemstyle == 1 && + state_type == GTK_STATE_SELECTED && ( + !strncmp ("cell_even", detail, strlen ("cell_even")) || + !strncmp ("cell_odd", detail, strlen ("cell_odd")))) + { + GdkGC *gc; + GdkColor lower_color; + GdkColor *upper_color; + + if (GTK_WIDGET_HAS_FOCUS (widget)) + { + gc = style->base_gc[state_type]; + upper_color = &style->base[state_type]; + } + else + { + gc = style->base_gc[GTK_STATE_ACTIVE]; + upper_color = &style->base[GTK_STATE_ACTIVE]; + } + + if (GTK_IS_TREE_VIEW (widget) && 0) + { + GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); + + if (gtk_tree_selection_count_selected_rows (sel) > 1) + { + parent_class->draw_flat_box (style, window, state_type, shadow_type, + area, widget, detail, + x, y, width, height); + return; + } + } + + shade (upper_color, &lower_color, 0.8); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + draw_hgradient (window, gc, style, + x, y, width, height, upper_color, &lower_color); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); + } + else + { + parent_class->draw_flat_box (style, window, state_type, + shadow_type, + area, widget, detail, + x, y, width, height); + } +} +/**************************************************************************/ + +static void +draw_shadow (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + + GdkGC *outer_gc = clearlooks_style->shade_gc[4]; + GdkGC *gc1 = NULL; + GdkGC *gc2 = NULL; + gint thickness_light; + gint thickness_dark; + gboolean interior_focus = FALSE; + +#if DEBUG + printf("draw_shadow: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + if (widget == NULL) + { + gdk_draw_rectangle (window, outer_gc, FALSE, + x, y, width - 1, height - 1); + return; + } + + if ((width == -1) && (height == -1)) + gdk_window_get_size (window, &width, &height); + else if (width == -1) + gdk_window_get_size (window, &width, NULL); + else if (height == -1) + gdk_window_get_size (window, NULL, &height); + + cl_rectangle_reset (&r, style); + + if (DETAIL ("frame") && widget->parent && + GTK_IS_STATUSBAR (widget->parent)) + { + gtk_style_apply_default_background (style, window,widget && !GTK_WIDGET_NO_WINDOW (widget), + state_type, area, x, y, width, height); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + } + + gdk_draw_line (window, clearlooks_style->shade_gc[3], + x, y, x + width, y); + gdk_draw_line (window, clearlooks_style->shade_gc[0], + x, y + 1, x + width, y + 1); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + } + } + else if (detail && !strcmp (detail, "entry")) + { + if ( widget->parent && (GTK_IS_COMBO_BOX_ENTRY (widget->parent) || + GTK_IS_SPIN_BUTTON(widget) || + GTK_IS_COMBO (widget->parent))) + { + cl_draw_combobox_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height); + } + else + { + cl_draw_entry (style, window, GTK_WIDGET_STATE(widget), shadow_type, area, widget, detail, x, y, width, height); + } + } + else if (DETAIL ("viewport") || DETAIL ("scrolled_window")) + { + gdk_draw_rectangle (window, clearlooks_style->shade_gc[4], FALSE, + x, y, width - 1, height - 1); + } + else + { + if (DETAIL ("menuitem")) + outer_gc = clearlooks_style->spot3_gc; + else + outer_gc = clearlooks_style->shade_gc[4]; + + if (shadow_type == GTK_SHADOW_IN) + gdk_draw_rectangle (window, outer_gc, FALSE, + x, y, width - 1, height - 1); + else if (shadow_type == GTK_SHADOW_OUT) + { + gdk_draw_rectangle (window, outer_gc, FALSE, + x, y, width - 1, height - 1); + gdk_draw_line (window, style->light_gc[state_type], + x+1, y+1, x+width-2, y+1); + gdk_draw_line (window, style->light_gc[state_type], + x+1, y+1, x+1, y+height-2); + } + else if (shadow_type == GTK_SHADOW_ETCHED_IN) + { + GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3]; + GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0]; + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = a; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + + r.bordergc = b; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (shadow_type == GTK_SHADOW_ETCHED_IN) + { + GdkGC *a = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 3 : 0]; + GdkGC *b = clearlooks_style->shade_gc[(shadow_type == GTK_SHADOW_ETCHED_IN) ? 0 : 3]; + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = a; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + + r.bordergc = b; + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else + parent_class->draw_shadow (style, window, state_type, shadow_type, + area, widget, detail, + x, y, width, height); + } +} + +#define GDK_RECTANGLE_SET(rect,a,b,c,d) rect.x = a; \ + rect.y = b; \ + rect.width = c; \ + rect.height = d; + + +static void +draw_box_gap (DRAW_ARGS, + GtkPositionType gap_side, + gint gap_x, + gint gap_width) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + + GdkRegion *area_region = NULL, + *gap_region = NULL; + GdkRectangle light_rect; + GdkRectangle dark_rect; + +#if DEBUG + printf("draw_box_gap: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + cl_rectangle_reset (&r, style); + + r.bordergc = clearlooks_style->shade_gc[5]; + + r.topleft = style->light_gc[state_type]; + r.bottomright = clearlooks_style->shade_gc[1]; + + if (area) + area_region = gdk_region_rectangle (area); + else + { + GdkRectangle tmp = { x, y, width, height }; + area_region = gdk_region_rectangle (&tmp); + } + + switch (gap_side) + { + case GTK_POS_TOP: + { + GdkRectangle rect = { x+gap_x+1, y, gap_width-2, 2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y, x+gap_x+1, y+1); + GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y, x+gap_x+gap_width-2, y); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + break; + } + case GTK_POS_BOTTOM: + { + GdkRectangle rect = { x+gap_x+1, y+height-2, gap_width-2, 2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x+gap_x+1, y+height-2, x+gap_x+1, y+height-1); + GDK_RECTANGLE_SET (dark_rect, x+gap_x+gap_width-2, y+height-2, x+gap_x+gap_width-2, y+height-1); + + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_NONE); + + break; + } + case GTK_POS_LEFT: + { + GdkRectangle rect = { x, y+gap_x+1, 2, gap_width-2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x, y+gap_x+1, x+1, y+gap_x+1); + GDK_RECTANGLE_SET (dark_rect, x, y+gap_x+gap_width-2, x, y+gap_x+gap_width-2); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + break; + } + case GTK_POS_RIGHT: + { + GdkRectangle rect = { x+width-2, y+gap_x+1, 2, gap_width-2 }; + gap_region = gdk_region_rectangle (&rect); + + GDK_RECTANGLE_SET (light_rect, x+width-2, y+gap_x+1, x+width-1, y+gap_x+1); + GDK_RECTANGLE_SET (dark_rect, x+width-2, y+gap_x+gap_width-2, x+width-1, y+gap_x+gap_width-2); + + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_NONE); + break; + } + } + + gdk_region_subtract (area_region, gap_region); + + gdk_gc_set_clip_region (r.bordergc, area_region); + gdk_gc_set_clip_region (r.topleft, area_region); + gdk_gc_set_clip_region (r.bottomright, area_region); + + gdk_region_destroy (area_region); + gdk_region_destroy (gap_region); + + gdk_draw_rectangle (window, style->bg_gc[state_type], TRUE, x, y, width, height); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + gdk_gc_set_clip_region (r.bordergc, NULL); + gdk_gc_set_clip_region (r.topleft, NULL); + gdk_gc_set_clip_region (r.bottomright, NULL); + + /* it's a semi hack */ + gdk_draw_line (window, style->light_gc[state_type], + light_rect.x, light_rect.y, + light_rect.width, light_rect.height); + + gdk_draw_line (window, clearlooks_style->shade_gc[1], + dark_rect.x, dark_rect.y, + dark_rect.width, dark_rect.height); +} + +/**************************************************************************/ + +static void +draw_extension (DRAW_ARGS, GtkPositionType gap_side) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int my_state_type = (state_type == GTK_STATE_ACTIVE) ? 2 : 0; + CLRectangle r; + +#if DEBUG + printf("draw_extension: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + if (DETAIL ("tab")) + { + GdkRectangle new_area; + GdkColor tmp_color; + + cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE, + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + if (state_type == GTK_STATE_ACTIVE) + shade (&style->bg[state_type], &tmp_color, 1.08); + else + shade (&style->bg[state_type], &tmp_color, 1.05); + + if (area) + { + new_area = *area; + } + else + { + new_area.x = x; + new_area.y = y; + new_area.width = width; + new_area.height = height; + } + + switch (gap_side) + { + case GTK_POS_BOTTOM: + height+=2; + new_area.y = y; + new_area.height = height-2; + r.gradient_type = CL_GRADIENT_VERTICAL; + cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type], + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]); + break; + case GTK_POS_TOP: + y-=2; + height+=2; + new_area.y = y+2; + new_area.height = height; + r.gradient_type = CL_GRADIENT_VERTICAL; + cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type], + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]); + break; + case GTK_POS_LEFT: + x-=2; + width+=2; + new_area.x = x+2; + new_area.width = width; + r.gradient_type = CL_GRADIENT_HORIZONTAL; + cl_rectangle_set_gradient (&r.fill_gradient, &style->bg[state_type], &tmp_color); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type], + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type]); + break; + case GTK_POS_RIGHT: + width+=2; + new_area.x = x; + new_area.width = width-2; + r.gradient_type = CL_GRADIENT_HORIZONTAL; + cl_rectangle_set_gradient (&r.fill_gradient, &tmp_color, &style->bg[state_type]); + cl_rectangle_set_gradient (&r.border_gradient, + &clearlooks_style->border[CL_BORDER_UPPER+my_state_type], + &clearlooks_style->border[CL_BORDER_LOWER+my_state_type]); + break; + } + + r.topleft = style->light_gc[state_type]; + r.bottomright = (state_type == GTK_STATE_NORMAL) ? clearlooks_style->shade_gc[1] : NULL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + /* draw the selection stripe */ + if (state_type != GTK_STATE_ACTIVE) { + cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL); + r.fillgc = clearlooks_style->spot2_gc; + + switch (gap_side) + { + case GTK_POS_BOTTOM: + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_NONE); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2); + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y, width, 3, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + case GTK_POS_TOP: + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_ROUND); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3); + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y + height - 3, width, 3, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + case GTK_POS_LEFT: + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot2, &clearlooks_style->spot3); + r.gradient_type = CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x + width - 3, y, 3, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + case GTK_POS_RIGHT: + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_NONE); + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->spot3, &clearlooks_style->spot2); + r.gradient_type = CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_clip_rectangle (&r, &new_area); + cl_draw_rectangle (window, widget, style, x, y, 3, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + break; + } + } + + + } + else + { + parent_class->draw_extension (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height, + gap_side); + } +} + + +/**************************************************************************/ + +static void +draw_handle (DRAW_ARGS, GtkOrientation orientation) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint xx, yy; + gint xthick, ythick; + GdkGC *light_gc, *dark_gc; + GdkRectangle rect; + GdkRectangle dest; + gint intersect; + gint h; + int i; + int n_lines; + int offset; + +#if DEBUG + printf("draw_handle: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + if (state_type == GTK_STATE_PRELIGHT) + gtk_style_apply_default_background (style, window, + widget && !GTK_WIDGET_NO_WINDOW (widget), + state_type, area, x, y, width, height); + + /* orientation is totally bugged, but this actually works... */ + orientation = (width > height) ? GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; + + if (!strcmp (detail, "paned")) + { + /* we want to ignore the shadow border in paned widgets */ + xthick = 0; + ythick = 0; + } + else + { + xthick = style->xthickness; + ythick = style->ythickness; + } + + if ( ((DETAIL ("handlebox") && widget && GTK_IS_HANDLE_BOX (widget)) || DETAIL ("dockitem")) && + orientation == GTK_ORIENTATION_VERTICAL ) + { + /* The line in the toolbar */ + + light_gc = style->light_gc[state_type]; + dark_gc = clearlooks_style->shade_gc[3]; + + if (area) + { + gdk_gc_set_clip_rectangle (light_gc, area); + gdk_gc_set_clip_rectangle (dark_gc, area); + } + + if (area) + { + gdk_gc_set_clip_rectangle (light_gc, NULL); + gdk_gc_set_clip_rectangle (dark_gc, NULL); + } + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area); + } + + gdk_draw_line (window, clearlooks_style->shade_gc[0], x, y, x + width, y); + gdk_draw_line (window, clearlooks_style->shade_gc[3], x, y + height - 1, x + width, y + height - 1); + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL); + } + } + + light_gc = clearlooks_style->shade_gc[0]; + dark_gc = clearlooks_style->shade_gc[4]; + + rect.x = x + xthick; + rect.y = y + ythick; + rect.width = width - (xthick * 2); + rect.height = height - (ythick * 2); + + if (area) + intersect = gdk_rectangle_intersect (area, &rect, &dest); + else + { + intersect = TRUE; + dest = rect; + } + + if (!intersect) + return; + + gdk_gc_set_clip_rectangle (light_gc, &dest); + gdk_gc_set_clip_rectangle (dark_gc, &dest); + + n_lines = (!strcmp (detail, "paned")) ? 21 : 11; + + if (orientation == GTK_ORIENTATION_VERTICAL) + { + h = width - 2 * xthick; + h = MAX (3, h - 6); + + xx = x + (width - h) / 2; + offset = (height - 2*ythick - 2*n_lines)/2 + 1; + if (offset < 0) + offset = 0; + + for (i = 0, yy = y + ythick + offset; yy <= (y + height - ythick - 1) && i < n_lines; yy += 2, i++) + { + gdk_draw_line (window, dark_gc, xx, yy, xx + h, yy); + gdk_draw_line (window, light_gc, xx, yy + 1, xx + h, yy + 1); + } + } + else + { + h = height - 2 * ythick; + h = MAX (3, h - 6); + + yy = y + (height - h) / 2; + offset = (width - 2*xthick - 2*n_lines)/2 + 1; + if (offset < 0) + offset = 0; + + for (i = 0, xx = x + xthick + offset; i < n_lines; xx += 2, i++) + { + gdk_draw_line (window, dark_gc, xx, yy, xx, yy + h); + gdk_draw_line (window, light_gc, xx + 1, yy, xx + 1, yy + h); + } + } + + gdk_gc_set_clip_rectangle (light_gc, NULL); + gdk_gc_set_clip_rectangle (dark_gc, NULL); +} + +/**************************************************************************/ + +static void +draw_box (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + gboolean false_size = FALSE; + +#ifdef DEBUG + printf("draw_box: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (style != NULL); + g_return_if_fail (window != NULL); + + if (width == -1 || height == -1) + false_size = TRUE; + + if ((width == -1) && (height == -1)) + gdk_window_get_size (window, &width, &height); + else if (width == -1) + gdk_window_get_size (window, &width, NULL); + else if (height == -1) + gdk_window_get_size (window, NULL, &height); + + cl_rectangle_reset (&r, style); + + if (widget == NULL) + return; + + /* listview headers */ + if (widget && DETAIL ("button") && widget->parent && + (GTK_IS_TREE_VIEW(widget->parent) || + GTK_IS_CLIST (widget->parent) || + strcmp(G_OBJECT_TYPE_NAME (widget->parent), "ETree") == 0)) + { + cl_draw_treeview_header (style, window, state_type, shadow_type, + area, widget, detail, x, y, width, height); + } + else if (detail && (!strcmp (detail, "button") || + !strcmp (detail, "buttondefault"))) + { + if (GTK_IS_COMBO_BOX_ENTRY(widget->parent) || GTK_IS_COMBO(widget->parent)) + { + cl_draw_combobox_button (style, window, state_type, shadow_type, + area, widget, + detail, x, y, width, height); + } + else + { + cl_draw_button (style, window, state_type, shadow_type, area, widget, + detail, x, y, width, height); + } + } + else if (detail && ( + !strcmp (detail, "spinbutton_up") || + !strcmp (detail, "spinbutton_down") || + !strcmp (detail, "spinbutton"))) + { + cl_draw_spinbutton (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + } + else if (detail && ( + !strcmp (detail, "hscale") || !strcmp (detail, "vscale"))) + { + cl_rectangle_set_button (&r, style, state_type, + GTK_WIDGET_HAS_DEFAULT (widget), GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_ROUND, CL_CORNER_ROUND); + + if (!strcmp (detail, "hscale") || !strcmp (detail, "vscale")) + { + r.fill_gradient.to = &clearlooks_style->shade[2]; + r.bottomright = clearlooks_style->shade_gc[2]; + } + + cl_set_corner_sharpness (detail, widget, &r); + + if (!strcmp (detail, "spinbutton_up")) + { + r.border_gradient.to = r.border_gradient.from; + height++; + gtk_style_apply_default_background (style, window, FALSE, state_type, + area, x, y, width, height); + } + else if (!strcmp (detail, "spinbutton_down")) + { + r.border_gradient.to = r.border_gradient.from; + gtk_style_apply_default_background (style, window, FALSE, state_type, + area, x, y, width, height); + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x+1, y+1, width-2, height-2, &r); + cl_draw_shadow (window, widget, style, x+1, y+1, width-2, height-2, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("trough") && GTK_IS_PROGRESS_BAR (widget)) + { + GdkPoint points[4] = { {x,y}, {x+width-1,y}, {x,y+height-1}, {x+width-1,y+height-1} }; + + gdk_draw_points (window, style->bg_gc[state_type], points, 4); + + r.bordergc = clearlooks_style->shade_gc[5]; + r.fillgc = clearlooks_style->shade_gc[2]; + + cl_rectangle_set_corners (&r, CL_CORNER_NARROW, CL_CORNER_NARROW, + CL_CORNER_NARROW, CL_CORNER_NARROW); + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("trough") && + (GTK_IS_VSCALE (widget) || GTK_IS_HSCALE (widget))) + { + GdkGC *inner = clearlooks_style->shade_gc[3], + *outer = clearlooks_style->shade_gc[5], + *shadow = clearlooks_style->shade_gc[4]; + GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)), + lower_color; + + GtkAdjustment *adjustment = gtk_range_get_adjustment (GTK_RANGE (widget)); + + GtkOrientation orientation = GTK_RANGE (widget)->orientation; + + gint fill_size = (orientation ? height : width) * + (1 / ((adjustment->upper - adjustment->lower) / + (adjustment->value - adjustment->lower))); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + y += (height - SCALE_SIZE) / 2; + height = SCALE_SIZE; + } + else + { + x += (width - SCALE_SIZE) / 2; + width = SCALE_SIZE; + } + + if (state_type == GTK_STATE_INSENSITIVE) + { + outer = clearlooks_style->shade_gc[4]; + inner = clearlooks_style->shade_gc[2]; + shadow = clearlooks_style->shade_gc[3]; + } + + cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE ); + + r.topleft = shadow; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + /* DRAW FILL */ + shade (&upper_color, &lower_color, 1.3); + + r.bordergc = clearlooks_style->spot3_gc; + r.fillgc = style->bg_gc[state_type]; + + r.gradient_type = (orientation == GTK_ORIENTATION_HORIZONTAL ) ? CL_GRADIENT_VERTICAL + : CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color); + + cl_rectangle_set_clip_rectangle (&r, area); + if (orientation == GTK_ORIENTATION_HORIZONTAL && fill_size > 1) + { + if (gtk_range_get_inverted(GTK_RANGE(widget)) != (get_direction(widget) == GTK_TEXT_DIR_RTL)) + cl_draw_rectangle (window, widget, style, x+width-fill_size, y, fill_size, height, &r); + else + cl_draw_rectangle (window, widget, style, x, y, fill_size, height, &r); + } + else if (fill_size > 1) + { + if (gtk_range_get_inverted (GTK_RANGE (widget))) + cl_draw_rectangle (window, widget, style, x, y+height-fill_size, width, fill_size, &r); + else + cl_draw_rectangle (window, widget, style, x, y, width, fill_size, &r); + } + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("trough")) + { + GdkGC *inner = clearlooks_style->shade_gc[3], + *outer = clearlooks_style->shade_gc[5]; + + cl_rectangle_init (&r, inner, outer, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE ); + + if (GTK_RANGE (widget)->orientation == GTK_ORIENTATION_VERTICAL) + { + y+=1; + height-=2; + } + else + { + x+=1; + width-=2; + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (detail && (!strcmp (detail, "vscrollbar") || + !strcmp (detail, "hscrollbar") || + !strcmp (detail, "stepper"))) + { + ClScrollButtonType button_type = CL_SCROLLBUTTON_OTHER; + gboolean horizontal = TRUE; + + if (GTK_IS_VSCROLLBAR(widget)) + { + if (y == widget->allocation.y) + button_type = CL_SCROLLBUTTON_BEGIN; + else if (y+height == widget->allocation.y+widget->allocation.height) + button_type = CL_SCROLLBUTTON_END; + + horizontal = FALSE; + } + else if (GTK_IS_HSCROLLBAR(widget)) + { + if (x == widget->allocation.x) + button_type = CL_SCROLLBUTTON_BEGIN; + else if (x+width == widget->allocation.x+widget->allocation.width) + button_type = CL_SCROLLBUTTON_END; + } + + cl_rectangle_set_button (&r, style, state_type, FALSE, FALSE, 0,0,0,0); + + cl_rectangle_set_gradient (&r.fill_gradient, NULL, NULL); + cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type], + &clearlooks_style->inset_dark[state_type]); + + + r.gradient_type = horizontal ? CL_GRADIENT_VERTICAL + : CL_GRADIENT_HORIZONTAL; + + r.bottomright = clearlooks_style->shade_gc[1]; + r.border_gradient.to = r.border_gradient.from; + + if (button_type == CL_SCROLLBUTTON_OTHER) + { + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + } + else if (button_type == CL_SCROLLBUTTON_BEGIN) + { + if (horizontal) + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_NONE); + else + cl_rectangle_set_corners (&r, CL_CORNER_ROUND, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_NONE); + } + else + { + if (horizontal) + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_ROUND, + CL_CORNER_NONE, CL_CORNER_ROUND); + else + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_ROUND, CL_CORNER_ROUND); + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + } + else if (DETAIL ("slider")) + { + if (DETAIL("slider") && widget && GTK_IS_RANGE (widget)) + { + GtkAdjustment *adj = GTK_RANGE (widget)->adjustment; + + if (adj->value <= adj->lower && + (GTK_RANGE (widget)->has_stepper_a || GTK_RANGE (widget)->has_stepper_b)) + { + if (GTK_IS_VSCROLLBAR (widget)) + { + y-=1; + height+=1; + } + else if (GTK_IS_HSCROLLBAR (widget)) + { + x-=1; + width+=1; + } + } + if (adj->value >= adj->upper - adj->page_size && + (GTK_RANGE (widget)->has_stepper_c || GTK_RANGE (widget)->has_stepper_d)) + { + if (GTK_IS_VSCROLLBAR (widget)) + height+=1; + else if (GTK_IS_HSCROLLBAR (widget)) + width+=1; + } + } + + cl_rectangle_set_button (&r, style, state_type, FALSE, GTK_WIDGET_HAS_FOCUS (widget), + CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.gradient_type = GTK_IS_HSCROLLBAR (widget) ? CL_GRADIENT_VERTICAL + : CL_GRADIENT_HORIZONTAL; + + cl_rectangle_set_gradient (&r.fill_gradient, &clearlooks_style->inset_light[state_type], + &clearlooks_style->inset_dark[state_type]); + + r.bottomright = clearlooks_style->shade_gc[1]; + r.border_gradient.to = r.border_gradient.from; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (detail && !strcmp (detail, "optionmenu")) /* supporting deprecated */ + { + cl_draw_optionmenu(style, window, state_type, shadow_type, area, widget, detail, x, y, width, height); + } + else if (DETAIL ("menuitem")) + { + if (clearlooks_style->menuitemstyle == 0) + { + cl_draw_menuitem_flat (window, widget, style, area, state_type, + x, y, width, height, &r); + } + else if (clearlooks_style->menuitemstyle == 1) + { + cl_draw_menuitem_gradient (window, widget, style, area, state_type, + x, y, width, height, &r); + } + else + { + cl_draw_menuitem_button (window, widget, style, area, state_type, + x, y, width, height, &r); + } + } + else if (DETAIL ("menubar") && (clearlooks_style->sunkenmenubar || clearlooks_style->menubarstyle > 0)) + { + GdkGC *dark = clearlooks_style->shade_gc[2]; + GdkColor upper_color, lower_color; + + /* don't draw sunken menubar on gnome panel + IT'S A HACK! HORRIBLE HACK! HIDEOUS HACK! + BUT IT WORKS FOR ME(tm)! */ + if (widget->parent && + strcmp(G_OBJECT_TYPE_NAME (widget->parent), "PanelWidget") == 0) + return; + + shade(&style->bg[state_type], &upper_color, 1.0); + shade(&style->bg[state_type], &lower_color, 0.95); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.fillgc = style->bg_gc[state_type]; + r.bordergc = clearlooks_style->shade_gc[2]; + r.gradient_type = CL_GRADIENT_VERTICAL; + + cl_rectangle_set_gradient (&r.border_gradient, &clearlooks_style->shade[2], + &clearlooks_style->shade[3]); + cl_rectangle_set_gradient (&r.fill_gradient, &upper_color, &lower_color); + + /* make vertical and top borders invisible for style 2 */ + if (clearlooks_style->menubarstyle == 2) { + x--; width+=2; + y--; height+=1; + } + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + } + else if (DETAIL ("menu") && widget->parent && + GDK_IS_WINDOW (widget->parent->window)) + { + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = clearlooks_style->border_gc[CL_BORDER_UPPER]; + r.topleft = style->light_gc[state_type]; + r.bottomright = clearlooks_style->shade_gc[1]; + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + return; + } + else if (DETAIL ("bar") && widget && GTK_IS_PROGRESS_BAR (widget)) + { + GdkColor upper_color = *clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (style->rc_style)), + lower_color, + prev_foreground; + gboolean activity_mode = GTK_PROGRESS (widget)->activity_mode; + +#ifdef HAVE_ANIMATION + if (!activity_mode && gtk_progress_bar_get_fraction (widget) != 1.0 && + !cl_progressbar_known((gconstpointer)widget)) + { + cl_progressbar_add ((gpointer)widget); + } +#endif + cl_progressbar_fill (window, widget, style, style->black_gc, + x, y, width, height, +#ifdef HAVE_ANIMATION + activity_mode ? 0 : pboffset, +#else + 0, +#endif + area); + + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + r.bordergc = clearlooks_style->spot3_gc; + r.topleft = clearlooks_style->spot2_gc; + + prev_foreground = cl_gc_set_fg_color_shade (clearlooks_style->spot2_gc, + style->colormap, + &clearlooks_style->spot2, + 1.2); + + cl_rectangle_set_clip_rectangle (&r, area); + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + cl_rectangle_reset_clip_rectangle (&r); + + gdk_gc_set_foreground (clearlooks_style->spot2_gc, &prev_foreground); + } + + else if ( widget && (DETAIL ("menubar") || DETAIL ("toolbar") || DETAIL ("dockitem_bin") || DETAIL ("handlebox_bin")) && shadow_type != GTK_SHADOW_NONE) /* Toolbars and menus */ + { + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], area); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], area); + } + + gtk_style_apply_default_background (style, window, + widget && !GTK_WIDGET_NO_WINDOW (widget), + state_type, area, x, y, width, height); + + /* we only want the borders on horizontal toolbars */ + if ( DETAIL ("menubar") || height < 2*width ) { + if (!DETAIL ("menubar")) + gdk_draw_line (window, clearlooks_style->shade_gc[0], + x, y, x + width, y); /* top */ + + gdk_draw_line (window, clearlooks_style->shade_gc[3], + x, y + height - 1, x + width, y + height - 1); /* bottom */ + } + + if (area) + { + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[0], NULL); + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[3], NULL); + } + } + else + { + parent_class->draw_box (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + } +} + +/**************************************************************************/ + +static void +ensure_check_pixmaps (GtkStyle *style, + GtkStateType state, + GdkScreen *screen, + gboolean treeview) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style); + GdkPixbuf *check, *base, *inconsistent, *composite; + GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc); + + if (clearlooks_style->check_pixmap_nonactive[state] != NULL) + return; + + if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) { + check = generate_bit (check_alpha, &style->text[GTK_STATE_NORMAL], 1.0); + inconsistent = generate_bit (check_inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0); + } else { + check = generate_bit (check_alpha, &style->text[state], 1.0); + inconsistent = generate_bit (check_inconsistent_alpha, &style->text[state], 1.0); + } + + if (state == GTK_STATE_ACTIVE && !treeview) + base = generate_bit (check_base_alpha, &style->bg[state], 1.0); + else + base = generate_bit (check_base_alpha, &style->base[GTK_STATE_NORMAL], 1.0); + + if (treeview) + composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0); + else + composite = generate_bit (NULL, &clearlooks_style->shade[5], 1.0); + + gdk_pixbuf_composite (base, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->check_pixmap_nonactive[state] = + pixbuf_to_pixmap (style, composite, screen); + + gdk_pixbuf_composite (check, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->check_pixmap_active[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + + composite = generate_bit (NULL, &clearlooks_style->shade[6], 1.0); + + gdk_pixbuf_composite (base, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + gdk_pixbuf_composite (inconsistent, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->check_pixmap_inconsistent[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + g_object_unref (base); + g_object_unref (check); + g_object_unref (inconsistent); +} + +static void +draw_check (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *gc = style->base_gc[state_type]; + GdkPixmap *pixmap; + gboolean treeview; + + if (DETAIL ("check")) /* Menu item */ + { + parent_class->draw_check (style, window, state_type, shadow_type, area, + widget, detail, x, y, width, height); + return; + } + + treeview = widget && GTK_IS_TREE_VIEW(widget); + ensure_check_pixmaps (style, state_type, gtk_widget_get_screen (widget), treeview); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (shadow_type == GTK_SHADOW_IN) + pixmap = clearlooks_style->check_pixmap_active[state_type]; + else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ + pixmap = clearlooks_style->check_pixmap_inconsistent[state_type]; + else + pixmap = clearlooks_style->check_pixmap_nonactive[state_type]; + + x += (width - CHECK_SIZE)/2; + y += (height - CHECK_SIZE)/2; + + gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y, CHECK_SIZE, CHECK_SIZE); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +/**************************************************************************/ +static void +draw_slider (DRAW_ARGS, GtkOrientation orientation) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *shade_gc = clearlooks_style->shade_gc[4]; + GdkGC *white_gc = clearlooks_style->shade_gc[0]; + int x1, y1; + +#if DEBUG + printf("draw_slider: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + gtk_paint_box (style, window, state_type, shadow_type, + area, widget, detail, x, y, width, height); + + if ((orientation == GTK_ORIENTATION_VERTICAL && height < 20) || + (orientation == GTK_ORIENTATION_HORIZONTAL && width < 20)) + return; + + if (detail && strcmp ("slider", detail) == 0) + { + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, area); + gdk_gc_set_clip_rectangle (white_gc, area); + } + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + x1 = x + width / 2 - 4; + y1 = y + (height - 6) / 2; + gdk_draw_line (window, shade_gc, x1, y1, x1, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 1, y1, x1 + 1, y1 + 6); + gdk_draw_line (window, shade_gc, x1 + 3, y1, x1 + 3, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 3 + 1, y1, x1 + 3 + 1, y1 + 6); + gdk_draw_line (window, shade_gc, x1 + 3*2, y1, x1 + 3*2, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 3*2 + 1, y1, x1 + 3*2 + 1, y1 + 6); + } + else + { + x1 = x + (width - 6) / 2; + y1 = y + height / 2 - 4; + gdk_draw_line (window, shade_gc, x1 + 6, y1, x1, y1); + gdk_draw_line (window, white_gc, x1 + 6, y1 + 1, x1, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3, x1, y1 + 3); + gdk_draw_line (window, white_gc, x1 + 6, y1 + 3 + 1, x1, y1 + 3 + 1); + gdk_draw_line (window, shade_gc, x1 + 6, y1 + 3*2, x1, y1 + 3*2); + gdk_draw_line (window, white_gc, x1 + 6, y1 + 3*2 + 1, x1, y1 + 3*2 + 1); + } + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, NULL); + gdk_gc_set_clip_rectangle (white_gc, NULL); + } + } + else if (detail && (strcmp ("hscale", detail) == 0 || strcmp ("vscale", detail) == 0)) + { + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, area); + gdk_gc_set_clip_rectangle (white_gc, area); + } + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + x1 = x + width / 2 - 3; + y1 = y + (height - 7) / 2; + gdk_draw_line (window, shade_gc, x1 + 0, y1 + 5, x1 + 0, y1 + 1); + gdk_draw_line (window, white_gc, x1 + 1, y1 + 5, x1 + 1, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 3, y1 + 5, x1 + 3, y1 + 1); + gdk_draw_line (window, white_gc, x1 + 4, y1 + 5, x1 + 4, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 6, y1 + 5, x1 + 6, y1 + 1); + gdk_draw_line (window, white_gc, x1 + 7, y1 + 5, x1 + 7, y1 + 1); + } + else + { + x1 = x + (width - 7) / 2; + y1 = y + height / 2 - 3; + gdk_draw_line (window, shade_gc, x1 + 5, y1 + 0, x1 + 1, y1 + 0); + gdk_draw_line (window, white_gc, x1 + 5, y1 + 1, x1 + 1, y1 + 1); + gdk_draw_line (window, shade_gc, x1 + 5, y1 + 3, x1 + 1, y1 + 3); + gdk_draw_line (window, white_gc, x1 + 5, y1 + 4, x1 + 1, y1 + 4); + gdk_draw_line (window, shade_gc, x1 + 5, y1 + 6, x1 + 1, y1 + 6); + gdk_draw_line (window, white_gc, x1 + 5, y1 + 7, x1 + 1, y1 + 7); + } + if (area) + { + gdk_gc_set_clip_rectangle (shade_gc, NULL); + gdk_gc_set_clip_rectangle (white_gc, NULL); + } + } +} + +/**************************************************************************/ +static void +ensure_radio_pixmaps (GtkStyle *style, + GtkStateType state, + GdkScreen *screen) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + ClearlooksRcStyle *clearlooks_rc = CLEARLOOKS_RC_STYLE (style->rc_style); + GdkPixbuf *dot, *circle, *outline, *inconsistent, *composite; + GdkColor *spot_color = clearlooks_get_spot_color (clearlooks_rc); + GdkColor *composite_color; + + if (clearlooks_style->radio_pixmap_nonactive[state] != NULL) + return; + + if (state == GTK_STATE_ACTIVE || state == GTK_STATE_SELECTED) { + dot = colorize_bit (dot_intensity, dot_alpha, &style->text[GTK_STATE_NORMAL]); + inconsistent = generate_bit (inconsistent_alpha, &style->text[GTK_STATE_NORMAL], 1.0); + } else { + dot = colorize_bit (dot_intensity, dot_alpha, &style->text[state]); + inconsistent = generate_bit (inconsistent_alpha, &style->text[state], 1.0); + } + + outline = generate_bit (outline_alpha, &clearlooks_style->shade[5], 1.0); + + if (clearlooks_style->radio_pixmap_mask == NULL) + { + gdk_pixbuf_render_pixmap_and_mask (outline, + NULL, + &clearlooks_style->radio_pixmap_mask, + 1); + } + + if (state == GTK_STATE_ACTIVE) + { + composite_color = &style->bg[GTK_STATE_PRELIGHT]; + circle = generate_bit (circle_alpha, &style->bg[state], 1.0); + } + else + { + composite_color = &style->bg[state]; + circle = generate_bit (circle_alpha, &style->base[GTK_STATE_NORMAL], 1.0); + } + + composite = generate_bit (NULL, composite_color, 1.0); + + gdk_pixbuf_composite (outline, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + gdk_pixbuf_composite (circle, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->radio_pixmap_nonactive[state] = + pixbuf_to_pixmap (style, composite, screen); + + gdk_pixbuf_composite (dot, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->radio_pixmap_active[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + + composite = generate_bit (NULL, composite_color,1.0); + + gdk_pixbuf_composite (outline, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + gdk_pixbuf_composite (circle, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + gdk_pixbuf_composite (inconsistent, composite, + 0, 0, RADIO_SIZE, RADIO_SIZE, 0, 0, + 1.0, 1.0, GDK_INTERP_NEAREST, 255); + + clearlooks_style->radio_pixmap_inconsistent[state] = + pixbuf_to_pixmap (style, composite, screen); + + g_object_unref (composite); + g_object_unref (circle); + g_object_unref (dot); + g_object_unref (inconsistent); + g_object_unref (outline); +} + +static void +draw_option (DRAW_ARGS) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkGC *gc = style->base_gc[state_type]; + GdkPixmap *pixmap; + + if (DETAIL ("option")) /* Menu item */ + { + parent_class->draw_option (style, window, state_type, shadow_type, + area, widget, detail, x, y, width, height); + return; + } + + ensure_radio_pixmaps (style, state_type, gtk_widget_get_screen (widget)); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (shadow_type == GTK_SHADOW_IN) + pixmap = clearlooks_style->radio_pixmap_active[state_type]; + else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */ + pixmap = clearlooks_style->radio_pixmap_inconsistent[state_type]; + else + pixmap = clearlooks_style->radio_pixmap_nonactive[state_type]; + + x += (width - RADIO_SIZE)/2; + y += (height - RADIO_SIZE)/2; + +#ifndef GTKOSX + gdk_gc_set_clip_mask (gc, clearlooks_style->radio_pixmap_mask); + gdk_gc_set_clip_origin (gc, x, y); +#endif + + gdk_draw_drawable (window, gc, pixmap, 0, 0, x, y, + RADIO_SIZE, RADIO_SIZE); + +#ifndef GTKOSX + gdk_gc_set_clip_origin (gc, 0, 0); + gdk_gc_set_clip_mask (gc, NULL); +#endif + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +/**************************************************************************/ + +static void +draw_shadow_gap (DRAW_ARGS, + GtkPositionType gap_side, + gint gap_x, + gint gap_width) +{ + /* I need to improve this function. */ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + CLRectangle r; + GdkRegion *area_region = NULL, + *gap_region = NULL; + +#if DEBUG + printf("draw_shadow_gap: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + sanitize_size (window, &width, &height); + + cl_rectangle_reset (&r, style); + cl_rectangle_set_corners (&r, CL_CORNER_NONE, CL_CORNER_NONE, + CL_CORNER_NONE, CL_CORNER_NONE); + + if (area) + { + area_region = gdk_region_rectangle (area); + + switch (gap_side) + { + case GTK_POS_TOP: + { + GdkRectangle rect = { x+gap_x, y, gap_width, 2 }; + gap_region = gdk_region_rectangle (&rect); + break; + } + case GTK_POS_BOTTOM: + { + GdkRectangle rect = { x+gap_x, y+height-2, gap_width, 2 }; + gap_region = gdk_region_rectangle (&rect); + break; + } + case GTK_POS_LEFT: + { + GdkRectangle rect = { x, y+gap_x, 2, gap_width }; + gap_region = gdk_region_rectangle (&rect); + break; + } + case GTK_POS_RIGHT: + { + GdkRectangle rect = { x+width-2, y+gap_x, 2, gap_width }; + gap_region = gdk_region_rectangle (&rect); + break; + } + } + + gdk_region_subtract (area_region, gap_region); + } + + if (shadow_type == GTK_SHADOW_ETCHED_IN || + shadow_type == GTK_SHADOW_ETCHED_OUT) + { + GdkGC *a; + GdkGC *b; + + if (shadow_type == GTK_SHADOW_ETCHED_IN) + { + a = style->light_gc[state_type]; + b = clearlooks_style->shade_gc[3]; + } + else + { + a = clearlooks_style->shade_gc[3]; + b = style->light_gc[state_type]; + } + + gdk_gc_set_clip_region (a, area_region); + gdk_gc_set_clip_region (b, area_region); + + r.bordergc = a; + cl_draw_rectangle (window, widget, style, x+1, y+1, width-1, height-1, &r); + + r.bordergc = b; + cl_draw_rectangle (window, widget, style, x, y, width-1, height-1, &r); + + gdk_gc_set_clip_region (a, NULL); + gdk_gc_set_clip_region (b, NULL); + } + else if (shadow_type == GTK_SHADOW_IN || shadow_type == GTK_SHADOW_OUT) + { + r.topleft = (shadow_type == GTK_SHADOW_OUT) ? style->light_gc[state_type] : clearlooks_style->shade_gc[1]; + r.bottomright = (shadow_type == GTK_SHADOW_OUT) ? clearlooks_style->shade_gc[1] : style->light_gc[state_type]; + r.bordergc = clearlooks_style->shade_gc[5]; + + gdk_gc_set_clip_region (r.bordergc, area_region); + gdk_gc_set_clip_region (r.topleft, area_region); + gdk_gc_set_clip_region (r.bottomright, area_region); + + cl_draw_rectangle (window, widget, style, x, y, width, height, &r); + + cl_draw_shadow (window, widget, style, x, y, width, height, &r); + + gdk_gc_set_clip_region (r.bordergc, NULL); + gdk_gc_set_clip_region (r.topleft, NULL); + gdk_gc_set_clip_region (r.bottomright, NULL); + } + + if (area_region) + gdk_region_destroy (area_region); +} + +/**************************************************************************/ +static void +draw_hline (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x1, + gint x2, + gint y) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + +#if DEBUG + printf("draw_hline\n"); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area); + + if (detail && !strcmp (detail, "label")) + { + if (state_type == GTK_STATE_INSENSITIVE) + gdk_draw_line (window, style->light_gc[state_type], x1 + 1, y + 1, x2 + 1, y + 1); + + gdk_draw_line (window, style->fg_gc[state_type], x1, y, x2, y); + } + else + { + gdk_draw_line (window, clearlooks_style->shade_gc[2], x1, y, x2, y); + + /* if (DETAIL ("menuitem")) */ + gdk_draw_line (window, clearlooks_style->shade_gc[0], x1, y+1, x2, y+1); + } + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL); +} + +/**************************************************************************/ +static void +draw_vline (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint y1, + gint y2, + gint x) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + gint thickness_light; + gint thickness_dark; + +#if DEBUG + printf("draw_vline\n"); +#endif + + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + thickness_light = style->xthickness / 2; + thickness_dark = style->xthickness - thickness_light; + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], area); + + gdk_draw_line (window, clearlooks_style->shade_gc[2], x, y1, x, y2 - 1); + gdk_draw_line (window, clearlooks_style->shade_gc[0], x+1, y1, x+1, y2 - 1); + + if (area) + gdk_gc_set_clip_rectangle (clearlooks_style->shade_gc[2], NULL); +} + +/**************************************************************************/ +static void +draw_focus (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkPoint points[5]; + GdkGC *gc; + gboolean free_dash_list = FALSE; + gint line_width = 1; + gchar *dash_list = "\1\1"; + gint dash_len; + +#if DEBUG + printf("draw_focus: %s %d %d %d %d\n", detail, x, y, width, height); +#endif + + gc = clearlooks_style->shade_gc[6]; + + if (widget) + { + gtk_widget_style_get (widget, + "focus-line-width", &line_width, + "focus-line-pattern", (gchar *)&dash_list, + NULL); + + free_dash_list = TRUE; + } + + sanitize_size (window, &width, &height); + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + gdk_gc_set_line_attributes (gc, line_width, + dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID, + GDK_CAP_BUTT, GDK_JOIN_MITER); + + + if (detail && !strcmp (detail, "add-mode")) + { + if (free_dash_list) + g_free (dash_list); + + dash_list = "\4\4"; + free_dash_list = FALSE; + } + + points[0].x = x + line_width / 2; + points[0].y = y + line_width / 2; + points[1].x = x + width - line_width + line_width / 2; + points[1].y = y + line_width / 2; + points[2].x = x + width - line_width + line_width / 2; + points[2].y = y + height - line_width + line_width / 2; + points[3].x = x + line_width / 2; + points[3].y = y + height - line_width + line_width / 2; + points[4] = points[0]; + + if (!dash_list[0]) + { + gdk_draw_lines (window, gc, points, 5); + } + else + { + dash_len = strlen (dash_list); + + if (dash_list[0]) + gdk_gc_set_dashes (gc, 0, dash_list, dash_len); + + gdk_draw_lines (window, gc, points, 3); + + points[2].x += 1; + + if (dash_list[0]) + { + gint dash_pixels = 0; + gint i; + + /* Adjust the dash offset for the bottom and left so we + * match up at the upper left. + */ + for (i = 0; i < dash_len; i++) + dash_pixels += dash_list[i]; + + if (dash_len % 2 == 1) + dash_pixels *= 2; + + gdk_gc_set_dashes (gc, + dash_pixels - (width + height - 2 * line_width) % dash_pixels, + dash_list, dash_len); + } + + gdk_draw_lines (window, gc, points + 2, 3); + } + + gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER); + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); + + if (free_dash_list) + g_free (dash_list); +} + +static void +draw_layout(GtkStyle * style, + GdkWindow * window, + GtkStateType state_type, + gboolean use_text, + GdkRectangle * area, + GtkWidget * widget, + const gchar * detail, gint x, gint y, PangoLayout * layout) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + + g_return_if_fail(GTK_IS_STYLE (style)); + g_return_if_fail(window != NULL); + + parent_class->draw_layout(style, window, state_type, use_text, + area, widget, detail, x, y, layout); + + +} + +/**************************************************************************/ +static void +draw_resize_grip (GtkStyle *style, + GdkWindow *window, + GtkStateType state_type, + GdkRectangle *area, + GtkWidget *widget, + const gchar *detail, + GdkWindowEdge edge, + gint x, + gint y, + gint width, + gint height) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + g_return_if_fail (GTK_IS_STYLE (style)); + g_return_if_fail (window != NULL); + + if (area) + { + gdk_gc_set_clip_rectangle (style->light_gc[state_type], area); + gdk_gc_set_clip_rectangle (style->dark_gc[state_type], area); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], area); + } + + switch (edge) + { + case GDK_WINDOW_EDGE_NORTH_WEST: + /* make it square */ + if (width < height) + { + height = width; + } + else if (height < width) + { + width = height; + } + break; + case GDK_WINDOW_EDGE_NORTH: + if (width < height) + { + height = width; + } + break; + case GDK_WINDOW_EDGE_NORTH_EAST: + /* make it square, aligning to top right */ + if (width < height) + { + height = width; + } + else if (height < width) + { + x += (width - height); + width = height; + } + break; + case GDK_WINDOW_EDGE_WEST: + if (height < width) + { + width = height; + } + break; + case GDK_WINDOW_EDGE_EAST: + /* aligning to right */ + if (height < width) + { + x += (width - height); + width = height; + } + break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + /* make it square, aligning to bottom left */ + if (width < height) + { + y += (height - width); + height = width; + } + else if (height < width) + { + width = height; + } + break; + case GDK_WINDOW_EDGE_SOUTH: + /* align to bottom */ + if (width < height) + { + y += (height - width); + height = width; + } + break; + case GDK_WINDOW_EDGE_SOUTH_EAST: + /* make it square, aligning to bottom right */ + if (width < height) + { + y += (height - width); + height = width; + } + else if (height < width) + { + x += (width - height); + width = height; + } + break; + default: + g_assert_not_reached (); + } + + /* Clear background */ + gtk_style_apply_default_background (style, window, FALSE, + state_type, area, + x, y, width, height); + + switch (edge) + { + case GDK_WINDOW_EDGE_WEST: + case GDK_WINDOW_EDGE_EAST: + { + gint xi; + + xi = x; + + while (xi < x + width) + { + gdk_draw_line (window, + style->light_gc[state_type], + xi, y, + xi, y + height); + + xi++; + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y, + xi, y + height); + + xi += 2; + } + } + break; + case GDK_WINDOW_EDGE_NORTH: + case GDK_WINDOW_EDGE_SOUTH: + { + gint yi; + + yi = y; + + while (yi < y + height) + { + gdk_draw_line (window, + style->light_gc[state_type], + x, yi, + x + width, yi); + + yi++; + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + x, yi, + x + width, yi); + + yi+= 2; + } + } + break; + case GDK_WINDOW_EDGE_NORTH_WEST: + { + gint xi, yi; + + xi = x + width; + yi = y + height; + + while (xi > x + 3) + { + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y, + x, yi); + + --xi; + --yi; + + gdk_draw_line (window, + style->light_gc[state_type], + xi, y, + x, yi); + + xi -= 3; + yi -= 3; + + } + } + break; + case GDK_WINDOW_EDGE_NORTH_EAST: + { + gint xi, yi; + + xi = x; + yi = y + height; + + while (xi < (x + width - 3)) + { + gdk_draw_line (window, + style->light_gc[state_type], + xi, y, + x + width, yi); + + ++xi; + --yi; + + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y, + x + width, yi); + + xi += 3; + yi -= 3; + } + } + break; + case GDK_WINDOW_EDGE_SOUTH_WEST: + { + gint xi, yi; + + xi = x + width; + yi = y; + + while (xi > x + 3) + { + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + x, yi, + xi, y + height); + + --xi; + ++yi; + + gdk_draw_line (window, + style->light_gc[state_type], + x, yi, + xi, y + height); + + xi -= 3; + yi += 3; + + } + } + break; + + case GDK_WINDOW_EDGE_SOUTH_EAST: + { + gint xi, yi; + + xi = x; + yi = y; + + while (xi < (x + width - 3)) + { + gdk_draw_line (window, + style->light_gc[state_type], + xi, y + height, + x + width, yi); + + ++xi; + ++yi; + + gdk_draw_line (window, + clearlooks_style->shade_gc[4], + xi, y + height, + x + width, yi); + + xi += 3; + yi += 3; + } + } + break; + default: + g_assert_not_reached (); + break; + } + + if (area) + { + gdk_gc_set_clip_rectangle (style->light_gc[state_type], NULL); + gdk_gc_set_clip_rectangle (style->dark_gc[state_type], NULL); + gdk_gc_set_clip_rectangle (style->bg_gc[state_type], NULL); + } +} + +/**************************************************************************/ + +static void +clearlooks_style_init_from_rc (GtkStyle * style, + GtkRcStyle * rc_style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + GdkColor *spot_color; + double shades[] = {1.065, 0.93, 0.896, 0.85, 0.768, 0.665, 0.4, 0.205}; + int i; + double contrast; + + parent_class->init_from_rc (style, rc_style); + + contrast = CLEARLOOKS_RC_STYLE (rc_style)->contrast; + + clearlooks_style->sunkenmenubar = CLEARLOOKS_RC_STYLE (rc_style)->sunkenmenubar; + clearlooks_style->progressbarstyle = CLEARLOOKS_RC_STYLE (rc_style)->progressbarstyle; + clearlooks_style->menubarstyle = CLEARLOOKS_RC_STYLE (rc_style)->menubarstyle; + clearlooks_style->menuitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->menuitemstyle; + clearlooks_style->listviewitemstyle = CLEARLOOKS_RC_STYLE (rc_style)->listviewitemstyle; + + /* Lighter to darker */ + for (i = 0; i < 8; i++) + { + shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->shade[i], + (shades[i]-0.7) * contrast + 0.7); + } + + spot_color = clearlooks_get_spot_color (CLEARLOOKS_RC_STYLE (rc_style)); + + clearlooks_style->spot_color = *spot_color; + shade (&clearlooks_style->spot_color, &clearlooks_style->spot1, 1.42); + shade (&clearlooks_style->spot_color, &clearlooks_style->spot2, 1.05); + shade (&clearlooks_style->spot_color, &clearlooks_style->spot3, 0.65); + + shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_UPPER], 0.5); + shade (&style->bg[GTK_STATE_NORMAL], &clearlooks_style->border[CL_BORDER_LOWER], 0.62); + shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_UPPER_ACTIVE], 0.5); + shade (&style->bg[GTK_STATE_ACTIVE], &clearlooks_style->border[CL_BORDER_LOWER_ACTIVE], 0.55); +} + +static GdkGC * +realize_color (GtkStyle * style, + GdkColor * color) +{ + GdkGCValues gc_values; + + gdk_colormap_alloc_color (style->colormap, color, FALSE, TRUE); + + gc_values.foreground = *color; + + return gtk_gc_get (style->depth, style->colormap, &gc_values, GDK_GC_FOREGROUND); +} + +static void +clearlooks_style_realize (GtkStyle * style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int i; + + parent_class->realize (style); + + for (i = 0; i < 8; i++) + clearlooks_style->shade_gc[i] = realize_color (style, &clearlooks_style->shade[i]); + + for (i=0; i < CL_BORDER_COUNT; i++) + clearlooks_style->border_gc[i] = realize_color (style, &clearlooks_style->border[i]); + + clearlooks_style->spot1_gc = realize_color (style, &clearlooks_style->spot1); + clearlooks_style->spot2_gc = realize_color (style, &clearlooks_style->spot2); + clearlooks_style->spot3_gc = realize_color (style, &clearlooks_style->spot3); + + /* set light inset color */ + for (i=0; i<5; i++) + { + shade (&style->bg[i], &clearlooks_style->inset_dark[i], 0.93); + gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_dark[i]); + + shade (&style->bg[i], &clearlooks_style->inset_light[i], 1.055); + gdk_rgb_find_color (style->colormap, &clearlooks_style->inset_light[i]); + + shade (&style->bg[i], &clearlooks_style->listview_bg[i], 1.015); + gdk_rgb_find_color (style->colormap, &clearlooks_style->listview_bg[i]); + + /* CREATE GRADIENT FOR BUTTONS */ + shade (&style->bg[i], &clearlooks_style->button_g1[i], 1.055); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g1[i]); + + shade (&style->bg[i], &clearlooks_style->button_g2[i], 1.005); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g2[i]); + + shade (&style->bg[i], &clearlooks_style->button_g3[i], 0.98); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g3[i]); + + shade (&style->bg[i], &clearlooks_style->button_g4[i], 0.91); + gdk_rgb_find_color (style->colormap, &clearlooks_style->button_g4[i]); + } + +} + +static void +clearlooks_style_unrealize (GtkStyle * style) +{ + ClearlooksStyle *clearlooks_style = CLEARLOOKS_STYLE (style); + int i; + + /* We don't free the colors, because we don't know if + * gtk_gc_release() actually freed the GC. FIXME - need + * a way of ref'ing colors explicitely so GtkGC can + * handle things properly. + */ + for (i=0; i < 8; i++) + gtk_gc_release (clearlooks_style->shade_gc[i]); + + gtk_gc_release (clearlooks_style->spot1_gc); + gtk_gc_release (clearlooks_style->spot2_gc); + gtk_gc_release (clearlooks_style->spot3_gc); + + for (i = 0; i < 5; i++) + { + if (clearlooks_style->radio_pixmap_nonactive[i] != NULL) + { + g_object_unref (clearlooks_style->radio_pixmap_nonactive[i]); + clearlooks_style->radio_pixmap_nonactive[i] = NULL; + g_object_unref (clearlooks_style->radio_pixmap_active[i]); + clearlooks_style->radio_pixmap_active[i] = NULL; + g_object_unref (clearlooks_style->radio_pixmap_inconsistent[i]); + clearlooks_style->radio_pixmap_inconsistent[i] = NULL; + } + + if (clearlooks_style->check_pixmap_nonactive[i] != NULL) + { + g_object_unref (clearlooks_style->check_pixmap_nonactive[i]); + clearlooks_style->check_pixmap_nonactive[i] = NULL; + g_object_unref (clearlooks_style->check_pixmap_active[i]); + clearlooks_style->check_pixmap_active[i] = NULL; + g_object_unref (clearlooks_style->check_pixmap_inconsistent[i]); + clearlooks_style->check_pixmap_inconsistent[i] = NULL; + } + } + + if (clearlooks_style->radio_pixmap_mask != NULL) + g_object_unref (clearlooks_style->radio_pixmap_mask); + + clearlooks_style->radio_pixmap_mask = NULL; + + while (progressbars = g_list_first (progressbars)) + cl_progressbar_remove (progressbars->data); + + if (timer_id != 0) + { + g_source_remove(timer_id); + timer_id = 0; + } + + parent_class->unrealize (style); +} + +static GdkPixbuf * +set_transparency (const GdkPixbuf *pixbuf, gdouble alpha_percent) +{ + GdkPixbuf *target; + guchar *data, *current; + guint x, y, rowstride, height, width; + + g_return_val_if_fail (pixbuf != NULL, NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + /* Returns a copy of pixbuf with it's non-completely-transparent pixels to + have an alpha level "alpha_percent" of their original value. */ + + target = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); + + if (alpha_percent == 1.0) + return target; + width = gdk_pixbuf_get_width (target); + height = gdk_pixbuf_get_height (target); + rowstride = gdk_pixbuf_get_rowstride (target); + data = gdk_pixbuf_get_pixels (target); + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + /* The "4" is the number of chars per pixel, in this case, RGBA, + the 3 means "skip to the alpha" */ + current = data + (y * rowstride) + (x * 4) + 3; + *(current) = (guchar) (*(current) * alpha_percent); + } + } + + return target; +} + +static GdkPixbuf* +scale_or_ref (GdkPixbuf *src, + int width, + int height) +{ + if (width == gdk_pixbuf_get_width (src) && + height == gdk_pixbuf_get_height (src)) { + return g_object_ref (src); + } else { + return gdk_pixbuf_scale_simple (src, + width, height, + GDK_INTERP_BILINEAR); + } +} + +static GdkPixbuf * +render_icon (GtkStyle *style, + const GtkIconSource *source, + GtkTextDirection direction, + GtkStateType state, + GtkIconSize size, + GtkWidget *widget, + const char *detail) +{ + int width = 1; + int height = 1; + GdkPixbuf *scaled; + GdkPixbuf *stated; + GdkPixbuf *base_pixbuf; + GdkScreen *screen; + GtkSettings *settings; + + /* Oddly, style can be NULL in this function, because + * GtkIconSet can be used without a style and if so + * it uses this function. + */ + + base_pixbuf = gtk_icon_source_get_pixbuf (source); + + g_return_val_if_fail (base_pixbuf != NULL, NULL); + + if (widget && gtk_widget_has_screen (widget)) { + screen = gtk_widget_get_screen (widget); + settings = gtk_settings_get_for_screen (screen); + } else if (style->colormap) { + screen = gdk_colormap_get_screen (style->colormap); + settings = gtk_settings_get_for_screen (screen); + } else { + settings = gtk_settings_get_default (); + GTK_NOTE (MULTIHEAD, + g_warning ("Using the default screen for gtk_default_render_icon()")); + } + + + if (size != (GtkIconSize) -1 && !gtk_icon_size_lookup_for_settings (settings, size, &width, &height)) { + g_warning (G_STRLOC ": invalid icon size '%d'", size); + return NULL; + } + + /* If the size was wildcarded, and we're allowed to scale, then scale; otherwise, + * leave it alone. + */ + if (size != (GtkIconSize)-1 && gtk_icon_source_get_size_wildcarded (source)) + scaled = scale_or_ref (base_pixbuf, width, height); + else + scaled = g_object_ref (base_pixbuf); + + /* If the state was wildcarded, then generate a state. */ + if (gtk_icon_source_get_state_wildcarded (source)) { + if (state == GTK_STATE_INSENSITIVE) { + stated = set_transparency (scaled, 0.3); +#if 0 + stated = + gdk_pixbuf_composite_color_simple (scaled, + gdk_pixbuf_get_width (scaled), + gdk_pixbuf_get_height (scaled), + GDK_INTERP_BILINEAR, 128, + gdk_pixbuf_get_width (scaled), + style->bg[state].pixel, + style->bg[state].pixel); +#endif + gdk_pixbuf_saturate_and_pixelate (stated, stated, + 0.1, FALSE); + + g_object_unref (scaled); + } else if (state == GTK_STATE_PRELIGHT) { + stated = gdk_pixbuf_copy (scaled); + + gdk_pixbuf_saturate_and_pixelate (scaled, stated, + 1.2, FALSE); + + g_object_unref (scaled); + } else { + stated = scaled; + } + } + else + stated = scaled; + + return stated; +} + +static void +clearlooks_style_init (ClearlooksStyle * style) +{ +} + +static void +clearlooks_style_class_init (ClearlooksStyleClass * klass) +{ + GtkStyleClass *style_class = GTK_STYLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + style_class->realize = clearlooks_style_realize; + style_class->unrealize = clearlooks_style_unrealize; + style_class->init_from_rc = clearlooks_style_init_from_rc; + style_class->draw_focus = draw_focus; + style_class->draw_resize_grip = draw_resize_grip; + style_class->draw_handle = draw_handle; + style_class->draw_vline = draw_vline; + style_class->draw_hline = draw_hline; + style_class->draw_slider = draw_slider; + style_class->draw_shadow_gap = draw_shadow_gap; + style_class->draw_arrow = clearlooks_draw_arrow; + style_class->draw_check = draw_check; + style_class->draw_tab = draw_tab; + style_class->draw_box = draw_box; + style_class->draw_shadow = draw_shadow; + style_class->draw_box_gap = draw_box_gap; + style_class->draw_extension = draw_extension; + style_class->draw_option = draw_option; + style_class->draw_layout = draw_layout; + style_class->render_icon = render_icon; + style_class->draw_flat_box = draw_flat_box; +} + +GType clearlooks_type_style = 0; + +void +clearlooks_style_register_type (GTypeModule * module) +{ + static const GTypeInfo object_info = + { + sizeof (ClearlooksStyleClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) clearlooks_style_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (ClearlooksStyle), + 0, /* n_preallocs */ + (GInstanceInitFunc) clearlooks_style_init, + NULL + }; + + clearlooks_type_style = g_type_module_register_type (module, + GTK_TYPE_STYLE, + "ClearlooksStyle", + &object_info, 0); +} diff --git a/libs/clearlooks-older/clearlooks_style.h b/libs/clearlooks-older/clearlooks_style.h new file mode 100644 index 0000000000..1e07877bf7 --- /dev/null +++ b/libs/clearlooks-older/clearlooks_style.h @@ -0,0 +1,108 @@ +/* Clearlooks Engine + * Copyright (C) 2005 Richard Stellingwerff. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Written by Owen Taylor <otaylor@redhat.com> + * and by Alexander Larsson <alexl@redhat.com> + * Modified by Richard Stellingwerff <remenic@gmail.com> + */ +#include <gtk/gtkstyle.h> + +#include "clearlooks_draw.h" + +typedef struct _ClearlooksStyle ClearlooksStyle; +typedef struct _ClearlooksStyleClass ClearlooksStyleClass; + +extern GType clearlooks_type_style; + +#define CLEARLOOKS_TYPE_STYLE clearlooks_type_style +#define CLEARLOOKS_STYLE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), CLEARLOOKS_TYPE_STYLE, ClearlooksStyle)) +#define CLEARLOOKS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) +#define CLEARLOOKS_IS_STYLE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), CLEARLOOKS_TYPE_STYLE)) +#define CLEARLOOKS_IS_STYLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLEARLOOKS_TYPE_STYLE)) +#define CLEARLOOKS_STYLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLEARLOOKS_TYPE_STYLE, ClearlooksStyleClass)) + +typedef enum +{ + CL_BORDER_UPPER = 0, + CL_BORDER_LOWER, + CL_BORDER_UPPER_ACTIVE, + CL_BORDER_LOWER_ACTIVE, + CL_BORDER_COUNT +} ClBorderColorType; + +typedef enum +{ + CL_SCROLLBUTTON_BEGIN = 0, + CL_SCROLLBUTTON_END, + CL_SCROLLBUTTON_OTHER +} ClScrollButtonType; + +struct _ClearlooksStyle +{ + GtkStyle parent_instance; + + GdkColor shade[9]; + + GdkColor spot_color; + GdkColor spot1; + GdkColor spot2; + GdkColor spot3; + + GdkColor border[CL_BORDER_COUNT]; + + /* from light to dark */ + GdkGC *shade_gc[9]; + GdkGC *border_gc[CL_BORDER_COUNT]; + + GdkGC *spot1_gc; + GdkGC *spot2_gc; + GdkGC *spot3_gc; + + GdkColor inset_light[5]; + GdkColor inset_dark[5]; + + GdkColor button_g1[5]; + GdkColor button_g2[5]; + GdkColor button_g3[5]; + GdkColor button_g4[5]; + + GdkColor listview_bg[5]; + + GdkPixmap *radio_pixmap_nonactive[5]; + GdkPixmap *radio_pixmap_active[5]; + GdkPixmap *radio_pixmap_inconsistent[5]; + GdkBitmap *radio_pixmap_mask; /* All masks are the same */ + + GdkPixmap *check_pixmap_nonactive[5]; + GdkPixmap *check_pixmap_active[5]; + GdkPixmap *check_pixmap_inconsistent[5]; + + gboolean sunkenmenubar:1; + + guint8 progressbarstyle; + guint8 menubarstyle; + guint8 menuitemstyle; + guint8 listviewitemstyle; +}; + +struct _ClearlooksStyleClass +{ + GtkStyleClass parent_class; +}; + +void clearlooks_style_register_type (GTypeModule *module); diff --git a/libs/clearlooks-older/clearlooks_theme_main.c b/libs/clearlooks-older/clearlooks_theme_main.c new file mode 100644 index 0000000000..5356f915dd --- /dev/null +++ b/libs/clearlooks-older/clearlooks_theme_main.c @@ -0,0 +1,37 @@ +#include <gmodule.h> +#include <gtk/gtk.h> + +#include "clearlooks_style.h" +#include "clearlooks_rc_style.h" + +G_MODULE_EXPORT void +theme_init (GTypeModule *module) +{ + clearlooks_rc_style_register_type (module); + clearlooks_style_register_type (module); + printf("theme_init() called from internal clearlooks engine\n"); +} + +G_MODULE_EXPORT void +theme_exit (void) +{ +} + +G_MODULE_EXPORT GtkRcStyle * +theme_create_rc_style (void) +{ + return GTK_RC_STYLE (g_object_new (CLEARLOOKS_TYPE_RC_STYLE, NULL)); +} + +/* The following function will be called by GTK+ when the module + * is loaded and checks to see if we are compatible with the + * version of GTK+ that loads us. + */ +G_MODULE_EXPORT const gchar* g_module_check_init (GModule *module); +const gchar* +g_module_check_init (GModule *module) +{ + return gtk_check_version (GTK_MAJOR_VERSION, + GTK_MINOR_VERSION, + GTK_MICRO_VERSION - GTK_INTERFACE_AGE); +} diff --git a/libs/clearlooks-older/cpdll.sh b/libs/clearlooks-older/cpdll.sh new file mode 100755 index 0000000000..fb101d52a0 --- /dev/null +++ b/libs/clearlooks-older/cpdll.sh @@ -0,0 +1,2 @@ +mkdir engines +cp libclearlooks.so engines diff --git a/libs/clearlooks-older/support.c b/libs/clearlooks-older/support.c new file mode 100644 index 0000000000..358c7f43fb --- /dev/null +++ b/libs/clearlooks-older/support.c @@ -0,0 +1,981 @@ +#include "support.h" + +/* #define ALWAYS_DITHER_GRADIENTS */ + +GtkTextDirection +get_direction (GtkWidget *widget) +{ + GtkTextDirection dir; + + if (widget) + dir = gtk_widget_get_direction (widget); + else + dir = GTK_TEXT_DIR_LTR; + + return dir; +} + +GdkPixbuf * +generate_bit (unsigned char alpha[], GdkColor *color, double mult) +{ + guint r, g, b; + GdkPixbuf *pixbuf; + unsigned char *pixels; + int w, h, rs; + int x, y; + + r = (color->red >> 8) * mult; + r = MIN(r, 255); + g = (color->green >> 8) * mult; + g = MIN(g, 255); + b = (color->blue >> 8) * mult; + b = MIN(b, 255); + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, RADIO_SIZE, RADIO_SIZE); + + w = gdk_pixbuf_get_width (pixbuf); + h = gdk_pixbuf_get_height (pixbuf); + rs = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + + for (y=0; y < h; y++) + { + for (x=0; x < w; x++) + { + pixels[y*rs + x*4 + 0] = r; + pixels[y*rs + x*4 + 1] = g; + pixels[y*rs + x*4 + 2] = b; + if (alpha) + pixels[y*rs + x*4 + 3] = alpha[y*w + x]; + else + pixels[y*rs + x*4 + 3] = 255; + } + } + + return pixbuf; +} + +#define CLAMP_UCHAR(v) ((guchar) (CLAMP (((int)v), (int)0, (int)255))) + +GdkPixbuf * +colorize_bit (unsigned char *bit, + unsigned char *alpha, + GdkColor *new_color) +{ + GdkPixbuf *pixbuf; + double intensity; + int x, y; + const guchar *src, *asrc; + guchar *dest; + int dest_rowstride; + int width, height; + guchar *dest_pixels; + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, RADIO_SIZE, RADIO_SIZE); + + if (pixbuf == NULL) + return NULL; + + dest_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + dest_pixels = gdk_pixbuf_get_pixels (pixbuf); + + for (y = 0; y < RADIO_SIZE; y++) + { + src = bit + y * RADIO_SIZE; + asrc = alpha + y * RADIO_SIZE; + dest = dest_pixels + y * dest_rowstride; + + for (x = 0; x < RADIO_SIZE; x++) + { + double dr, dg, db; + + intensity = (src[x] + 0 )/ 255.0; + + if (intensity <= 0.5) + { + /* Go from black at intensity = 0.0 to new_color at intensity = 0.5 */ + dr = (new_color->red * intensity * 2.0) / 65535.0; + dg = (new_color->green * intensity * 2.0) / 65535.0; + db = (new_color->blue * intensity * 2.0) / 65535.0; + } + else + { + /* Go from new_color at intensity = 0.5 to white at intensity = 1.0 */ + dr = (new_color->red + (65535 - new_color->red) * (intensity - 0.5) * 2.0) / 65535.0; + dg = (new_color->green + (65535 - new_color->green) * (intensity - 0.5) * 2.0) / 65535.0; + db = (new_color->blue + (65535 - new_color->blue) * (intensity - 0.5) * 2.0) / 65535.0; + } + + dest[0] = CLAMP_UCHAR (255 * dr); + dest[1] = CLAMP_UCHAR (255 * dg); + dest[2] = CLAMP_UCHAR (255 * db); + + dest[3] = asrc[x]; + dest += 4; + } + } + + return pixbuf; +} + +GdkPixmap * +pixbuf_to_pixmap (GtkStyle *style, + GdkPixbuf *pixbuf, + GdkScreen *screen) +{ + GdkGC *tmp_gc; + GdkPixmap *pixmap; + + pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + style->depth); + + gdk_drawable_set_colormap (pixmap, style->colormap); + + tmp_gc = gdk_gc_new (pixmap); + + gdk_pixbuf_render_to_drawable (pixbuf, pixmap, tmp_gc, 0, 0, 0, 0, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + + gdk_gc_unref (tmp_gc); + + return pixmap; +} + + +void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b) +{ + gdouble min; + gdouble max; + gdouble red; + gdouble green; + gdouble blue; + gdouble h, l, s; + gdouble delta; + + red = *r; + green = *g; + blue = *b; + + if (red > green) + { + if (red > blue) + max = red; + else + max = blue; + + if (green < blue) + min = green; + else + min = blue; + } + else + { + if (green > blue) + max = green; + else + max = blue; + + if (red < blue) + min = red; + else + min = blue; + } + + l = (max + min) / 2; + s = 0; + h = 0; + + if (max != min) + { + if (l <= 0.5) + s = (max - min) / (max + min); + else + s = (max - min) / (2 - max - min); + + delta = max -min; + if (red == max) + h = (green - blue) / delta; + else if (green == max) + h = 2 + (blue - red) / delta; + else if (blue == max) + h = 4 + (red - green) / delta; + + h *= 60; + if (h < 0.0) + h += 360; + } + + *r = h; + *g = l; + *b = s; +} + +void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s) +{ + gdouble hue; + gdouble lightness; + gdouble saturation; + gdouble m1, m2; + gdouble r, g, b; + + lightness = *l; + saturation = *s; + + if (lightness <= 0.5) + m2 = lightness * (1 + saturation); + else + m2 = lightness + saturation - lightness * saturation; + + m1 = 2 * lightness - m2; + + if (saturation == 0) + { + *h = lightness; + *l = lightness; + *s = lightness; + } + else + { + hue = *h + 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + r = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + r = m2; + else if (hue < 240) + r = m1 + (m2 - m1) * (240 - hue) / 60; + else + r = m1; + + hue = *h; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + g = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + g = m2; + else if (hue < 240) + g = m1 + (m2 - m1) * (240 - hue) / 60; + else + g = m1; + + hue = *h - 120; + while (hue > 360) + hue -= 360; + while (hue < 0) + hue += 360; + + if (hue < 60) + b = m1 + (m2 - m1) * hue / 60; + else if (hue < 180) + b = m2; + else if (hue < 240) + b = m1 + (m2 - m1) * (240 - hue) / 60; + else + b = m1; + + *h = r; + *l = g; + *s = b; + } +} + +void +shade (GdkColor * a, GdkColor * b, float k) +{ + gdouble red; + gdouble green; + gdouble blue; + + red = (gdouble) a->red / 65535.0; + green = (gdouble) a->green / 65535.0; + blue = (gdouble) a->blue / 65535.0; + + rgb_to_hls (&red, &green, &blue); + + green *= k; + if (green > 1.0) + green = 1.0; + else if (green < 0.0) + green = 0.0; + + blue *= k; + if (blue > 1.0) + blue = 1.0; + else if (blue < 0.0) + blue = 0.0; + + hls_to_rgb (&red, &green, &blue); + + b->red = red * 65535.0; + b->green = green * 65535.0; + b->blue = blue * 65535.0; +} + + +/**************************************************************************/ + +void +arrow_draw_hline (GdkWindow *window, + GdkGC *gc, + int x1, + int x2, + int y, + gboolean last) +{ + if (x2 - x1 < 7 && !last) /* 7 to get garretts pixels, otherwise 6 */ + { + gdk_draw_line (window, gc, x1, y, x2, y); + } + else if (last) + { + /* we don't draw "spikes" for very small arrows */ + if (x2 - x1 <= 9) + { + /*gdk_draw_line (window, gc, x1+1, y, x1+1, y); + gdk_draw_line (window, gc, x2-1, y, x2-1, y);*/ + } + else + { + gdk_draw_line (window, gc, x1+2, y, x1+2, y); + gdk_draw_line (window, gc, x2-2, y, x2-2, y); + } + } + else + { + gdk_draw_line (window, gc, x1, y, x1+2, y); + gdk_draw_line (window, gc, x2-2, y, x2, y); + } +} + +void +arrow_draw_vline (GdkWindow *window, + GdkGC *gc, + int y1, + int y2, + int x, + gboolean last) +{ + if (y2 - y1 < 7 && !last) /* 7 to get garretts pixels */ + gdk_draw_line (window, gc, x, y1, x, y2); + else if (last) + { + /* we don't draw "spikes" for very small arrows */ + if (y2 - y1 > 9) { + gdk_draw_line (window, gc, x, y1+2, x, y1+2); + gdk_draw_line (window, gc, x, y2-2, x, y2-2); + } + } + else + { + gdk_draw_line (window, gc, x, y1, x, y1+2); + gdk_draw_line (window, gc, x, y2-2, x, y2); + } +} + + + +void +draw_arrow (GdkWindow *window, + GdkGC *gc, + GdkRectangle *area, + GtkArrowType arrow_type, + gint x, + gint y, + gint width, + gint height) +{ + gint i, j; + + if (area) + gdk_gc_set_clip_rectangle (gc, area); + + if (arrow_type == GTK_ARROW_DOWN) + { + for (i = 0, j = -1; i < height; i++, j++) + arrow_draw_hline (window, gc, x + j, x + width - j - 1, y + i, i == 0); + + } + else if (arrow_type == GTK_ARROW_UP) + { + for (i = height - 1, j = -1; i >= 0; i--, j++) + arrow_draw_hline (window, gc, x + j, x + width - j - 1, y + i, i == height - 1); + } + else if (arrow_type == GTK_ARROW_LEFT) + { + for (i = width - 1, j = -1; i >= 0; i--, j++) + arrow_draw_vline (window, gc, y + j, y + height - j - 1, x + i, i == width - 1); + } + else if (arrow_type == GTK_ARROW_RIGHT) + { + for (i = 0, j = -1; i < width; i++, j++) + arrow_draw_vline (window, gc, y + j, y + height - j - 1, x + i, i == 0); + } + + if (area) + gdk_gc_set_clip_rectangle (gc, NULL); +} + +void +calculate_arrow_geometry (GtkArrowType arrow_type, + gint *x, + gint *y, + gint *width, + gint *height) +{ + gint w = *width; + gint h = *height; + + switch (arrow_type) + { + case GTK_ARROW_UP: + case GTK_ARROW_DOWN: + w += (w % 2) - 1; + h = (w / 2 + 1) + 1; + + if (h > *height) + { + h = *height; + w = 2 * (h - 1) - 1; + } + + if (arrow_type == GTK_ARROW_DOWN) + { + if (*height % 2 == 1 || h % 2 == 0) + *height += 1; + } + else + { + if (*height % 2 == 0 || h % 2 == 0) + *height -= 1; + } + break; + + case GTK_ARROW_RIGHT: + case GTK_ARROW_LEFT: + h += (h % 2) - 1; + w = (h / 2 + 1) + 1; + + if (w > *width) + { + w = *width; + h = 2 * (w - 1) - 1; + } + + if (arrow_type == GTK_ARROW_RIGHT) + { + if (*width % 2 == 1 || w % 2 == 0) + *width += 1; + } + else + { + if (*width % 2 == 0 || w % 2 == 0) + *width -= 1; + } + break; + + default: + /* should not be reached */ + break; + } + + *x += (*width - w) / 2; + *y += (*height - h) / 2; + *height = h; + *width = w; +} + + +void gtk_treeview_get_header_index (GtkTreeView *tv, GtkWidget *header, + gint *column_index, gint *columns, +gboolean *resizable) +{ + GList *list; + *column_index = *columns = 0; + list = gtk_tree_view_get_columns (tv); + + do + { + GtkTreeViewColumn *column = GTK_TREE_VIEW_COLUMN(list->data); + if ( column->button == header ) + { + *column_index = *columns; + *resizable = column->resizable; + } + if ( column->visible ) + (*columns)++; + } while ((list = g_list_next(list))); +} + +void gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns) +{ + *columns = clist->columns; + int i; + + for (i=0; i<*columns; i++) + { + if (clist->column[i].button == button) + { + *column_index = i; + break; + } + } +} + +gboolean +sanitize_size (GdkWindow *window, + gint *width, + gint *height) +{ + gboolean set_bg = FALSE; + + if ((*width == -1) && (*height == -1)) + { + set_bg = GDK_IS_WINDOW (window); + gdk_window_get_size (window, width, height); + } + else if (*width == -1) + gdk_window_get_size (window, width, NULL); + else if (*height == -1) + gdk_window_get_size (window, NULL, height); + + return set_bg; +} + +static GtkRequisition default_option_indicator_size = { 7, 13 }; +static GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 }; + +void +option_menu_get_props (GtkWidget *widget, + GtkRequisition *indicator_size, + GtkBorder *indicator_spacing) +{ + GtkRequisition *tmp_size = NULL; + GtkBorder *tmp_spacing = NULL; + + if (widget) + gtk_widget_style_get (widget, "indicator_size", &tmp_size, + "indicator_spacing", &tmp_spacing, NULL); + + if (tmp_size) + { + *indicator_size = *tmp_size; + g_free (tmp_size); + } + else + *indicator_size = default_option_indicator_size; + + if (tmp_spacing) + { + *indicator_spacing = *tmp_spacing; + g_free (tmp_spacing); + } + else + *indicator_spacing = default_option_indicator_spacing; +} + +GtkWidget *special_get_ancestor(GtkWidget * widget, + GType widget_type) +{ + g_return_val_if_fail(GTK_IS_WIDGET(widget), NULL); + + while (widget && widget->parent + && !g_type_is_a(GTK_WIDGET_TYPE(widget->parent), + widget_type)) + widget = widget->parent; + + if (! + (widget && widget->parent + && g_type_is_a(GTK_WIDGET_TYPE(widget->parent), widget_type))) + return NULL; + + return widget; +} + +/* Dithered Gradient Buffers */ +static void +internel_image_buffer_free_pixels (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + +static GdkPixbuf* +internal_image_buffer_new (gint width, gint height) +{ + guchar *buf; + int rowstride; + + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + rowstride = width * 3; + + buf = g_try_malloc (height * rowstride); + + if (!buf) + return NULL; + + return gdk_pixbuf_new_from_data(buf, GDK_COLORSPACE_RGB, + FALSE, 8, + width, height, rowstride, + internel_image_buffer_free_pixels, NULL); +} + +static void +internal_color_get_as_uchars(GdkColor *color, + guchar *red, + guchar *green, + guchar *blue) +{ + *red = (guchar) (color->red / 256.0); + *green = (guchar) (color->green / 256.0); + *blue = (guchar) (color->blue / 256.0); +} + +static GdkPixbuf* +internal_create_horizontal_gradient_image_buffer (gint width, gint height, + GdkColor *from, + GdkColor *to) +{ + int i; + long r, g, b, dr, dg, db; + GdkPixbuf* buffer; + guchar *ptr; + guchar *pixels; + guchar r0, g0, b0; + guchar rf, gf, bf; + int rowstride; + + buffer = internal_image_buffer_new (width, height); + + if (buffer == NULL) + return NULL; + + pixels = gdk_pixbuf_get_pixels (buffer); + ptr = pixels; + rowstride = gdk_pixbuf_get_rowstride (buffer); + + internal_color_get_as_uchars(from, &r0, &g0, &b0); + internal_color_get_as_uchars(to, &rf, &gf, &bf); + + r = r0 << 16; + g = g0 << 16; + b = b0 << 16; + + dr = ((rf-r0)<<16)/width; + dg = ((gf-g0)<<16)/width; + db = ((bf-b0)<<16)/width; + + /* render the first line */ + for (i=0; i<width; i++) + { + *(ptr++) = (guchar)(r>>16); + *(ptr++) = (guchar)(g>>16); + *(ptr++) = (guchar)(b>>16); + + r += dr; + g += dg; + b += db; + } + + /* copy the first line to the other lines */ + for (i=1; i<height; i++) + { + memcpy (&(pixels[i*rowstride]), pixels, rowstride); + } + + return buffer; +} + +static GdkPixbuf* +internal_create_vertical_gradient_image_buffer (gint width, gint height, + GdkColor *from, + GdkColor *to) +{ + gint i, j, max_block, last_block; + long r, g, b, dr, dg, db; + GdkPixbuf *buffer; + + guchar *ptr; + guchar point[4]; + + guchar r0, g0, b0; + guchar rf, gf, bf; + + gint rowstride; + guchar *pixels; + + buffer = internal_image_buffer_new (width, height); + + if (buffer == NULL) + return NULL; + + pixels = gdk_pixbuf_get_pixels (buffer); + rowstride = gdk_pixbuf_get_rowstride (buffer); + + internal_color_get_as_uchars(from, &r0, &g0, &b0); + internal_color_get_as_uchars(to, &rf, &gf, &bf); + + r = r0<<16; + g = g0<<16; + b = b0<<16; + + dr = ((rf-r0)<<16)/height; + dg = ((gf-g0)<<16)/height; + db = ((bf-b0)<<16)/height; + + max_block = width/2; + + for (i=0; i < height; i++) + { + ptr = pixels + i * rowstride; + + ptr[0] = r>>16; + ptr[1] = g>>16; + ptr[2] = b>>16; + + if (width > 1) + { + last_block = 0; + + for (j=1; j <= max_block; j *= 2) + { + memcpy (&(ptr[j*3]), ptr, j*3); + + if ((j*2) >= max_block) + { + last_block = j*2; + } + } + + if ((last_block < width) && (last_block > 0)) + { + memcpy (&(ptr[last_block*3]), ptr, (width - last_block)*3); + } + } + + r += dr; + g += dg; + b += db; + } + + return buffer; +} + +void +draw_vgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *left_color, GdkColor *right_color) +{ + #ifndef ALWAYS_DITHER_GRADIENTS + gboolean dither = ((style->depth > 0) && (style->depth <= 16)); + #endif + + if ((width <= 0) || (height <= 0)) + return; + + if ( left_color == NULL || right_color == NULL ) + { + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + return; + } + + #ifndef ALWAYS_DITHER_GRADIENTS + if (dither) + #endif + { + GdkPixbuf *image_buffer = NULL; + + image_buffer = internal_create_horizontal_gradient_image_buffer (width, height, left_color, right_color); + + if (image_buffer) + { + gdk_draw_pixbuf(drawable, gc, image_buffer, 0, 0, x, y, width, height, GDK_RGB_DITHER_MAX, 0, 0); + + g_object_unref(image_buffer); + } + } + #ifndef ALWAYS_DITHER_GRADIENTS + else + { + int i; + GdkColor col; + int dr, dg, db; + GdkGCValues old_values; + + gdk_gc_get_values (gc, &old_values); + + if (left_color == right_color ) + { + col = *left_color; + gdk_rgb_find_color (style->colormap, &col); + gdk_gc_set_foreground (gc, &col); + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + gdk_gc_set_foreground (gc, &old_values.foreground); + return; + } + + col = *left_color; + dr = (right_color->red - left_color->red) / width; + dg = (right_color->green - left_color->green) / width; + db = (right_color->blue - left_color->blue) / width; + + for (i = 0; i < width; i++) + { + gdk_rgb_find_color (style->colormap, &col); + + gdk_gc_set_foreground (gc, &col); + gdk_draw_line (drawable, gc, x + i, y, x + i, y + height - 1); + + col.red += dr; + col.green += dg; + col.blue += db; + } + + gdk_gc_set_foreground (gc, &old_values.foreground); + } + #endif +} + +void +draw_hgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *top_color, GdkColor *bottom_color) +{ + #ifndef ALWAYS_DITHER_GRADIENTS + gboolean dither = ((style->depth > 0) && (style->depth <= 16)); + #endif + + if ((width <= 0) || (height <= 0)) + return; + + #ifndef ALWAYS_DITHER_GRADIENTS + if (dither) + #endif + { + GdkPixbuf *image_buffer = NULL; + + image_buffer = internal_create_vertical_gradient_image_buffer (width, height, top_color, bottom_color); + + if (image_buffer) + { + gdk_draw_pixbuf(drawable, gc, image_buffer, 0, 0, x, y, width, height, GDK_RGB_DITHER_MAX, 0, 0); + + g_object_unref(image_buffer); + } + } + #ifndef ALWAYS_DITHER_GRADIENTS + else + { + int i; + GdkColor col; + int dr, dg, db; + GdkGCValues old_values; + + gdk_gc_get_values (gc, &old_values); + + if (top_color == bottom_color ) + { + col = *top_color; + gdk_rgb_find_color (style->colormap, &col); + gdk_gc_set_foreground (gc, &col); + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + gdk_gc_set_foreground (gc, &old_values.foreground); + return; + } + + col = *top_color; + dr = (bottom_color->red - top_color->red) / height; + dg = (bottom_color->green - top_color->green) / height; + db = (bottom_color->blue - top_color->blue) / height; + + for (i = 0; i < height; i++) + { + gdk_rgb_find_color (style->colormap, &col); + + gdk_gc_set_foreground (gc, &col); + gdk_draw_line (drawable, gc, x, y + i, x + width - 1, y + i); + + col.red += dr; + col.green += dg; + col.blue += db; + } + + gdk_gc_set_foreground (gc, &old_values.foreground); + } + #endif +} + +void blend (GdkColormap *colormap, + GdkColor *a, GdkColor *b, GdkColor *c, int alpha) +{ + int inAlpha = 100-alpha; + c->red = (a->red * alpha + b->red * inAlpha) / 100; + c->green = (a->green * alpha + b->green * inAlpha) / 100; + c->blue = (a->blue * alpha + b->blue * inAlpha) / 100; + + gdk_rgb_find_color (colormap, c); +} + +GtkWidget *get_parent_window (GtkWidget *widget) +{ + GtkWidget *parent = widget->parent; + + while (parent && GTK_WIDGET_NO_WINDOW (parent)) + parent = parent->parent; + + return parent; +} + +GdkColor *get_parent_bgcolor (GtkWidget *widget) +{ + GtkWidget *parent = get_parent_window (widget); + + if (parent && parent->style) + return &parent->style->bg[GTK_STATE_NORMAL]; + + return NULL; +} + +GtkWidget * +find_combo_box_widget (GtkWidget * widget) +{ + GtkWidget *result = NULL; + + if (widget && !GTK_IS_COMBO_BOX_ENTRY (widget)) + { + if (GTK_IS_COMBO_BOX (widget)) + result = widget; + else + result = find_combo_box_widget(widget->parent); + } + + return result; +} + +gboolean +is_combo_box (GtkWidget * widget) +{ + return (find_combo_box_widget(widget) != NULL); +} diff --git a/libs/clearlooks-older/support.h b/libs/clearlooks-older/support.h new file mode 100644 index 0000000000..a1430b40d0 --- /dev/null +++ b/libs/clearlooks-older/support.h @@ -0,0 +1,110 @@ +#include <gtk/gtk.h> +#include <math.h> +#include <string.h> + +/* GTK 2.2 compatibility */ +#ifndef GTK_IS_COMBO_BOX_ENTRY + #define GTK_IS_COMBO_BOX_ENTRY(x) 0 +#endif +#ifndef GTK_IS_COMBO_BOX + #define GTK_IS_COMBO_BOX(x) 0 +#endif + +#define RADIO_SIZE 13 +#define CHECK_SIZE 13 + +GtkTextDirection +get_direction (GtkWidget *widget); + +GdkPixbuf * +generate_bit (unsigned char alpha[], + GdkColor *color, + double mult); + +GdkPixbuf * +colorize_bit (unsigned char *bit, + unsigned char *alpha, + GdkColor *new_color); + +GdkPixmap * +pixbuf_to_pixmap (GtkStyle *style, + GdkPixbuf *pixbuf, + GdkScreen *screen); + +gboolean +sanitize_size (GdkWindow *window, + gint *width, + gint *height); + +void +rgb_to_hls (gdouble *r, + gdouble *g, + gdouble *b); + +void +hls_to_rgb (gdouble *h, + gdouble *l, + gdouble *s); + +void +shade (GdkColor * a, GdkColor * b, float k); + +void +draw_hgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *top_color, GdkColor *bottom_color); + +void +draw_vgradient (GdkDrawable *drawable, GdkGC *gc, GtkStyle *style, + int x, int y, int width, int height, + GdkColor *left_color, GdkColor *right_color); + +void +arrow_draw_hline (GdkWindow *window, + GdkGC *gc, + int x1, + int x2, + int y, + gboolean last); + +void +arrow_draw_vline (GdkWindow *window, + GdkGC *gc, + int y1, + int y2, + int x, + gboolean last); + +void +draw_arrow (GdkWindow *window, + GdkGC *gc, + GdkRectangle *area, + GtkArrowType arrow_type, + gint x, + gint y, + gint width, + gint height); + +void +calculate_arrow_geometry (GtkArrowType arrow_type, + gint *x, + gint *y, + gint *width, + gint *height); + +GtkWidget *special_get_ancestor(GtkWidget * widget, + GType widget_type); + +void blend (GdkColormap *colormap, + GdkColor *a, GdkColor *b, GdkColor *c, int alpha); + +GtkWidget *get_parent_window (GtkWidget *widget); + +GdkColor *get_parent_bgcolor (GtkWidget *widget); + +gboolean is_combo_box (GtkWidget * widget); + +GtkWidget *find_combo_box_widget (GtkWidget * widget); + +void gtk_clist_get_header_index (GtkCList *clist, GtkWidget *button, + gint *column_index, gint *columns); diff --git a/libs/clearlooks/clearlooks_draw.h b/libs/clearlooks/clearlooks_draw.h deleted file mode 100644 index 71d3b4ae68..0000000000 --- a/libs/clearlooks/clearlooks_draw.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CLEARLOOKS_DRAW_H -#define CLEARLOOKS_DRAW_H - -#include "clearlooks_types.h" -#include "clearlooks_style.h" - -#include <gtk/gtk.h> -#include <gdk/gdk.h> - -#include <cairo.h> - -GE_INTERNAL void clearlooks_register_style_classic (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants); -GE_INTERNAL void clearlooks_register_style_glossy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants); -GE_INTERNAL void clearlooks_register_style_gummy (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants); -GE_INTERNAL void clearlooks_register_style_inverted (ClearlooksStyleFunctions *functions, ClearlooksStyleConstants *constants); - -/* Fallback focus function */ -GE_INTERNAL void clearlooks_draw_focus (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const FocusParameters *focus, - int x, int y, int width, int height); - -#endif /* CLEARLOOKS_DRAW_H */ diff --git a/libs/clearlooks/clearlooks_types.h b/libs/clearlooks/clearlooks_types.h deleted file mode 100644 index 5d5757f95a..0000000000 --- a/libs/clearlooks/clearlooks_types.h +++ /dev/null @@ -1,510 +0,0 @@ -#ifndef CLEARLOOKS_TYPES_H -#define CLEARLOOKS_TYPES_H - -#include <ge-support.h> - -typedef unsigned char boolean; -typedef unsigned char uint8; -typedef struct _ClearlooksStyleFunctions ClearlooksStyleFunctions; -typedef struct _ClearlooksStyleConstants ClearlooksStyleConstants; - -typedef enum -{ - CL_STYLE_CLASSIC = 0, - CL_STYLE_GLOSSY = 1, - CL_STYLE_INVERTED = 2, - CL_STYLE_GUMMY = 3, - CL_NUM_STYLES = 4 -} ClearlooksStyles; - -typedef enum -{ - CL_STATE_NORMAL, - CL_STATE_ACTIVE, - CL_STATE_SELECTED, - CL_STATE_INSENSITIVE -} ClearlooksStateType; - -typedef enum -{ - CL_JUNCTION_NONE = 0, - CL_JUNCTION_BEGIN = 1, - CL_JUNCTION_END = 2 -} ClearlooksJunction; - -typedef enum -{ - CL_STEPPER_UNKNOWN = 0, - CL_STEPPER_A = 1, - CL_STEPPER_B = 2, - CL_STEPPER_C = 4, - CL_STEPPER_D = 8 -} ClearlooksStepper; - -typedef enum -{ - CL_ORDER_FIRST = 1 << 0, - CL_ORDER_LAST = 1 << 1, -} ClearlooksOrder; - -typedef enum -{ - CL_CONT_NONE = 0, - CL_CONT_LEFT = 1 << 0, - CL_CONT_RIGHT = 1 << 1 -} ClearlooksContinue; - -typedef enum -{ - CL_ORIENTATION_LEFT_TO_RIGHT, - CL_ORIENTATION_RIGHT_TO_LEFT, - CL_ORIENTATION_BOTTOM_TO_TOP, - CL_ORIENTATION_TOP_TO_BOTTOM -} ClearlooksOrientation; - -typedef enum -{ - CL_GAP_LEFT, - CL_GAP_RIGHT, - CL_GAP_TOP, - CL_GAP_BOTTOM -} ClearlooksGapSide; - -typedef enum -{ - CL_SHADOW_NONE, - CL_SHADOW_IN, - CL_SHADOW_OUT, - CL_SHADOW_ETCHED_IN, - CL_SHADOW_ETCHED_OUT -} ClearlooksShadowType; - -typedef enum -{ - CL_HANDLE_TOOLBAR, - CL_HANDLE_SPLITTER -} ClearlooksHandleType; - -typedef enum -{ - CL_ARROW_NORMAL, - CL_ARROW_COMBO -} ClearlooksArrowType; - -typedef enum -{ - CL_FOCUS_BUTTON, - CL_FOCUS_BUTTON_FLAT, - CL_FOCUS_LABEL, - CL_FOCUS_TREEVIEW, - CL_FOCUS_TREEVIEW_HEADER, - CL_FOCUS_TREEVIEW_ROW, - CL_FOCUS_TREEVIEW_DND, - CL_FOCUS_SCALE, - CL_FOCUS_TAB, - CL_FOCUS_COLOR_WHEEL_DARK, - CL_FOCUS_COLOR_WHEEL_LIGHT, - CL_FOCUS_UNKNOWN -} ClearlooksFocusType; - - -typedef enum -{ - CL_DIRECTION_UP, - CL_DIRECTION_DOWN, - CL_DIRECTION_LEFT, - CL_DIRECTION_RIGHT -} ClearlooksDirection; - -typedef enum -{ - CL_PROGRESSBAR_CONTINUOUS, - CL_PROGRESSBAR_DISCRETE -} ClearlooksProgressBarStyle; - -typedef enum -{ - CL_WINDOW_EDGE_NORTH_WEST, - CL_WINDOW_EDGE_NORTH, - CL_WINDOW_EDGE_NORTH_EAST, - CL_WINDOW_EDGE_WEST, - CL_WINDOW_EDGE_EAST, - CL_WINDOW_EDGE_SOUTH_WEST, - CL_WINDOW_EDGE_SOUTH, - CL_WINDOW_EDGE_SOUTH_EAST -} ClearlooksWindowEdge; - -typedef struct -{ - double x; - double y; - double width; - double height; -} ClearlooksRectangle; - -typedef struct -{ - CairoColor fg[5]; - CairoColor bg[5]; - CairoColor base[5]; - CairoColor text[5]; - - CairoColor shade[9]; - CairoColor spot[3]; -} ClearlooksColors; - -typedef struct -{ - boolean active; - boolean prelight; - boolean disabled; - boolean focus; - boolean is_default; - boolean ltr; - boolean enable_shadow; - - gfloat radius; - - ClearlooksStateType state_type; - - uint8 corners; - uint8 xthickness; - uint8 ythickness; - - CairoColor parentbg; - - ClearlooksStyleFunctions *style_functions; - ClearlooksStyleConstants *style_constants; -} WidgetParameters; - -typedef struct -{ - ClearlooksFocusType type; - ClearlooksContinue continue_side; - CairoColor color; - boolean has_color; - gint line_width; - gint padding; - guint8* dash_list; - boolean interior; -} FocusParameters; - -typedef struct -{ - boolean lower; - boolean horizontal; - boolean fill_level; -} SliderParameters; - -typedef struct -{ - ClearlooksOrientation orientation; - boolean pulsing; - float value; -} ProgressBarParameters; - -typedef struct -{ - int linepos; -} OptionMenuParameters; - -typedef struct -{ - ClearlooksShadowType shadow; - ClearlooksGapSide gap_side; - int gap_x; - int gap_width; - const CairoColor *border; /* maybe changes this to some other hint ... */ -} FrameParameters; - -typedef struct -{ - ClearlooksGapSide gap_side; - FocusParameters focus; -} TabParameters; - -typedef struct -{ - CairoCorners corners; - ClearlooksShadowType shadow; -} ShadowParameters; - -typedef struct -{ - boolean horizontal; -} SeparatorParameters; - -typedef struct -{ - ClearlooksOrder order; /* XXX: rename to position */ - boolean resizable; -} ListViewHeaderParameters; - -typedef struct -{ - CairoColor color; - ClearlooksJunction junction; /* On which sides the slider junctions */ - boolean horizontal; - boolean has_color; -} ScrollBarParameters; - -typedef struct -{ - ClearlooksHandleType type; - boolean horizontal; -} HandleParameters; - -typedef struct -{ - ClearlooksStepper stepper; /* Which stepper to draw */ -} ScrollBarStepperParameters; - -typedef struct -{ - ClearlooksWindowEdge edge; -} ResizeGripParameters; - -typedef struct -{ - int style; -} MenuBarParameters; - -typedef struct -{ - ClearlooksShadowType shadow_type; - boolean in_cell; - boolean in_menu; -} CheckboxParameters; - -typedef struct -{ - ClearlooksArrowType type; - ClearlooksDirection direction; -} ArrowParameters; - -typedef struct -{ - int style; - boolean topmost; -} ToolbarParameters; - -struct _ClearlooksStyleConstants -{ - gdouble topleft_highlight_shade; - gdouble topleft_highlight_alpha; -}; - -struct _ClearlooksStyleFunctions -{ - void (*draw_top_left_highlight) (cairo_t *cr, - const CairoColor *color, - const WidgetParameters *params, - int x, int y, int width, int height, - gdouble radius, - CairoCorners corners); - - void (*draw_button) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_scale_trough) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const SliderParameters *slider, - int x, int y, int width, int height); - - void (*draw_progressbar_trough) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_progressbar_fill) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ProgressBarParameters *progressbar, - int x, int y, int width, int height, gint offset); - - void (*draw_slider_button) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const SliderParameters *slider, - int x, int y, int width, int height); - - void (*draw_entry) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_spinbutton) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_spinbutton_down) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_optionmenu) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const OptionMenuParameters *optionmenu, - int x, int y, int width, int height); - - void (*draw_inset) (cairo_t *cr, - const CairoColor *bg_color, - double x, double y, double w, double h, - double radius, uint8 corners); - - void (*draw_menubar) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const MenuBarParameters *menubar, - int x, int y, int width, int height); - - void (*draw_tab) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const TabParameters *tab, - int x, int y, int width, int height); - - void (*draw_frame) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const FrameParameters *frame, - int x, int y, int width, int height); - - void (*draw_separator) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const SeparatorParameters *separator, - int x, int y, int width, int height); - - void (*draw_menu_item_separator) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const SeparatorParameters *separator, - int x, int y, int width, int height); - - void (*draw_list_view_header) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ListViewHeaderParameters *header, - int x, int y, int width, int height); - - void (*draw_toolbar) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ToolbarParameters *toolbar, - int x, int y, int width, int height); - - void (*draw_menuitem) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_menubaritem) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_selected_cell) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_scrollbar_stepper) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ScrollBarParameters *scrollbar, - const ScrollBarStepperParameters *stepper, - int x, int y, int width, int height); - - void (*draw_scrollbar_slider) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ScrollBarParameters *scrollbar, - int x, int y, int width, int height); - - void (*draw_scrollbar_trough) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ScrollBarParameters *scrollbar, - int x, int y, int width, int height); - - void (*draw_statusbar) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_menu_frame) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_tooltip) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_handle) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const HandleParameters *handle, - int x, int y, int width, int height); - - void (*draw_resize_grip) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ResizeGripParameters *grip, - int x, int y, int width, int height); - - void (*draw_arrow) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const ArrowParameters *arrow, - int x, int y, int width, int height); - - void (*draw_focus) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const FocusParameters *focus, - int x, int y, int width, int height); - - void (*draw_checkbox) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const CheckboxParameters *checkbox, - int x, int y, int width, int height); - - void (*draw_radiobutton) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - const CheckboxParameters *checkbox, - int x, int y, int width, int height); - - /* Style internal functions */ - /* XXX: Only used by slider_button, inline it? */ - void (*draw_shadow) (cairo_t *cr, - const ClearlooksColors *colors, - gfloat radius, int width, int height); - - void (*draw_slider) (cairo_t *cr, - const ClearlooksColors *colors, - const WidgetParameters *widget, - int x, int y, int width, int height); - - void (*draw_gripdots) (cairo_t *cr, - const ClearlooksColors *colors, int x, int y, - int width, int height, int xr, int yr, - float contrast); -}; - - -#define CLEARLOOKS_RECTANGLE_SET(rect, _x, _y, _w, _h) (rect).x = (_x); \ - (rect).y = (_y); \ - (rect).width = (_w); \ - (rect).height = (_h); - -#endif /* CLEARLOOKS_TYPES_H */ diff --git a/libs/gtkmm2ext/dndtreeview.cc b/libs/gtkmm2ext/dndtreeview.cc index 2c2e69f6b6..0695dd3281 100644 --- a/libs/gtkmm2ext/dndtreeview.cc +++ b/libs/gtkmm2ext/dndtreeview.cc @@ -29,6 +29,8 @@ using namespace Gtk; using namespace Glib; using namespace Gtkmm2ext; +DnDTreeViewBase::DragData DnDTreeViewBase::drag_data; + DnDTreeViewBase::DnDTreeViewBase () : TreeView () { @@ -47,6 +49,7 @@ DnDTreeViewBase::add_drop_targets (list<TargetEntry>& targets) for (list<TargetEntry>::iterator i = targets.begin(); i != targets.end(); ++i) { draggable.push_back (*i); } + enable_model_drag_source (draggable); enable_model_drag_dest (draggable); } @@ -56,6 +59,7 @@ DnDTreeViewBase::add_object_drag (int column, string type_name) { draggable.push_back (TargetEntry (type_name, TargetFlags(0))); data_column = column; + object_type = type_name; enable_model_drag_source (draggable); enable_model_drag_dest (draggable); diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc index 4ca23b0240..e15a3524db 100644 --- a/libs/gtkmm2ext/gtk_ui.cc +++ b/libs/gtkmm2ext/gtk_ui.cc @@ -65,6 +65,9 @@ UI::UI (string namestr, int *argc, char ***argv) : AbstractUI<UIRequest> (namestr, true) { theMain = new Main (argc, argv); +#ifndef GTK_NEW_TOOLTIP_API + tips = new Tooltips; +#endif _active = false; @@ -95,6 +98,7 @@ UI::UI (string namestr, int *argc, char ***argv) errors->dismiss_button().set_name ("ErrorLogCloseButton"); errors->signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), (Window *) errors)); + errors->set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY); register_thread (pthread_self(), X_("GUI")); @@ -372,7 +376,16 @@ UI::do_request (UIRequest* req) } else if (req->type == SetTip) { - /* XXX need to figure out how this works */ +#ifdef GTK_NEW_TOOLTIP_API + /* even if the installed GTK is up to date, + at present (November 2008) our included + version of gtkmm is not. so use the GTK + API that we've verified has the right function. + */ + gtk_widget_set_tooltip_text (req->widget->gobj(), req->msg); +#else + tips->set_tip (*req->widget, req->msg, ""); +#endif } else { diff --git a/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h b/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h index fbc5ea90ef..085e500f21 100644 --- a/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h +++ b/libs/gtkmm2ext/gtkmm2ext/dndtreeview.h @@ -62,6 +62,21 @@ class DnDTreeViewBase : public Gtk::TreeView std::list<Gtk::TargetEntry> draggable; Gdk::DragAction suggested_action; int data_column; + std::string object_type; + + struct DragData { + Gtk::TreeView* source; + int data_column; + std::string object_type; + }; + + static DragData drag_data; + + void start_object_drag () { + drag_data.source = this; + drag_data.data_column = data_column; + drag_data.object_type = object_type; + } }; template<class DataType> @@ -71,21 +86,26 @@ class DnDTreeView : public DnDTreeViewBase DnDTreeView() {} ~DnDTreeView() {} - sigc::signal<void,std::string,uint32_t,const DataType*> signal_object_drop; + sigc::signal<void,const std::list<DataType>& > signal_drop; void on_drag_data_get(const Glib::RefPtr<Gdk::DragContext>& context, Gtk::SelectionData& selection_data, guint info, guint time) { if (selection_data.get_target() == "GTK_TREE_MODEL_ROW") { - + TreeView::on_drag_data_get (context, selection_data, info, time); - - } else if (data_column >= 0) { - - Gtk::TreeSelection::ListHandle_Path selection = get_selection()->get_selected_rows (); - SerializedObjectPointers<DataType>* sr = serialize_pointers (get_model(), &selection, selection_data.get_target()); - selection_data.set (8, (guchar*)sr, sr->size); + + } else if (selection_data.get_target() == object_type) { + + start_object_drag (); + + /* we don't care about the data passed around by DnD, but + we have to provide something otherwise it will stop. + */ + + guchar c; + selection_data.set (8, (guchar*)&c, 1); } } - + void on_drag_data_received(const Glib::RefPtr<Gdk::DragContext>& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time) { if (suggested_action) { /* this is a drag motion callback. just update the status to @@ -100,64 +120,39 @@ class DnDTreeView : public DnDTreeViewBase TreeView::on_drag_data_received (context, x, y, selection_data, info, time); - } else if (data_column >= 0) { - - /* object D-n-D */ - - const void* data = selection_data.get_data(); - const SerializedObjectPointers<DataType>* sr = reinterpret_cast<const SerializedObjectPointers<DataType> *>(data); - - if (sr) { - signal_object_drop (sr->type, sr->cnt, sr->data); - } + + } else if (selection_data.get_target() == object_type) { + end_object_drag (); + } else { /* some kind of target type added by the app, which will be handled by a signal handler */ } } - private: - - SerializedObjectPointers<DataType>* serialize_pointers (Glib::RefPtr<Gtk::TreeModel> model, - Gtk::TreeSelection::ListHandle_Path* selection, - Glib::ustring type) { - - /* this nasty chunk of code is here because X's DnD protocol (probably other graphics UI's too) - requires that we package up the entire data collection for DnD in a single contiguous region - (so that it can be trivially copied between address spaces). We don't know the type of DataType so - we have to mix-and-match C and C++ programming techniques here to get the right result. - - The C trick is to use the "someType foo[0];" declaration trick to create a zero-sized array at the - end of a SerializedObjectPointers<DataType object. Then we allocate a raw memory buffer that extends - past that array and thus provides space for however many DataType items we actually want to pass - around. - - The C++ trick is to use the placement operator new() syntax to initialize that extra - memory properly. - */ - - uint32_t cnt = selection->size(); - uint32_t sz = (sizeof (DataType) * cnt) + sizeof (SerializedObjectPointers<DataType>); - - char* buf = new char[sz]; - SerializedObjectPointers<DataType>* sr = (SerializedObjectPointers<DataType>*) buf; + /** + * this can be called by the Treeview itself or by some other + * object that wants to get the list of dragged items. + */ - for (uint32_t i = 0; i < cnt; ++i) { - new ((void *) &sr->data[i]) DataType (); - } - - sr->cnt = cnt; - sr->size = sz; - snprintf (sr->type, sizeof (sr->type), "%s", type.c_str()); + void get_object_drag_data (std::list<DataType>& l) { + Glib::RefPtr<Gtk::TreeModel> model = drag_data.source->get_model(); + DataType v; + Gtk::TreeSelection::ListHandle_Path selection = drag_data.source->get_selection()->get_selected_rows (); - cnt = 0; - - for (Gtk::TreeSelection::ListHandle_Path::iterator x = selection->begin(); x != selection->end(); ++x, ++cnt) { - model->get_iter (*x)->get_value (data_column, sr->data[cnt]); + for (Gtk::TreeSelection::ListHandle_Path::iterator x = selection.begin(); x != selection.end(); ++x) { + model->get_iter (*x)->get_value (drag_data.data_column, v); + l.push_back (v); } + } - return sr; + private: + void end_object_drag () { + std::list<DataType> l; + get_object_drag_data (l); + signal_drop (l); } + }; } // namespace diff --git a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h index 22ac517672..89f3413435 100644 --- a/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h +++ b/libs/gtkmm2ext/gtkmm2ext/gtk_ui.h @@ -29,6 +29,9 @@ #include <pthread.h> #include <gtkmm/widget.h> #include <gtkmm/style.h> +#ifndef GTK_NEW_TOOLTIP_API +#include <gtkmm/tooltips.h> +#endif #include <gtkmm/textbuffer.h> #include <gtkmm/main.h> #include <gdkmm/color.h> @@ -149,6 +152,9 @@ class UI : public Receiver, public AbstractUI<UIRequest> static pthread_t gui_thread; bool _active; Gtk::Main *theMain; +#ifndef GTK_NEW_TOOLTIP_API + Gtk::Tooltips *tips; +#endif TextViewer *errors; Glib::RefPtr<Gtk::TextBuffer::Tag> error_ptag; Glib::RefPtr<Gtk::TextBuffer::Tag> error_mtag; diff --git a/libs/gtkmm2ext/gtkmm2ext/tearoff.h b/libs/gtkmm2ext/gtkmm2ext/tearoff.h index 5e80892b98..737a6ddd03 100644 --- a/libs/gtkmm2ext/gtkmm2ext/tearoff.h +++ b/libs/gtkmm2ext/gtkmm2ext/tearoff.h @@ -34,6 +34,8 @@ class TearOff : public Gtk::HBox virtual ~TearOff (); void set_visible (bool yn); + void set_can_be_torn_off (bool); + bool can_be_torn_off () const { return _can_be_torn_off; } sigc::signal<void> Detach; sigc::signal<void> Attach; @@ -55,6 +57,7 @@ class TearOff : public Gtk::HBox double drag_y; bool dragging; bool _visible; + bool _can_be_torn_off; gint tearoff_click (GdkEventButton*); gint close_click (GdkEventButton*); diff --git a/libs/gtkmm2ext/popup.cc b/libs/gtkmm2ext/popup.cc index 0b150eefe1..2d586d0317 100644 --- a/libs/gtkmm2ext/popup.cc +++ b/libs/gtkmm2ext/popup.cc @@ -22,6 +22,7 @@ #include <gtkmm2ext/popup.h> #include <gtkmm2ext/utils.h> +#include <gtkmm2ext/gtk_ui.h> using namespace std; using namespace Gtk; @@ -83,9 +84,17 @@ PopUp::remove () } } +#define ENSURE_GUI_THREAD(slot) \ + if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {\ + Gtkmm2ext::UI::instance()->call_slot ((slot));\ + return;\ + } + void PopUp::touch () { + ENSURE_GUI_THREAD (mem_fun (*this, &PopUp::touch)); + if (is_visible ()) { remove (); } else { diff --git a/libs/gtkmm2ext/tearoff.cc b/libs/gtkmm2ext/tearoff.cc index 92bde5541e..be3bfe4113 100644 --- a/libs/gtkmm2ext/tearoff.cc +++ b/libs/gtkmm2ext/tearoff.cc @@ -36,6 +36,7 @@ TearOff::TearOff (Widget& c, bool allow_resize) { dragging = false; _visible = true; + _can_be_torn_off = true; tearoff_event_box.add (tearoff_arrow); tearoff_event_box.set_events (BUTTON_PRESS_MASK|BUTTON_RELEASE_MASK); @@ -79,6 +80,21 @@ TearOff::~TearOff () } void +TearOff::set_can_be_torn_off (bool yn) +{ + if (yn != _can_be_torn_off) { + if (yn) { + tearoff_arrow.set_no_show_all (false); + tearoff_arrow.show (); + } else { + tearoff_arrow.set_no_show_all (true); + tearoff_arrow.hide (); + } + _can_be_torn_off = yn; + } +} + +void TearOff::set_visible (bool yn) { /* don't change visibility if torn off */ @@ -102,13 +118,16 @@ TearOff::set_visible (bool yn) gint TearOff::tearoff_click (GdkEventButton* ev) { - remove (contents); - window_box.pack_start (contents); - own_window.set_name (get_name()); - close_event_box.set_name (get_name()); - own_window.show_all (); - hide (); - Detach (); + if (_can_be_torn_off) { + remove (contents); + window_box.pack_start (contents); + own_window.set_name (get_name()); + close_event_box.set_name (get_name()); + own_window.show_all (); + hide (); + Detach (); + } + return true; } diff --git a/libs/midi++2/alsa_sequencer_midiport.cc b/libs/midi++2/alsa_sequencer_midiport.cc index 1c2a98bfa3..fc69099d0e 100644 --- a/libs/midi++2/alsa_sequencer_midiport.cc +++ b/libs/midi++2/alsa_sequencer_midiport.cc @@ -171,7 +171,7 @@ ALSA_SequencerMidiPort::create_ports (const Port::Descriptor& desc) caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE; if (desc.mode == O_RDONLY || desc.mode == O_RDWR) caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ; - + if (0 <= (err = snd_seq_create_simple_port (seq, desc.tag.c_str(), caps, (SND_SEQ_PORT_TYPE_MIDI_GENERIC| SND_SEQ_PORT_TYPE_SOFTWARE| @@ -308,13 +308,17 @@ ALSA_SequencerMidiPort::get_connections (vector<SequencerPortAddress>& connectio seq_addr.client = snd_seq_client_id (seq); seq_addr.port = port_id; snd_seq_query_subscribe_set_root(subs, &seq_addr); - + while (snd_seq_query_port_subscribers(seq, subs) >= 0) { - seq_addr = *snd_seq_query_subscribe_get_addr (subs); - - connections.push_back (SequencerPortAddress (seq_addr.client, - seq_addr.port)); + if (snd_seq_query_subscribe_get_time_real (subs)) { + /* interesting connection */ + + seq_addr = *snd_seq_query_subscribe_get_addr (subs); + + connections.push_back (SequencerPortAddress (seq_addr.client, + seq_addr.port)); + } snd_seq_query_subscribe_set_index(subs, snd_seq_query_subscribe_get_index(subs) + 1); } diff --git a/libs/midi++2/coremidi_midiport.cc b/libs/midi++2/coremidi_midiport.cc index 14020a6f35..9eacfc0cc3 100644 --- a/libs/midi++2/coremidi_midiport.cc +++ b/libs/midi++2/coremidi_midiport.cc @@ -122,7 +122,7 @@ void CoreMidi_MidiPort::read_proc (const MIDIPacketList *pktlist, void *refCon, if (driver->firstrecv) { driver->firstrecv = false; - PBD::ThreadCreated (pthread_self(), "COREMIDI"); + PBD::notify_gui_about_thread_creation (pthread_self(), "COREMIDI"); } for (unsigned int i = 0; i < pktlist->numPackets; ++i) { diff --git a/libs/midi++2/midi.cc b/libs/midi++2/midi.cc index f612b4707a..89d74b1b31 100644 --- a/libs/midi++2/midi.cc +++ b/libs/midi++2/midi.cc @@ -19,8 +19,6 @@ */ #include <cstring> -#include <string> -#include <cstring> #include <cstdlib> #include <midi++/types.h> diff --git a/libs/midi++2/midimanager.cc b/libs/midi++2/midimanager.cc index 8a358c3183..14c9d43793 100644 --- a/libs/midi++2/midimanager.cc +++ b/libs/midi++2/midimanager.cc @@ -70,6 +70,47 @@ Manager::add_port (const XMLNode& node) PortMap::iterator existing; pair<string, Port *> newpair; + /* do not allow multiple ports with the same tag. if attempted, just return the existing + port with the same tag. XXX this is really caused by the mess of setup_midi() being + called twice in Ardour, once in the global init() function and once after the user RC file + has been loaded (there may be extra ports in it). + */ + + if ((existing = ports_by_tag.find (desc.tag)) != ports_by_tag.end()) { + + port = (*existing).second; + + if (port->mode() == desc.mode) { + + /* Same mode - reuse the port, and just + create a new tag entry. + */ + + newpair.first = desc.tag; + newpair.second = port; + + ports_by_tag.insert (newpair); + return port; + } + + /* If the existing is duplex, and this request + is not, then fail, because most drivers won't + allow opening twice with duplex and non-duplex + operation. + */ + + if ((desc.mode == O_RDWR && port->mode() != O_RDWR) || + (desc.mode != O_RDWR && port->mode() == O_RDWR)) { + error << "MIDIManager: port tagged \"" + << desc.tag + << "\" cannot be opened duplex and non-duplex" + << endmsg; + return 0; + } + + /* modes must be different or complementary */ + } + if (!PortFactory::ignore_duplicate_devices (desc.type)) { if ((existing = ports_by_device.find (desc.device)) != ports_by_device.end()) { diff --git a/libs/midi++2/midiparser.cc b/libs/midi++2/midiparser.cc index 423e833d2c..4cbcd27694 100644 --- a/libs/midi++2/midiparser.cc +++ b/libs/midi++2/midiparser.cc @@ -24,7 +24,7 @@ #include <cstring> #include <cstdlib> #include <unistd.h> -#include <string> +#include <cstring> #include <iostream> #include <iterator> diff --git a/libs/midi++2/mtc.cc b/libs/midi++2/mtc.cc index 13f5221929..9d62c7354c 100644 --- a/libs/midi++2/mtc.cc +++ b/libs/midi++2/mtc.cc @@ -18,10 +18,9 @@ $Id$ */ -#include <cstring> #include <cstdlib> #include <unistd.h> -#include <string> +#include <cstring> #include <iostream> #include <midi++/types.h> @@ -51,7 +50,6 @@ Parser::possible_mtc (byte *sysex_buf, size_t msglen) fake_mtc_time[3] = (sysex_buf[5] & 0x1f); // hours _mtc_fps = MTC_FPS ((sysex_buf[5] & 0x60) >> 5); // fps - fake_mtc_time[4] = (byte) _mtc_fps; /* wait for first quarter frame, which could indicate forwards @@ -293,6 +291,7 @@ Parser::process_mtc_quarter_frame (byte *msg) if (!_mtc_locked) { _mtc_locked = true; } + mtc_time (_mtc_time, false); } expected_mtc_quarter_frame_code = 0; diff --git a/libs/pbd/command.cc b/libs/pbd/command.cc index 011534a662..2b64c46030 100644 --- a/libs/pbd/command.cc +++ b/libs/pbd/command.cc @@ -20,7 +20,6 @@ #include <pbd/command.h> #include <pbd/xml++.h> - XMLNode &Command::get_state() { XMLNode *node = new XMLNode ("Command"); diff --git a/libs/pbd/pbd/abstract_ui.cc b/libs/pbd/pbd/abstract_ui.cc index 97f19e1fe5..8e5b9ceb07 100644 --- a/libs/pbd/pbd/abstract_ui.cc +++ b/libs/pbd/pbd/abstract_ui.cc @@ -17,7 +17,6 @@ AbstractUI<RequestObject>::AbstractUI (string name, bool with_signal_pipes) throw failed_constructor(); } - PBD::ThreadCreated.connect (mem_fun (*this, &AbstractUI<RequestObject>::register_thread)); PBD::ThreadCreatedWithRequestSize.connect (mem_fun (*this, &AbstractUI<RequestObject>::register_thread_with_request_count)); } diff --git a/libs/pbd/pbd/command.h b/libs/pbd/pbd/command.h index a66485bc0d..3fac531591 100644 --- a/libs/pbd/pbd/command.h +++ b/libs/pbd/pbd/command.h @@ -26,7 +26,7 @@ class Command : public PBD::StatefulDestructible { public: - virtual ~Command() {} + virtual ~Command() { /* NOTE: derived classes must call drop_references() */ } virtual void operator() () = 0; diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h index fdc7527dc6..660e5875d5 100644 --- a/libs/pbd/pbd/memento_command.h +++ b/libs/pbd/pbd/memento_command.h @@ -43,7 +43,7 @@ public: : obj(object), before(before), after(after) { /* catch destruction of the object */ - new PBD::Shiva<obj_T,MementoCommand<obj_T> > (object, *this); + new PBD::PairedShiva<obj_T,MementoCommand<obj_T> > (object, *this); } ~MementoCommand () diff --git a/libs/pbd/pbd/pthread_utils.h b/libs/pbd/pbd/pthread_utils.h index 9fa6ba4ce4..dd91e0a2b1 100644 --- a/libs/pbd/pbd/pthread_utils.h +++ b/libs/pbd/pbd/pthread_utils.h @@ -35,8 +35,11 @@ void pthread_exit_pbd (void* status); std::string pthread_name (); namespace PBD { - extern sigc::signal<void,pthread_t,std::string> ThreadCreated; - extern sigc::signal<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; + extern void notify_gui_about_thread_creation (pthread_t, std::string, int requests = 256); + extern void notify_gui_about_thread_exit (pthread_t); + + extern sigc::signal<void,pthread_t> ThreadLeaving; + extern sigc::signal<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; } #endif /* __pbd_pthread_utils__ */ diff --git a/libs/pbd/pbd/shiva.h b/libs/pbd/pbd/shiva.h index 2e53ff65f5..90adad6250 100644 --- a/libs/pbd/pbd/shiva.h +++ b/libs/pbd/pbd/shiva.h @@ -27,7 +27,8 @@ namespace PBD { /* named after the Hindu god Shiva, The Destroyer */ template<typename ObjectWithGoingAway, typename ObjectToBeDestroyed> -class Shiva { +class Shiva : public sigc::trackable +{ public: Shiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver) { @@ -58,15 +59,15 @@ class Shiva { }; template<typename ObjectWithGoingAway, typename ObjectToBeDestroyed> -class ProxyShiva { +class ProxyShiva : public sigc::trackable +{ public: ProxyShiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver, void (*callback)(ObjectToBeDestroyed*, ObjectWithGoingAway*)) { - + /* if the emitter goes away, destroy the receiver */ _callback = callback; - _callback_argument1 = &receiver; - _callback_argument2 = &emitter; + _callback_argument = &emitter; _connection = emitter.GoingAway.connect (sigc::bind (sigc::mem_fun @@ -74,19 +75,18 @@ class ProxyShiva { &receiver)); } - ~ProxyShiva() { + ~ProxyShiva () { forget (); } private: sigc::connection _connection; void (*_callback) (ObjectToBeDestroyed*, ObjectWithGoingAway*); - ObjectToBeDestroyed* _callback_argument1; - ObjectWithGoingAway* _callback_argument2; + ObjectWithGoingAway* _callback_argument; void destroy (ObjectToBeDestroyed* obj) { /* callback must destroy obj if appropriate, not done here */ - _callback (obj, _callback_argument2); + _callback (obj, _callback_argument); forget (); } @@ -96,7 +96,8 @@ class ProxyShiva { }; template<typename ObjectWithGoingAway, typename ObjectToBeDestroyed> -class PairedShiva { +class PairedShiva : public sigc::trackable +{ public: PairedShiva (ObjectWithGoingAway& emitter, ObjectToBeDestroyed& receiver) { diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h index 8f1716d09f..cf1f6f3470 100644 --- a/libs/pbd/pbd/undo.h +++ b/libs/pbd/pbd/undo.h @@ -27,6 +27,7 @@ #include <sigc++/bind.h> #include <sys/time.h> #include <pbd/command.h> +#include <pbd/shiva.h> typedef sigc::slot<void> UndoAction; @@ -36,7 +37,6 @@ class UndoTransaction : public Command UndoTransaction (); UndoTransaction (const UndoTransaction&); UndoTransaction& operator= (const UndoTransaction&); - ~UndoTransaction (); void clear (); bool empty() const; @@ -61,10 +61,17 @@ class UndoTransaction : public Command private: std::list<Command*> actions; + std::list<PBD::ProxyShiva<Command,UndoTransaction>*> shivas; struct timeval _timestamp; bool _clearing; friend void command_death (UndoTransaction*, Command *); + + friend class UndoHistory; + + ~UndoTransaction (); + void about_to_explicitly_delete (); + }; class UndoHistory : public sigc::trackable @@ -87,17 +94,24 @@ class UndoHistory : public sigc::trackable void clear_undo (); void clear_redo (); + /* returns all or part of the history. + If depth==0 it returns just the top + node. If depth<0, it returns everything. + If depth>0, it returns state for that + many elements of the history, or + the full history, whichever is smaller. + */ + XMLNode &get_state(int32_t depth = 0); void save_state(); - void set_depth (int32_t); - int32_t get_depth() const { return _depth; } + void set_depth (uint32_t); sigc::signal<void> Changed; private: bool _clearing; - int32_t _depth; + uint32_t _depth; std::list<UndoTransaction*> UndoList; std::list<UndoTransaction*> RedoList; diff --git a/libs/pbd/pthread_utils.cc b/libs/pbd/pthread_utils.cc index 3408f2c0b7..c63f988af3 100644 --- a/libs/pbd/pthread_utils.cc +++ b/libs/pbd/pthread_utils.cc @@ -30,14 +30,31 @@ using namespace std; typedef std::map<string,pthread_t> ThreadMap; static ThreadMap all_threads; static pthread_mutex_t thread_map_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t gui_notify_lock = PTHREAD_MUTEX_INITIALIZER; namespace PBD { - sigc::signal<void,pthread_t,std::string> ThreadCreated; + sigc::signal<void,pthread_t> ThreadLeaving; sigc::signal<void,pthread_t,std::string,uint32_t> ThreadCreatedWithRequestSize; } using namespace PBD; +void +PBD::notify_gui_about_thread_creation (pthread_t thread, std::string str, int request_count) +{ + pthread_mutex_lock (&gui_notify_lock); + ThreadCreatedWithRequestSize (thread, str, request_count); + pthread_mutex_unlock (&gui_notify_lock); +} + +void +PBD::notify_gui_about_thread_exit (pthread_t thread) +{ + pthread_mutex_lock (&gui_notify_lock); + ThreadLeaving (thread); + pthread_mutex_unlock (&gui_notify_lock); +} + int pthread_create_and_store (string name, pthread_t *thread, pthread_attr_t *attr, void * (*start_routine)(void *), void * arg) { diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc index f04b4d9431..5365a98146 100644 --- a/libs/pbd/undo.cc +++ b/libs/pbd/undo.cc @@ -18,14 +18,12 @@ $Id$ */ -#include <iostream> #include <string> #include <sstream> #include <time.h> #include <pbd/undo.h> #include <pbd/xml++.h> -#include <pbd/shiva.h> #include <sigc++/bind.h> @@ -79,8 +77,10 @@ UndoTransaction::operator= (const UndoTransaction& rhs) void UndoTransaction::add_command (Command *const action) { - /* catch death */ - new PBD::ProxyShiva<Command,UndoTransaction> (*action, *this, &command_death); + /* catch death of command (e.g. caused by death of object to + which it refers. + */ + shivas.push_back (new PBD::ProxyShiva<Command,UndoTransaction> (*action, *this, &command_death)); actions.push_back (action); } @@ -90,6 +90,21 @@ UndoTransaction::remove_command (Command* const action) actions.remove (action); } +void +UndoTransaction::about_to_explicitly_delete () +{ + /* someone is going to call our destructor and its not Shiva, + the god of destruction and chaos. This happens when an UndoHistory + is pruning itself. we must remove Shivas to avoid the god + striking us down a second time, unnecessarily and illegally. + */ + + for (list<PBD::ProxyShiva<Command,UndoTransaction>*>::iterator i = shivas.begin(); i != shivas.end(); ++i) { + delete *i; + } + shivas.clear (); +} + bool UndoTransaction::empty () const { @@ -154,27 +169,59 @@ UndoHistory::UndoHistory () } void -UndoHistory::set_depth (int32_t d) +UndoHistory::set_depth (uint32_t d) { + UndoTransaction* ut; + uint32_t current_depth = UndoList.size(); + _depth = d; - while (_depth > 0 && UndoList.size() > (uint32_t) _depth) { - UndoList.pop_front (); + if (d > current_depth) { + /* not even transactions to meet request */ + return; + } + + if (_depth > 0) { + + uint32_t cnt = current_depth - d; + + while (cnt--) { + ut = UndoList.front(); + UndoList.pop_front (); + ut->about_to_explicitly_delete (); + delete ut; + } } } void UndoHistory::add (UndoTransaction* const ut) { + uint32_t current_depth = UndoList.size(); + ut->GoingAway.connect (bind (mem_fun (*this, &UndoHistory::remove), ut)); - while (_depth > 0 && UndoList.size() > (uint32_t) _depth) { - UndoList.pop_front (); + /* if the current undo history is larger than or equal to the currently + requested depth, then pop off at least 1 element to make space + at the back for new one. + */ + + if ((_depth > 0) && current_depth && (current_depth >= _depth)) { + + uint32_t cnt = 1 + (current_depth - _depth); + + while (cnt--) { + UndoTransaction* ut; + ut = UndoList.front (); + UndoList.pop_front (); + ut->about_to_explicitly_delete (); + delete ut; + } } UndoList.push_back (ut); - /* we are now owners of the transaction */ + /* we are now owners of the transaction and must delete it when finished with it */ Changed (); /* EMIT SIGNAL */ } diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc index 71d5794805..b88e002374 100644 --- a/libs/surfaces/control_protocol/basic_ui.cc +++ b/libs/surfaces/control_protocol/basic_ui.cc @@ -50,10 +50,9 @@ BasicUI::~BasicUI () void BasicUI::register_thread (std::string name) { - PBD::ThreadCreated (pthread_self(), name); + PBD::notify_gui_about_thread_creation (pthread_self(), name); } - void BasicUI::access_action ( std::string action_path ) { diff --git a/libs/surfaces/control_protocol/control_protocol.cc b/libs/surfaces/control_protocol/control_protocol.cc index 708373e3bc..1c9ee83833 100644 --- a/libs/surfaces/control_protocol/control_protocol.cc +++ b/libs/surfaces/control_protocol/control_protocol.cc @@ -70,14 +70,14 @@ ControlProtocol::next_track (uint32_t initial_id) id++; } - while (id < limit) { + while (id <= limit) { if ((cr = session->route_by_remote_id (id)) != 0) { break; } id++; } - if (id == limit) { + if (id >= limit) { id = 0; while (id != initial_id) { if ((cr = session->route_by_remote_id (id)) != 0) { @@ -93,9 +93,9 @@ ControlProtocol::next_track (uint32_t initial_id) void ControlProtocol::prev_track (uint32_t initial_id) { - uint32_t limit = session->nroutes() - 1; + uint32_t limit = session->nroutes(); boost::shared_ptr<Route> cr = route_table[0]; - uint32_t id; + int32_t id; if (cr) { id = cr->remote_control_id (); @@ -104,7 +104,7 @@ ControlProtocol::prev_track (uint32_t initial_id) } if (id == 0) { - id = session->nroutes() - 1; + id = limit; } else { id--; } diff --git a/libs/surfaces/frontier/tranzport/tranzport_control_protocol.cc b/libs/surfaces/frontier/tranzport/tranzport_control_protocol.cc index c874a05de5..5b413273ea 100644 --- a/libs/surfaces/frontier/tranzport/tranzport_control_protocol.cc +++ b/libs/surfaces/frontier/tranzport/tranzport_control_protocol.cc @@ -1029,7 +1029,7 @@ TranzportControlProtocol::monitor_work () uint8_t offline = 0; - PBD::ThreadCreated (pthread_self(), X_("Tranzport")); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("Tranzport")); pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); next_track (); diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc index 502cea581f..f7886e078f 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.cc +++ b/libs/surfaces/mackie/mackie_control_protocol.cc @@ -1030,9 +1030,9 @@ void MackieControlProtocol::update_automation( RouteSignal & rs ) } } -void MackieControlProtocol::poll_automation() +void MackieControlProtocol::poll_automation () { - if ( _active ) + if ( _active && _automation_last.elapsed() >= 20 ) { // do all currently mapped routes for( RouteSignals::iterator it = route_signals.begin(); it != route_signals.end(); ++it ) @@ -1041,7 +1041,92 @@ void MackieControlProtocol::poll_automation() } // and the master strip - if ( master_route_signal != 0 ) update_automation( *master_route_signal ); + if ( master_route_signal != 0 ) + { + update_automation( *master_route_signal ); + } + + update_timecode_display(); + + _automation_last.start(); + } +} + +string MackieControlProtocol::format_bbt_timecode( nframes_t now_frame ) +{ + BBT_Time bbt_time; + session->bbt_time( now_frame, bbt_time ); + + // According to the Logic docs + // digits: 888/88/88/888 + // BBT mode: Bars/Beats/Subdivisions/Ticks + ostringstream os; + os << setw(3) << setfill('0') << bbt_time.bars; + os << setw(2) << setfill('0') << bbt_time.beats; + + // figure out subdivisions per beat + const Meter & meter = session->tempo_map().meter_at( now_frame ); + int subdiv = 2; + if ( meter.note_divisor() == 8 && (meter.beats_per_bar() == 12.0 || meter.beats_per_bar() == 9.0 || meter.beats_per_bar() == 6.0) ) + { + subdiv = 3; + } + + uint32_t subdivisions = bbt_time.ticks / uint32_t( Meter::ticks_per_beat / subdiv ); + uint32_t ticks = bbt_time.ticks % uint32_t( Meter::ticks_per_beat / subdiv ); + + os << setw(2) << setfill('0') << subdivisions + 1; + os << setw(3) << setfill('0') << ticks; + + return os.str(); +} + +string MackieControlProtocol::format_smpte_timecode( nframes_t now_frame ) +{ + SMPTE::Time smpte; + session->smpte_time( now_frame, smpte ); + + // According to the Logic docs + // digits: 888/88/88/888 + // SMPTE mode: Hours/Minutes/Seconds/Frames + ostringstream os; + os << setw(3) << setfill('0') << smpte.hours; + os << setw(2) << setfill('0') << smpte.minutes; + os << setw(2) << setfill('0') << smpte.seconds; + os << setw(3) << setfill('0') << smpte.frames; + + return os.str(); +} + +void MackieControlProtocol::update_timecode_display() +{ + if ( surface().has_timecode_display() ) + { + // do assignment here so current_frame is fixed + nframes_t current_frame = session->transport_frame(); + string timecode; + + switch ( _timecode_type ) + { + case ARDOUR::AnyTime::BBT: + timecode = format_bbt_timecode( current_frame ); + break; + case ARDOUR::AnyTime::SMPTE: + timecode = format_smpte_timecode( current_frame ); + break; + default: + ostringstream os; + os << "Unknown timecode: " << _timecode_type; + throw runtime_error( os.str() ); + } + + // only write the timecode string to the MCU if it's changed + // since last time. This is to reduce midi bandwidth used. + if ( timecode != _timecode_last ) + { + surface().display_timecode( mcu_port(), builder, timecode, _timecode_last ); + _timecode_last = timecode; + } } } diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h index 0ff7fbd9d4..735a2c88bd 100644 --- a/libs/surfaces/mackie/mackie_control_protocol.h +++ b/libs/surfaces/mackie/mackie_control_protocol.h @@ -255,12 +255,19 @@ class MackieControlProtocol void add_port( MIDI::Port &, int number ); - /// read automation data from the currently active routes and send to surface - void poll_automation(); + /** + Read session data and send to surface. Includes + automation from the currently active routes and + timecode displays. + */ + void poll_automation (); // called from poll_automation to figure out which automations need to be sent void update_automation( Mackie::RouteSignal & ); + // also called from poll_automation to update timecode display + void update_timecode_display(); + /** notification that the port is about to start it's init sequence. We must make sure that before this exits, the port is being polled diff --git a/libs/surfaces/mackie/mackie_control_protocol_poll.cc b/libs/surfaces/mackie/mackie_control_protocol_poll.cc index cf72c35678..cd95551f70 100644 --- a/libs/surfaces/mackie/mackie_control_protocol_poll.cc +++ b/libs/surfaces/mackie/mackie_control_protocol_poll.cc @@ -33,8 +33,7 @@ bool MackieControlProtocol::probe() void * MackieControlProtocol::monitor_work() { - // What does ThreadCreatedWithRequestSize do? - PBD::ThreadCreated (pthread_self(), X_("Mackie")); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("Mackie")); pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); @@ -105,6 +104,8 @@ void MackieControlProtocol::read_ports() for ( int p = 0; p < nfds; ++p ) { // this will cause handle_midi_any in the MackiePort to be triggered + // for alsa/raw ports + // alsa/sequencer ports trigger the midi parser off poll if ( (pfd[p].revents & POLLIN) > 0 ) { // avoid deadlocking? diff --git a/libs/surfaces/tranzport/init.cc b/libs/surfaces/tranzport/init.cc index 94f85bdc56..726cb60d49 100644 --- a/libs/surfaces/tranzport/init.cc +++ b/libs/surfaces/tranzport/init.cc @@ -173,7 +173,7 @@ TranzportControlProtocol::monitor_work () bool first_time = true; uint8_t offline = 0; - PBD::ThreadCreated (pthread_self(), X_("Tranzport")); + PBD::notify_gui_about_thread_creation (pthread_self(), X_("Tranzport")); pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, 0); pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0); rtpriority_set(); diff --git a/libs/surfaces/wiimote/SConscript b/libs/surfaces/wiimote/SConscript new file mode 100644 index 0000000000..c530445887 --- /dev/null +++ b/libs/surfaces/wiimote/SConscript @@ -0,0 +1,60 @@ +# -*- python -*- + +import os +import os.path +import glob + +Import('env final_prefix install_prefix final_config_prefix libraries i18n') + +wiimote = env.Clone() + +# +# this defines the version number of libardour_wiimote +# + +domain = 'ardour_wiimote' + +wiimote.Append(DOMAIN = domain, MAJOR = 1, MINOR = 0, MICRO = 0) +wiimote.Append(CXXFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"") +wiimote.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") +wiimote.Append(PACKAGE = domain) +wiimote.Append(POTFILE = domain + '.pot') + +wiimote_files=Split(""" +wiimote.cc +interface.cc +""") + +wiimote.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") +wiimote.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"") +wiimote.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"") +wiimote.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") +wiimote.Append(LINKFLAGS="-lcwiid") +#wiimote.Append(CPPPATH = libraries['jack'].get('CPPPATH', [])) + +wiimote.Merge ([ + libraries['ardour'], + libraries['ardour_cp'], + libraries['sndfile'], + libraries['midi++2'], + libraries['pbd'], + libraries['sigc2'], + libraries['usb'], + libraries['xml'], + libraries['glib2'], + libraries['glibmm2'] + ]) + +libardour_wiimote = wiimote.SharedLibrary('ardour_wiimote', wiimote_files) + +if wiimote['WIIMOTE']: + Default(libardour_wiimote) + env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2', 'surfaces'), libardour_wiimote)) + +if env['NLS']: + i18n (wiimote, wiimote_files, env) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript' ] + + wiimote_files + + glob.glob('po/*.po') + glob.glob('*.h'))) diff --git a/libs/surfaces/wiimote/interface.cc b/libs/surfaces/wiimote/interface.cc new file mode 100644 index 0000000000..0ef301dd6c --- /dev/null +++ b/libs/surfaces/wiimote/interface.cc @@ -0,0 +1,73 @@ +#include <pbd/failed_constructor.h> + +#include <control_protocol/control_protocol.h> +#include "wiimote.h" + +#include <ardour/session.h> + +using namespace ARDOUR; + +static WiimoteControlProtocol *foo; + +ControlProtocol* +new_wiimote_protocol (ControlProtocolDescriptor* descriptor, Session* s) +{ + WiimoteControlProtocol* wmcp; + + try { + wmcp = new WiimoteControlProtocol (*s); + } catch (failed_constructor& err) { + return 0; + } + + if (wmcp-> set_active (true)) { + delete wmcp; + return 0; + } + + foo = wmcp; + + return wmcp; +} + +void +wiimote_control_protocol_cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg[], struct timespec *t) +{ + assert(foo != 0); + + foo->wiimote_callback(wiimote,mesg_count,mesg,t); +} + +void +delete_wiimote_protocol (ControlProtocolDescriptor* descriptor, ControlProtocol* cp) +{ + foo = 0; + delete cp; +} + +bool +probe_wiimote_protocol (ControlProtocolDescriptor* descriptor) +{ + return WiimoteControlProtocol::probe (); +} + +static ControlProtocolDescriptor wiimote_descriptor = { + name : "Wiimote", + id : "uri://ardour.org/surfaces/wiimote:0", + ptr : 0, + module : 0, + mandatory : 0, + supports_feedback : false, + probe : probe_wiimote_protocol, + initialize : new_wiimote_protocol, + destroy : delete_wiimote_protocol +}; + + +extern "C" { +ControlProtocolDescriptor* +protocol_descriptor () { + return &wiimote_descriptor; +} +} + diff --git a/libs/surfaces/wiimote/wiimote.cc b/libs/surfaces/wiimote/wiimote.cc new file mode 100644 index 0000000000..af3bbc369d --- /dev/null +++ b/libs/surfaces/wiimote/wiimote.cc @@ -0,0 +1,289 @@ +#include "wiimote.h" + +#include <iostream> +#include <sigc++/bind.h> + +#include <pbd/xml++.h> +#include <ardour/session.h> + +#include "i18n.h" + + +using namespace ARDOUR; +using namespace PBD; + +void wiimote_control_protocol_cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg[], struct timespec *t); + +uint16_t WiimoteControlProtocol::button_state = 0; + +WiimoteControlProtocol::WiimoteControlProtocol ( Session & session) + : ControlProtocol ( session, "Wiimote"), + main_thread_quit (false), + restart_discovery (false), + callback_thread_registered_for_ardour (false), + wiimote_handle (0) +{ + main_thread = Glib::Thread::create( sigc::mem_fun(*this, &WiimoteControlProtocol::wiimote_main), true); +} + +WiimoteControlProtocol::~WiimoteControlProtocol() +{ + main_thread_quit = true; + slot_cond.signal(); + main_thread->join(); + + if (wiimote_handle) { + cwiid_close(wiimote_handle); + } + std::cerr << "Wiimote: closed" << std::endl; +} + + +bool +WiimoteControlProtocol::probe() +{ + return true; +} + +void +WiimoteControlProtocol::wiimote_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg[], struct timespec *t) +{ + int i; + uint16_t b; + + if (!callback_thread_registered_for_ardour) { + register_thread("Wiimote Control Protocol"); + callback_thread_registered_for_ardour = true; + } + + for (i=0; i < mesg_count; i++) + { + if (mesg[i].type == CWIID_MESG_ERROR) { + std::cerr << "Wiimote: disconnect" << std::endl; + restart_discovery = true; + slot_cond.signal(); + return; + } + + if (mesg[i].type != CWIID_MESG_BTN) continue; + + // what buttons are pressed down which weren't pressed down last time + b = (mesg[i].btn_mesg.buttons ^ button_state) & mesg[i].btn_mesg.buttons; + + button_state = mesg[i].btn_mesg.buttons; + + // if B is pressed down + if (button_state & CWIID_BTN_B) { + if (b & CWIID_BTN_A) { // B is down and A is pressed + access_action("Transport/ToggleRollForgetCapture"); + } + + if (b & CWIID_BTN_LEFT) { + access_action("Editor/playhead-to-previous-region-boundary"); + } + if (b & CWIID_BTN_RIGHT) { + access_action("Editor/playhead-to-next-region-boundary"); + } + if (b & CWIID_BTN_UP) { + next_marker(); + } + if (b & CWIID_BTN_DOWN) { + prev_marker(); + } + + if (b & CWIID_BTN_HOME) { + access_action("Editor/add-location-from-playhead"); + } + + if (b & CWIID_BTN_MINUS) { + access_action("Transport/GotoStart"); + } + + if (b & CWIID_BTN_PLUS) { + access_action("Transport/GotoEnd"); + } + + continue; + } + + + if (b & CWIID_BTN_A) { + access_action("Transport/ToggleRoll"); + } + + if (b & CWIID_BTN_1) { // 1 + access_action("Editor/track-record-enable-toggle"); + } + if (b & CWIID_BTN_2) { // 2 + rec_enable_toggle(); + } + + // d-pad + if (b & CWIID_BTN_LEFT) { // left + access_action("Editor/nudge-playhead-backward"); + } + if (b & CWIID_BTN_RIGHT) { // right + access_action("Editor/nudge-playhead-forward"); + } + if (b & CWIID_BTN_DOWN) { // down + access_action("Editor/select-next-route"); + } + if (b & CWIID_BTN_UP) { // up + access_action("Editor/select-prev-route"); + } + + + if (b & CWIID_BTN_PLUS) { // + + access_action("Editor/temporal-zoom-in"); + } + if (b & CWIID_BTN_MINUS) { // - + access_action("Editor/temporal-zoom-out"); + } + if (b & CWIID_BTN_HOME) { // "home" + // no op, yet. any suggestions? + access_action("Editor/playhead-to-edit"); + } + + } +} + +void +WiimoteControlProtocol::update_led_state() +{ + ENSURE_WIIMOTE_THREAD(sigc::mem_fun(*this, &WiimoteControlProtocol::update_led_state)); + + uint8_t state = 0; + + if (session->transport_rolling()) { + state |= CWIID_LED1_ON; + } + + if (session->actively_recording()) { + state |= CWIID_LED4_ON; + } + + cwiid_set_led(wiimote_handle, state); +} + +void +WiimoteControlProtocol::wiimote_main() +{ + bdaddr_t bdaddr; + unsigned char rpt_mode = 0; + register_thread("Wiimote Discovery and Callback Thread"); + +wiimote_discovery: + + std::cerr << "Wiimote: discovering, press 1+2" << std::endl; + + while (!wiimote_handle && !main_thread_quit) { + bdaddr = *BDADDR_ANY; + callback_thread_registered_for_ardour = false; + wiimote_handle = cwiid_open(&bdaddr, 0); + + if (!wiimote_handle && !main_thread_quit) { + sleep(1); + // We don't know whether the issue was a timeout or a configuration + // issue + } + } + + if (main_thread_quit) { + // The corner case where the wiimote is bound at the same time as + // the control protocol is destroyed + if (wiimote_handle) { + cwiid_close(wiimote_handle); + } + wiimote_handle = 0; + + std::cerr << "Wiimote Control Protocol stopped before connected to a wiimote" << std::endl; + return; + } + + std::cerr << "Wiimote: connected" << std::endl; + WiimoteControlProtocol::button_state = 0; + + if (cwiid_enable(wiimote_handle, CWIID_FLAG_REPEAT_BTN)) { + std::cerr << "cwiid_enable(), error" << std::endl; + cwiid_close(wiimote_handle); + wiimote_handle = 0; + return; + } + if (cwiid_set_mesg_callback(wiimote_handle, wiimote_control_protocol_cwiid_callback)) { + std::cerr << "cwiid_set_mesg_callback(), couldn't connect callback" << std::endl; + cwiid_close(wiimote_handle); + wiimote_handle = 0; + return; + } + if (cwiid_command(wiimote_handle, CWIID_CMD_RPT_MODE, CWIID_RPT_BTN)) { + std::cerr << "cwiid_command(), RPT_MODE error" << std::endl; + cwiid_close(wiimote_handle); + wiimote_handle = 0; + return; + } + + rpt_mode |= CWIID_RPT_BTN; + cwiid_enable(wiimote_handle, CWIID_FLAG_MESG_IFC); + cwiid_set_rpt_mode(wiimote_handle, rpt_mode); + + transport_state_conn = session->TransportStateChange.connect(sigc::mem_fun(*this, &WiimoteControlProtocol::update_led_state)); + record_state_conn = session->RecordStateChanged.connect(sigc::mem_fun(*this, &WiimoteControlProtocol::update_led_state)); + + std::cerr << "Wiimote: initialization done, waiting for callbacks / quit" << std::endl; + + while (!main_thread_quit) { + slot_mutex.lock(); + while (slot_list.empty() && !main_thread_quit && !restart_discovery) + slot_cond.wait(slot_mutex); + + if (main_thread_quit) { + slot_mutex.unlock(); + break; + } + + if (restart_discovery) { + std::cerr << "Wiimote: closing wiimote and restarting discovery" << std::endl; + if (wiimote_handle) { + cwiid_close(wiimote_handle); + wiimote_handle = 0; + } + slot_mutex.unlock(); + restart_discovery = false; + goto wiimote_discovery; + } + + sigc::slot<void> call_me = *slot_list.begin(); + slot_list.pop_front(); + slot_mutex.unlock(); + + call_me(); + } + + + std::cerr << "Wiimote: main thread stopped" << std::endl; +} + + +int +WiimoteControlProtocol::set_active (bool yn) +{ + // Let's not care about this just yet + return 0; + +} + +XMLNode& +WiimoteControlProtocol::get_state() +{ + XMLNode *node = new XMLNode ("Protocol"); + node->add_property (X_("name"), _name); + node->add_property (X_("feedback"), "0"); + + return *node; +} + +int +WiimoteControlProtocol::set_state(const XMLNode& node) +{ + return 0; +} diff --git a/libs/surfaces/wiimote/wiimote.h b/libs/surfaces/wiimote/wiimote.h new file mode 100644 index 0000000000..a6680edd2e --- /dev/null +++ b/libs/surfaces/wiimote/wiimote.h @@ -0,0 +1,69 @@ +#ifndef ardour_wiimote_control_protocol_h +#define ardour_wiimote_control_protocol_h + +#include <ardour/types.h> +#include <control_protocol/control_protocol.h> + +#include <glibmm/thread.h> + +#include <pbd/abstract_ui.h> + +#include <cwiid.h> + + +namespace ARDOUR { + class Session; +} + +#define ENSURE_WIIMOTE_THREAD(slot) \ + if (Glib::Thread::self() != main_thread) {\ + slot_mutex.lock();\ + slot_list.push_back(slot);\ + slot_cond.signal();\ + slot_mutex.unlock();\ + return;\ + } + + +class WiimoteControlProtocol : public ARDOUR::ControlProtocol { + public: + WiimoteControlProtocol (ARDOUR::Session &); + virtual ~WiimoteControlProtocol (); + + static bool probe(); + + int set_active (bool yn); + XMLNode& get_state(); + int set_state(const XMLNode&); + + void wiimote_callback(cwiid_wiimote_t *, int, union cwiid_mesg [], + struct timespec *); + + private: + + void wiimote_main(); + volatile bool main_thread_quit; + volatile bool restart_discovery; + + Glib::Thread *main_thread; + + void update_led_state(); + + bool callback_thread_registered_for_ardour; + + static uint16_t button_state; + + cwiid_wiimote_t *wiimote_handle; + + Glib::Cond slot_cond; + Glib::Mutex slot_mutex; + + std::list< sigc::slot<void> > slot_list; + + sigc::connection transport_state_conn; + sigc::connection record_state_conn; +}; + + +#endif /* ardour_wiimote_control_protocol_h */ + diff --git a/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp b/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp index 63cbfecfd1..ff02b87b75 100644 --- a/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp +++ b/libs/vamp-sdk/vamp-sdk/PluginAdapter.cpp @@ -38,6 +38,9 @@ #include <cstdlib> #include "PluginAdapter.h" +#include <cstdlib> +#include <cstring> + //#define DEBUG_PLUGIN_ADAPTER 1 diff --git a/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp index 334c11103c..4729a6223c 100644 --- a/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp +++ b/libs/vamp-sdk/vamp-sdk/PluginHostAdapter.cpp @@ -37,6 +37,8 @@ #include <cstdlib> #include "PluginHostAdapter.h" +#include <cstdlib> + namespace Vamp { |