Merge lp:~victored/noise/new-album-view into lp:~elementary-apps/noise/trunk
- new-album-view
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Corentin Noël | ||||
Approved revision: | 1518 | ||||
Merged at revision: | 1540 | ||||
Proposed branch: | lp:~victored/noise/new-album-view | ||||
Merge into: | lp:~elementary-apps/noise/trunk | ||||
Diff against target: |
966 lines (+477/-266) (has conflicts) 14 files modified
core/Utils/Icons.vala (+0/-12) core/Utils/PixbufUtils.vala (+14/-64) images/CMakeLists.txt (+5/-0) plugins/Devices/CDRom/CDView.vala (+1/-1) src/CMakeLists.txt (+79/-0) src/Objects/CoverartCache.vala (+2/-4) src/Views/GridView/GridLayout.vala (+0/-160) src/Views/GridView/GridView.vala (+6/-16) src/Widgets/FastView/FastGrid.vala (+7/-5) src/Widgets/FastView/FastGridModel.vala (+3/-1) src/Widgets/FastView/TileView/ImageUtils.vala (+51/-0) src/Widgets/FastView/TileView/TileRenderer.vala (+234/-0) src/Widgets/FastView/TileView/TileView.vala (+70/-0) src/Widgets/InfoPanel.vala (+5/-3) Text conflict in images/CMakeLists.txt Text conflict in src/CMakeLists.txt |
||||
To merge this branch: | bzr merge lp:~victored/noise/new-album-view | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
elementary Apps team | Pending | ||
Review via email: mp+180679@code.launchpad.net |
Commit message
Add fancier album view by using a custom cell renderer in GtkIconView.
Please note that the code used for "smart spacing" has been removed as it only worked before GTK+ 3.4.3. New bugs in GTK+ prevent us from keeping this code around.
Description of the change
As you may have seen, the "smart spacing" code from the album view does not work with new GTK+ versions, due to some bugs in GtkIconView we have not been able to work around. This branch removes that code for the time being and adds a custom cell renderer that makes our icon view more similar to the one used by Shotwell.
Victor Martinez (victored) wrote : | # |
David Gomes (davidgomes) wrote : | # |
We'll merge this when we have Saucy builds and are officially using GTK+ 3.8+-
- 1518. By Victor Martinez
-
Fix coding style issue
Rico Tzschichholz (ricotz) wrote : | # |
If noise doesn't work as expected with gtk+3.0 < 3.8 after this change then the dependency should have been bumped.
Preview Diff
1 | === modified file 'core/Utils/Icons.vala' | |||
2 | --- core/Utils/Icons.vala 2013-02-26 21:56:08 +0000 | |||
3 | +++ core/Utils/Icons.vala 2013-09-26 03:02:55 +0000 | |||
4 | @@ -33,15 +33,8 @@ | |||
5 | 33 | * A place to store icon information and pixbufs. | 33 | * A place to store icon information and pixbufs. |
6 | 34 | */ | 34 | */ |
7 | 35 | public class Noise.Icons { | 35 | public class Noise.Icons { |
8 | 36 | |||
9 | 37 | /** | ||
10 | 38 | * Size of the cover art used in the album view | ||
11 | 39 | **/ | ||
12 | 40 | public const int ALBUM_VIEW_IMAGE_SIZE = 168; | ||
13 | 41 | public const int DEFAULT_ALBUM_ART_SIZE = 138; | 36 | public const int DEFAULT_ALBUM_ART_SIZE = 138; |
14 | 42 | 37 | ||
15 | 43 | public static Gdk.Pixbuf DEFAULT_ALBUM_SHADOW_PIXBUF { get; private set; } | ||
16 | 44 | |||
17 | 45 | public static Icon DEFAULT_ALBUM_ART { get; private set; default = new Icon ("albumart"); } | 38 | public static Icon DEFAULT_ALBUM_ART { get; private set; default = new Icon ("albumart"); } |
18 | 46 | public static Icon DEFAULT_ALBUM_ART_2 { get; private set; default = new Icon ("albumart_2"); } | 39 | public static Icon DEFAULT_ALBUM_ART_2 { get; private set; default = new Icon ("albumart_2"); } |
19 | 47 | public static Icon MUSIC_FOLDER { get; private set; default = new Icon ("folder-music"); } | 40 | public static Icon MUSIC_FOLDER { get; private set; default = new Icon ("folder-music"); } |
20 | @@ -83,11 +76,6 @@ | |||
21 | 83 | public static Icon LIST_ADD_SYMBOLIC { get; private set; default = new Icon ("list-add-symbolic"); } | 76 | public static Icon LIST_ADD_SYMBOLIC { get; private set; default = new Icon ("list-add-symbolic"); } |
22 | 84 | public static Icon REFRESH_SYMBOLIC { get; private set; default = new Icon ("view-refresh-symbolic"); } | 77 | public static Icon REFRESH_SYMBOLIC { get; private set; default = new Icon ("view-refresh-symbolic"); } |
23 | 85 | 78 | ||
24 | 86 | static construct { | ||
25 | 87 | var default_shadow = new Icon ("albumart-shadow"); | ||
26 | 88 | DEFAULT_ALBUM_SHADOW_PIXBUF = default_shadow.render_at_size (ALBUM_VIEW_IMAGE_SIZE); | ||
27 | 89 | } | ||
28 | 90 | |||
29 | 91 | /** | 79 | /** |
30 | 92 | * This is needed until vala really supports initialization of static members. | 80 | * This is needed until vala really supports initialization of static members. |
31 | 93 | * See https://bugzilla.gnome.org/show_bug.cgi?id=543189 | 81 | * See https://bugzilla.gnome.org/show_bug.cgi?id=543189 |
32 | 94 | 82 | ||
33 | === modified file 'core/Utils/PixbufUtils.vala' | |||
34 | --- core/Utils/PixbufUtils.vala 2013-06-12 18:04:28 +0000 | |||
35 | +++ core/Utils/PixbufUtils.vala 2013-09-26 03:02:55 +0000 | |||
36 | @@ -22,75 +22,25 @@ | |||
37 | 22 | */ | 22 | */ |
38 | 23 | 23 | ||
39 | 24 | namespace Noise.PixbufUtils { | 24 | namespace Noise.PixbufUtils { |
40 | 25 | |||
41 | 26 | /** | ||
42 | 27 | * @param pixbuf original image | ||
43 | 28 | * @param stretch whether to strech the image inside the square or keep the original dimensions | ||
44 | 29 | * @return original pixbuf + drop shadow | ||
45 | 30 | **/ | ||
46 | 31 | public Gdk.Pixbuf? get_pixbuf_shadow (Gdk.Pixbuf pixbuf, int surface_size, bool stretch = true) { | ||
47 | 32 | const int SHADOW_SIZE = 15; | ||
48 | 33 | |||
49 | 34 | int S_WIDTH = (stretch)? surface_size: pixbuf.width; | ||
50 | 35 | int S_HEIGHT = (stretch)? surface_size : pixbuf.height; | ||
51 | 36 | |||
52 | 37 | var buffer_surface = new Granite.Drawing.BufferSurface (S_WIDTH, S_HEIGHT); | ||
53 | 38 | |||
54 | 39 | // paint shadow | ||
55 | 40 | buffer_surface.context.rectangle (0, 0, S_WIDTH, S_HEIGHT); | ||
56 | 41 | |||
57 | 42 | if (stretch) | ||
58 | 43 | Gdk.cairo_set_source_pixbuf (buffer_surface.context, | ||
59 | 44 | Icons.DEFAULT_ALBUM_SHADOW_PIXBUF.scale_simple (S_WIDTH, S_HEIGHT, Gdk.InterpType.BILINEAR), 0, 0); | ||
60 | 45 | else | ||
61 | 46 | Gdk.cairo_set_source_pixbuf (buffer_surface.context, Icons.DEFAULT_ALBUM_SHADOW_PIXBUF, 0, 0); | ||
62 | 47 | |||
63 | 48 | buffer_surface.context.paint(); | ||
64 | 49 | |||
65 | 50 | S_WIDTH -= 2 * SHADOW_SIZE; | ||
66 | 51 | S_HEIGHT -= 2 * SHADOW_SIZE; | ||
67 | 52 | |||
68 | 53 | // paint original pixbuf | ||
69 | 54 | var source_pixbuf = pixbuf; | ||
70 | 55 | if (pixbuf.width != S_WIDTH || pixbuf.height != S_HEIGHT) | ||
71 | 56 | source_pixbuf = pixbuf.scale_simple (S_WIDTH, S_HEIGHT, Gdk.InterpType.BILINEAR); | ||
72 | 57 | |||
73 | 58 | Gdk.cairo_set_source_pixbuf (buffer_surface.context, source_pixbuf, | ||
74 | 59 | SHADOW_SIZE, SHADOW_SIZE - 2); // 2px vertical offset | ||
75 | 60 | buffer_surface.context.paint(); | ||
76 | 61 | |||
77 | 62 | return buffer_surface.load_to_pixbuf(); | ||
78 | 63 | } | ||
79 | 64 | |||
80 | 65 | /** | 25 | /** |
81 | 66 | * @param surface_size size of the new pixbuf. Set a value of 0 to use the pixbuf's default size. | 26 | * @param surface_size size of the new pixbuf. Set a value of 0 to use the pixbuf's default size. |
82 | 67 | **/ | 27 | **/ |
96 | 68 | public Gdk.Pixbuf? render_pixbuf_shadow (Gdk.Pixbuf pixbuf, | 28 | public Gdk.Pixbuf? render_pixbuf_shadow (Gdk.Pixbuf pixbuf, int shadow_size = 5, double alpha = 0.75) { |
97 | 69 | int surface_size = Icons.ALBUM_VIEW_IMAGE_SIZE, | 29 | int width = pixbuf.width; |
98 | 70 | int shadow_size = 5, double alpha = 0.75) | 30 | int height = pixbuf.height; |
99 | 71 | { | 31 | int shadow_padding = 2 * shadow_size; |
100 | 72 | int S_WIDTH = (surface_size > 0)? surface_size : pixbuf.width; | 32 | |
101 | 73 | int S_HEIGHT = (surface_size > 0)? surface_size : pixbuf.height; | 33 | var buffer_surface = new Granite.Drawing.BufferSurface (width + shadow_padding, |
102 | 74 | 34 | height + shadow_padding); | |
103 | 75 | var buffer_surface = new Granite.Drawing.BufferSurface (S_WIDTH, S_HEIGHT); | 35 | |
104 | 76 | 36 | buffer_surface.context.rectangle (shadow_size, shadow_size, width, height); | |
92 | 77 | S_WIDTH -= 2 * shadow_size; | ||
93 | 78 | S_HEIGHT -= 2 * shadow_size; | ||
94 | 79 | |||
95 | 80 | buffer_surface.context.rectangle (shadow_size, shadow_size, S_WIDTH, S_HEIGHT); | ||
105 | 81 | buffer_surface.context.set_source_rgba (0, 0, 0, alpha); | 37 | buffer_surface.context.set_source_rgba (0, 0, 0, alpha); |
108 | 82 | buffer_surface.context.fill(); | 38 | buffer_surface.context.fill (); |
107 | 83 | |||
109 | 84 | buffer_surface.fast_blur (2, 3); | 39 | buffer_surface.fast_blur (2, 3); |
119 | 85 | 40 | Gdk.cairo_set_source_pixbuf (buffer_surface.context, pixbuf, shadow_size, shadow_size); | |
120 | 86 | Gdk.cairo_set_source_pixbuf (buffer_surface.context, | 41 | buffer_surface.context.paint (); |
121 | 87 | pixbuf.scale_simple (S_WIDTH, S_HEIGHT, Gdk.InterpType.BILINEAR), | 42 | |
122 | 88 | shadow_size, | 43 | return buffer_surface.load_to_pixbuf (); |
114 | 89 | shadow_size); | ||
115 | 90 | |||
116 | 91 | buffer_surface.context.paint(); | ||
117 | 92 | |||
118 | 93 | return buffer_surface.load_to_pixbuf(); | ||
123 | 94 | } | 44 | } |
124 | 95 | 45 | ||
125 | 96 | public async Gdk.Pixbuf? get_pixbuf_from_file_async (File file, Cancellable? c = null) throws Error { | 46 | public async Gdk.Pixbuf? get_pixbuf_from_file_async (File file, Cancellable? c = null) throws Error { |
126 | 97 | 47 | ||
127 | === modified file 'images/CMakeLists.txt' | |||
128 | --- images/CMakeLists.txt 2013-09-16 07:12:31 +0000 | |||
129 | +++ images/CMakeLists.txt 2013-09-26 03:02:55 +0000 | |||
130 | @@ -21,9 +21,14 @@ | |||
131 | 21 | # Default album image and album shadow. These would not be found by the icon renderer if | 21 | # Default album image and album shadow. These would not be found by the icon renderer if |
132 | 22 | # they were installed to the hicolor sub-directory, since their dimensions are not the ones | 22 | # they were installed to the hicolor sub-directory, since their dimensions are not the ones |
133 | 23 | # GTK+ expects to find in a normal icon theme. They work fine in the root icon dir though. | 23 | # GTK+ expects to find in a normal icon theme. They work fine in the root icon dir though. |
134 | 24 | <<<<<<< TREE | ||
135 | 24 | set (GENERIC_IMAGES | 25 | set (GENERIC_IMAGES |
136 | 25 | icons/albumart.svg | 26 | icons/albumart.svg |
137 | 26 | icons/albumart-shadow.png | 27 | icons/albumart-shadow.png |
138 | 28 | ======= | ||
139 | 29 | set(GENERIC_IMAGES | ||
140 | 30 | icons/albumart.svg | ||
141 | 31 | >>>>>>> MERGE-SOURCE | ||
142 | 27 | ) | 32 | ) |
143 | 28 | 33 | ||
144 | 29 | install (FILES ${GENERIC_IMAGES} DESTINATION ${ICON_DIR}) | 34 | install (FILES ${GENERIC_IMAGES} DESTINATION ${ICON_DIR}) |
145 | 30 | 35 | ||
146 | === removed file 'images/icons/albumart-shadow.png' | |||
147 | 31 | Binary files images/icons/albumart-shadow.png 2013-07-12 19:29:23 +0000 and images/icons/albumart-shadow.png 1970-01-01 00:00:00 +0000 differ | 36 | Binary files images/icons/albumart-shadow.png 2013-07-12 19:29:23 +0000 and images/icons/albumart-shadow.png 1970-01-01 00:00:00 +0000 differ |
148 | === modified file 'plugins/Devices/CDRom/CDView.vala' | |||
149 | --- plugins/Devices/CDRom/CDView.vala 2013-04-29 18:26:03 +0000 | |||
150 | +++ plugins/Devices/CDRom/CDView.vala 2013-09-26 03:02:55 +0000 | |||
151 | @@ -57,7 +57,7 @@ | |||
152 | 57 | } | 57 | } |
153 | 58 | 58 | ||
154 | 59 | var default_pix = Icons.DEFAULT_ALBUM_ART.render_at_size (Icons.DEFAULT_ALBUM_ART_SIZE); | 59 | var default_pix = Icons.DEFAULT_ALBUM_ART.render_at_size (Icons.DEFAULT_ALBUM_ART_SIZE); |
156 | 60 | default_pix = PixbufUtils.get_pixbuf_shadow (default_pix, Icons.ALBUM_VIEW_IMAGE_SIZE); | 60 | default_pix = PixbufUtils.render_pixbuf_shadow (default_pix); |
157 | 61 | 61 | ||
158 | 62 | album_image = new Gtk.Image.from_pixbuf (default_pix); | 62 | album_image = new Gtk.Image.from_pixbuf (default_pix); |
159 | 63 | album_image.halign = Gtk.Align.CENTER; | 63 | album_image.halign = Gtk.Align.CENTER; |
160 | 64 | 64 | ||
161 | === modified file 'src/CMakeLists.txt' | |||
162 | --- src/CMakeLists.txt 2013-09-16 07:12:31 +0000 | |||
163 | +++ src/CMakeLists.txt 2013-09-26 03:02:55 +0000 | |||
164 | @@ -1,3 +1,4 @@ | |||
165 | 1 | <<<<<<< TREE | ||
166 | 1 | set (CLIENT_SOURCE | 2 | set (CLIENT_SOURCE |
167 | 2 | main.vala | 3 | main.vala |
168 | 3 | Noise.vala | 4 | Noise.vala |
169 | @@ -71,6 +72,84 @@ | |||
170 | 71 | Dialogs/SetMusicFolderConfirmation.vala | 72 | Dialogs/SetMusicFolderConfirmation.vala |
171 | 72 | Dialogs/TransferFromDeviceDialog.vala | 73 | Dialogs/TransferFromDeviceDialog.vala |
172 | 73 | Dialogs/SyncWarningDialog.vala | 74 | Dialogs/SyncWarningDialog.vala |
173 | 75 | ======= | ||
174 | 76 | set(CLIENT_SOURCE | ||
175 | 77 | main.vala | ||
176 | 78 | Noise.vala | ||
177 | 79 | LibraryWindow.vala | ||
178 | 80 | LocalLibrary.vala | ||
179 | 81 | PlaybackManager.vala | ||
180 | 82 | FileOperator.vala | ||
181 | 83 | Objects/LyricFetcher.vala | ||
182 | 84 | Objects/MediaInfo.vala | ||
183 | 85 | Objects/AlbumInfo.vala | ||
184 | 86 | Objects/ArtistInfo.vala | ||
185 | 87 | Objects/TrackInfo.vala | ||
186 | 88 | Objects/MediaArtCache.vala | ||
187 | 89 | Objects/CoverartCache.vala | ||
188 | 90 | Objects/MediaKeyListener.vala | ||
189 | 91 | Widgets/NavigationArrows.vala | ||
190 | 92 | Widgets/SmartAlbumRenderer.vala | ||
191 | 93 | Widgets/TopDisplay.vala | ||
192 | 94 | Widgets/InfoPanel.vala | ||
193 | 95 | Widgets/EmbeddedAlert.vala | ||
194 | 96 | Widgets/SimpleOptionChooser.vala | ||
195 | 97 | Widgets/PresetList.vala | ||
196 | 98 | Widgets/SideBar.vala | ||
197 | 99 | Widgets/SourceListView.vala | ||
198 | 100 | Widgets/StatusBar.vala | ||
199 | 101 | Widgets/RatingWidget.vala | ||
200 | 102 | Widgets/SpaceWidget.vala | ||
201 | 103 | Widgets/FixedBin.vala | ||
202 | 104 | Widgets/ViewSelector.vala | ||
203 | 105 | Widgets/FastView/TileView/ImageUtils.vala | ||
204 | 106 | Widgets/FastView/TileView/TileRenderer.vala | ||
205 | 107 | Widgets/FastView/TileView/TileView.vala | ||
206 | 108 | Widgets/FastView/FastGrid.vala | ||
207 | 109 | Widgets/FastView/FastGridModel.vala | ||
208 | 110 | Widgets/FastView/FastList.vala | ||
209 | 111 | Widgets/FastView/FastListModel.vala | ||
210 | 112 | DataBase/DataBaseManager.vala | ||
211 | 113 | DataBase/DataBaseUpdater.vala | ||
212 | 114 | DataBase/Tables.vala | ||
213 | 115 | GStreamer/GStreamerTagger.vala | ||
214 | 116 | GStreamer/Streamer.vala | ||
215 | 117 | GStreamer/CoverImport.vala | ||
216 | 118 | Views/ViewContainer.vala | ||
217 | 119 | Views/Wrappers/ViewWrapper.vala | ||
218 | 120 | Views/Wrappers/MusicViewWrapper.vala | ||
219 | 121 | Views/Wrappers/DeviceViewWrapper.vala | ||
220 | 122 | Views/Wrappers/PlaylistViewWrapper.vala | ||
221 | 123 | Views/Wrappers/ReadOnlyPlaylistViewWrapper.vala | ||
222 | 124 | Views/DeviceView.vala | ||
223 | 125 | Views/DeviceSummaryWidget.vala | ||
224 | 126 | Views/ContentView.vala | ||
225 | 127 | Views/ViewTextOverlay.vala | ||
226 | 128 | Views/GridView/GridLayout.vala | ||
227 | 129 | Views/GridView/GridView.vala | ||
228 | 130 | Views/GridView/PopupListView.vala | ||
229 | 131 | Views/ListView/ListView.vala | ||
230 | 132 | Views/ListView/ColumnBrowser/BrowserColumnModel.vala | ||
231 | 133 | Views/ListView/ColumnBrowser/BrowserColumn.vala | ||
232 | 134 | Views/ListView/ColumnBrowser/ColumnBrowser.vala | ||
233 | 135 | Views/ListView/ColumnBrowser/MusicColumnBrowser.vala | ||
234 | 136 | Views/ListView/Lists/ListColumn.vala | ||
235 | 137 | Views/ListView/Lists/TreeViewSetup.vala | ||
236 | 138 | Views/ListView/Lists/CellDataFunctionHelper.vala | ||
237 | 139 | Views/ListView/Lists/GenericList.vala | ||
238 | 140 | Views/ListView/Lists/MusicListView.vala | ||
239 | 141 | Dialogs/EqualizerWindow.vala | ||
240 | 142 | Dialogs/SmartPlaylistEditor.vala | ||
241 | 143 | Dialogs/PreferencesWindow.vala | ||
242 | 144 | Dialogs/InstallGstreamerPluginsDialog.vala | ||
243 | 145 | Dialogs/MediaEditor.vala | ||
244 | 146 | Dialogs/FileNotFoundDialog.vala | ||
245 | 147 | Dialogs/RemoveFilesDialog.vala | ||
246 | 148 | Dialogs/NotImportedWindow.vala | ||
247 | 149 | Dialogs/SetMusicFolderConfirmation.vala | ||
248 | 150 | Dialogs/TransferFromDeviceDialog.vala | ||
249 | 151 | Dialogs/SyncWarningDialog.vala | ||
250 | 152 | >>>>>>> MERGE-SOURCE | ||
251 | 74 | ) | 153 | ) |
252 | 75 | 154 | ||
253 | 76 | set (CLIENT_VALAC_OPTIONS | 155 | set (CLIENT_VALAC_OPTIONS |
254 | 77 | 156 | ||
255 | === modified file 'src/Objects/CoverartCache.vala' | |||
256 | --- src/Objects/CoverartCache.vala 2012-11-03 18:52:31 +0000 | |||
257 | +++ src/Objects/CoverartCache.vala 2013-09-26 03:02:55 +0000 | |||
258 | @@ -55,11 +55,9 @@ | |||
259 | 55 | default_image = filter_func (default_pix); | 55 | default_image = filter_func (default_pix); |
260 | 56 | } | 56 | } |
261 | 57 | 57 | ||
262 | 58 | /** | ||
263 | 59 | * Adds a shadow to every image. | ||
264 | 60 | */ | ||
265 | 61 | protected override Gdk.Pixbuf? filter_func (Gdk.Pixbuf pix) { | 58 | protected override Gdk.Pixbuf? filter_func (Gdk.Pixbuf pix) { |
267 | 62 | return PixbufUtils.get_pixbuf_shadow (pix, Icons.ALBUM_VIEW_IMAGE_SIZE); | 59 | int size = Icons.DEFAULT_ALBUM_ART_SIZE; |
268 | 60 | return pix.scale_simple (size, size, Gdk.InterpType.BILINEAR); | ||
269 | 63 | } | 61 | } |
270 | 64 | 62 | ||
271 | 65 | protected override string get_key (Media m) { | 63 | protected override string get_key (Media m) { |
272 | 66 | 64 | ||
273 | === modified file 'src/Views/GridView/GridLayout.vala' | |||
274 | --- src/Views/GridView/GridLayout.vala 2013-05-22 20:42:53 +0000 | |||
275 | +++ src/Views/GridView/GridLayout.vala 2013-09-26 03:02:55 +0000 | |||
276 | @@ -17,23 +17,11 @@ | |||
277 | 17 | */ | 17 | */ |
278 | 18 | 18 | ||
279 | 19 | public abstract class Noise.GridLayout : ViewTextOverlay { | 19 | public abstract class Noise.GridLayout : ViewTextOverlay { |
280 | 20 | |||
281 | 21 | public ViewWrapper parent_view_wrapper { get; protected set; } | 20 | public ViewWrapper parent_view_wrapper { get; protected set; } |
282 | 22 | 21 | ||
283 | 23 | private FastGrid icon_view; | 22 | private FastGrid icon_view; |
284 | 24 | private Gtk.ScrolledWindow scroll; | 23 | private Gtk.ScrolledWindow scroll; |
285 | 25 | 24 | ||
286 | 26 | // Spacing Workarounds | ||
287 | 27 | #if !GTK_ICON_VIEW_BUG_IS_FIXED | ||
288 | 28 | private Gtk.EventBox vpadding_box; | ||
289 | 29 | private Gtk.EventBox hpadding_box; | ||
290 | 30 | #endif | ||
291 | 31 | |||
292 | 32 | private const string STYLESHEET = "*:selected{background-color:@transparent;}"; | ||
293 | 33 | private const int ITEM_PADDING = 0; | ||
294 | 34 | private const int MIN_SPACING = 6; | ||
295 | 35 | private const int ITEM_WIDTH = Icons.ALBUM_VIEW_IMAGE_SIZE; | ||
296 | 36 | |||
297 | 37 | public GridLayout (ViewWrapper view_wrapper) { | 25 | public GridLayout (ViewWrapper view_wrapper) { |
298 | 38 | parent_view_wrapper = view_wrapper; | 26 | parent_view_wrapper = view_wrapper; |
299 | 39 | build_ui (); | 27 | build_ui (); |
300 | @@ -88,59 +76,7 @@ | |||
301 | 88 | 76 | ||
302 | 89 | icon_view.set_columns (-1); | 77 | icon_view.set_columns (-1); |
303 | 90 | 78 | ||
304 | 91 | // Should be defined for GTK+ 3.4.3 or later | ||
305 | 92 | #if !GTK_ICON_VIEW_BUG_IS_FIXED | ||
306 | 93 | |||
307 | 94 | var wrapper_vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); | ||
308 | 95 | var wrapper_hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); | ||
309 | 96 | |||
310 | 97 | vpadding_box = new Gtk.EventBox(); | ||
311 | 98 | hpadding_box = new Gtk.EventBox(); | ||
312 | 99 | |||
313 | 100 | vpadding_box.get_style_context().add_class(Gtk.STYLE_CLASS_VIEW); | ||
314 | 101 | hpadding_box.get_style_context().add_class(Gtk.STYLE_CLASS_VIEW); | ||
315 | 102 | this.get_style_context().add_class(Gtk.STYLE_CLASS_VIEW); | ||
316 | 103 | |||
317 | 104 | vpadding_box.get_style_context().add_class (Granite.StyleClass.CONTENT_VIEW); | ||
318 | 105 | hpadding_box.get_style_context().add_class (Granite.StyleClass.CONTENT_VIEW); | ||
319 | 106 | this.get_style_context().add_class (Granite.StyleClass.CONTENT_VIEW); | ||
320 | 107 | |||
321 | 108 | vpadding_box.set_size_request (-1, MIN_SPACING + ITEM_PADDING); | ||
322 | 109 | hpadding_box.set_size_request (MIN_SPACING + ITEM_PADDING, -1); | ||
323 | 110 | |||
324 | 111 | vpadding_box.button_press_event.connect ( () => { | ||
325 | 112 | item_activated (null); | ||
326 | 113 | return false; | ||
327 | 114 | }); | ||
328 | 115 | |||
329 | 116 | hpadding_box.button_press_event.connect ( () => { | ||
330 | 117 | item_activated (null); | ||
331 | 118 | return false; | ||
332 | 119 | }); | ||
333 | 120 | |||
334 | 121 | |||
335 | 122 | wrapper_vbox.pack_start (vpadding_box, false, false, 0); | ||
336 | 123 | wrapper_vbox.pack_start (wrapper_hbox, true, true, 0); | ||
337 | 124 | wrapper_hbox.pack_start (hpadding_box, false, false, 0); | ||
338 | 125 | wrapper_hbox.pack_start (icon_view, true, true, 0); | ||
339 | 126 | |||
340 | 127 | scroll.add_with_viewport (wrapper_vbox); | ||
341 | 128 | |||
342 | 129 | icon_view.margin = 0; | ||
343 | 130 | |||
344 | 131 | #else | ||
345 | 132 | |||
346 | 133 | scroll.add (icon_view); | 79 | scroll.add (icon_view); |
347 | 134 | icon_view.margin = MIN_SPACING; | ||
348 | 135 | |||
349 | 136 | #endif | ||
350 | 137 | |||
351 | 138 | |||
352 | 139 | icon_view.item_width = ITEM_WIDTH; | ||
353 | 140 | icon_view.item_padding = ITEM_PADDING; | ||
354 | 141 | icon_view.spacing = 0; | ||
355 | 142 | icon_view.row_spacing = MIN_SPACING; | ||
356 | 143 | icon_view.column_spacing = MIN_SPACING; | ||
357 | 144 | 80 | ||
358 | 145 | icon_view.add_events (Gdk.EventMask.POINTER_MOTION_MASK); | 81 | icon_view.add_events (Gdk.EventMask.POINTER_MOTION_MASK); |
359 | 146 | icon_view.motion_notify_event.connect (on_motion_notify); | 82 | icon_view.motion_notify_event.connect (on_motion_notify); |
360 | @@ -150,24 +86,9 @@ | |||
361 | 150 | icon_view.button_release_event.connect (on_button_release); | 86 | icon_view.button_release_event.connect (on_button_release); |
362 | 151 | icon_view.item_activated.connect (on_item_activated); | 87 | icon_view.item_activated.connect (on_item_activated); |
363 | 152 | 88 | ||
364 | 153 | int MIN_N_ITEMS = 2; // we will allocate horizontal space for at least two items | ||
365 | 154 | int TOTAL_ITEM_WIDTH = ITEM_WIDTH + 2 * ITEM_PADDING; | ||
366 | 155 | int TOTAL_MARGIN = MIN_N_ITEMS * (MIN_SPACING + ITEM_PADDING); | ||
367 | 156 | int MIDDLE_SPACE = MIN_N_ITEMS * MIN_SPACING; | ||
368 | 157 | |||
369 | 158 | scroll.min_content_width = MIN_N_ITEMS * TOTAL_ITEM_WIDTH + TOTAL_MARGIN + MIDDLE_SPACE; | ||
370 | 159 | |||
371 | 160 | set_theming (); | ||
372 | 161 | scroll.get_hadjustment ().changed.connect (on_resize); | ||
373 | 162 | |||
374 | 163 | show_all (); | 89 | show_all (); |
375 | 164 | } | 90 | } |
376 | 165 | 91 | ||
377 | 166 | private void set_theming () { | ||
378 | 167 | // Change background color | ||
379 | 168 | Granite.Widgets.Utils.set_theming (icon_view, STYLESHEET, null, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); | ||
380 | 169 | } | ||
381 | 170 | |||
382 | 171 | private void on_item_activated (Gtk.TreePath? path) { | 92 | private void on_item_activated (Gtk.TreePath? path) { |
383 | 172 | if (path == null) | 93 | if (path == null) |
384 | 173 | item_activated (null); | 94 | item_activated (null); |
385 | @@ -218,85 +139,4 @@ | |||
386 | 218 | set_cursor ((int)ev.x, (int)ev.y); | 139 | set_cursor ((int)ev.x, (int)ev.y); |
387 | 219 | return false; | 140 | return false; |
388 | 220 | } | 141 | } |
389 | 221 | |||
390 | 222 | |||
391 | 223 | /** | ||
392 | 224 | * Smart spacing | ||
393 | 225 | */ | ||
394 | 226 | private bool waiting_resize = false; | ||
395 | 227 | |||
396 | 228 | private void on_resize () { | ||
397 | 229 | if (waiting_resize) | ||
398 | 230 | return; | ||
399 | 231 | |||
400 | 232 | waiting_resize = true; | ||
401 | 233 | |||
402 | 234 | int priority = parent_view_wrapper.is_current_wrapper ? Priority.HIGH_IDLE : Priority.LOW; | ||
403 | 235 | |||
404 | 236 | Idle.add_full (priority , () => { | ||
405 | 237 | update_spacing (); | ||
406 | 238 | waiting_resize = false; | ||
407 | 239 | return false; | ||
408 | 240 | }); | ||
409 | 241 | } | ||
410 | 242 | |||
411 | 243 | private int get_current_width () { | ||
412 | 244 | return (int) scroll.get_hadjustment ().page_size; | ||
413 | 245 | } | ||
414 | 246 | |||
415 | 247 | private void update_spacing () { | ||
416 | 248 | if (!visible) | ||
417 | 249 | return; | ||
418 | 250 | |||
419 | 251 | int new_width = get_current_width (); | ||
420 | 252 | |||
421 | 253 | int TOTAL_WIDTH = new_width; // width of view wrapper, not scrolled window! | ||
422 | 254 | int TOTAL_ITEM_WIDTH = ITEM_WIDTH + 2 * ITEM_PADDING; | ||
423 | 255 | |||
424 | 256 | // Calculate the number of columns | ||
425 | 257 | float n = (float)(TOTAL_WIDTH - MIN_SPACING) / (float)(TOTAL_ITEM_WIDTH + MIN_SPACING); | ||
426 | 258 | int n_columns = (int) GLib.Math.truncf (n); | ||
427 | 259 | |||
428 | 260 | if (n_columns < 1) | ||
429 | 261 | return; | ||
430 | 262 | |||
431 | 263 | icon_view.set_columns (n_columns); | ||
432 | 264 | |||
433 | 265 | // We don't want to adjust the spacing if the row is not full | ||
434 | 266 | if (icon_view.get_table ().size () < n_columns) | ||
435 | 267 | return; | ||
436 | 268 | |||
437 | 269 | // You're not supposed to understand this. | ||
438 | 270 | float spacing = (float)(TOTAL_WIDTH - n_columns * (ITEM_WIDTH + 1) - 2 * n_columns * ITEM_PADDING) / (float)(n_columns + 1); | ||
439 | 271 | int new_spacing = (int) GLib.Math.roundf (spacing); | ||
440 | 272 | |||
441 | 273 | if (new_spacing < 0) | ||
442 | 274 | return; | ||
443 | 275 | |||
444 | 276 | if (TOTAL_WIDTH < 750) | ||
445 | 277 | -- new_spacing; | ||
446 | 278 | |||
447 | 279 | // apply new spacing | ||
448 | 280 | set_spacing (new_spacing); | ||
449 | 281 | } | ||
450 | 282 | |||
451 | 283 | private void set_spacing (int spacing) { | ||
452 | 284 | if (spacing < 0) | ||
453 | 285 | return; | ||
454 | 286 | |||
455 | 287 | int item_offset = ITEM_PADDING / icon_view.columns; | ||
456 | 288 | int item_spacing = spacing - ((item_offset > 0) ? item_offset : 1); | ||
457 | 289 | |||
458 | 290 | icon_view.set_column_spacing (item_spacing); | ||
459 | 291 | icon_view.set_row_spacing (item_spacing); | ||
460 | 292 | |||
461 | 293 | int margin_width = spacing + ITEM_PADDING; | ||
462 | 294 | |||
463 | 295 | #if GTK_ICON_VIEW_BUG_IS_FIXED | ||
464 | 296 | icon_view.set_margin (margin_width); | ||
465 | 297 | #else | ||
466 | 298 | vpadding_box.set_size_request (-1, margin_width); | ||
467 | 299 | hpadding_box.set_size_request (margin_width, -1); | ||
468 | 300 | #endif | ||
469 | 301 | } | ||
470 | 302 | } | 142 | } |
471 | 303 | 143 | ||
472 | === modified file 'src/Views/GridView/GridView.vala' | |||
473 | --- src/Views/GridView/GridView.vala 2013-06-02 17:35:04 +0000 | |||
474 | +++ src/Views/GridView/GridView.vala 2013-09-26 03:02:55 +0000 | |||
475 | @@ -18,10 +18,6 @@ | |||
476 | 18 | */ | 18 | */ |
477 | 19 | 19 | ||
478 | 20 | public class Noise.GridView : ContentView, GridLayout { | 20 | public class Noise.GridView : ContentView, GridLayout { |
479 | 21 | |||
480 | 22 | private string TEXT_MARKUP = "%s\n<span foreground=\"#999\">%s</span>"; | ||
481 | 23 | private string TOOLTIP_MARKUP = "<span size=\"large\"><b>%s</b></span>\n%s"; | ||
482 | 24 | |||
483 | 25 | // The window used to present album contents | 21 | // The window used to present album contents |
484 | 26 | private static PopupListView? _popup = null; | 22 | private static PopupListView? _popup = null; |
485 | 27 | public PopupListView popup_list_view { | 23 | public PopupListView popup_list_view { |
486 | @@ -329,22 +325,16 @@ | |||
487 | 329 | // replace the current album-related media fields. | 325 | // replace the current album-related media fields. |
488 | 330 | return CoverartCache.instance.get_album_cover (album); | 326 | return CoverartCache.instance.get_album_cover (album); |
489 | 331 | 327 | ||
500 | 332 | case FastGrid.Column.MARKUP: | 328 | case FastGrid.Column.TITLE: |
501 | 333 | string name = album.get_display_name (); | 329 | return album.get_display_name (); |
502 | 334 | string artist = album.get_display_artist (); | 330 | |
503 | 335 | 331 | case FastGrid.Column.SUBTITLE: | |
504 | 336 | if (name.length > 25) | 332 | return album.get_display_artist (); |
495 | 337 | name = name.substring (0, 21) + "…"; | ||
496 | 338 | if (artist.length > 25) | ||
497 | 339 | artist = artist.substring (0, 21) + "…"; | ||
498 | 340 | |||
499 | 341 | return Markup.printf_escaped (TEXT_MARKUP, name, artist); | ||
505 | 342 | 333 | ||
506 | 343 | case FastGrid.Column.TOOLTIP: | 334 | case FastGrid.Column.TOOLTIP: |
507 | 344 | string name = album.get_display_name (); | 335 | string name = album.get_display_name (); |
508 | 345 | string artist = album.get_display_artist (); | 336 | string artist = album.get_display_artist (); |
511 | 346 | 337 | return Markup.printf_escaped ("<span size=\"large\"><b>%s</b></span>\n%s", name, artist); | |
510 | 347 | return Markup.printf_escaped (TOOLTIP_MARKUP, name, artist); | ||
512 | 348 | } | 338 | } |
513 | 349 | 339 | ||
514 | 350 | assert_not_reached (); | 340 | assert_not_reached (); |
515 | 351 | 341 | ||
516 | === modified file 'src/Widgets/FastView/FastGrid.vala' | |||
517 | --- src/Widgets/FastView/FastGrid.vala 2013-05-22 20:42:53 +0000 | |||
518 | +++ src/Widgets/FastView/FastGrid.vala 2013-09-26 03:02:55 +0000 | |||
519 | @@ -21,11 +21,12 @@ | |||
520 | 21 | 21 | ||
521 | 22 | using Gtk; | 22 | using Gtk; |
522 | 23 | 23 | ||
524 | 24 | public class Noise.FastGrid : IconView { | 24 | public class Noise.FastGrid : Widgets.TileView { |
525 | 25 | 25 | ||
526 | 26 | public enum Column { | 26 | public enum Column { |
527 | 27 | PIXBUF, | 27 | PIXBUF, |
529 | 28 | MARKUP, | 28 | TITLE, |
530 | 29 | SUBTITLE, | ||
531 | 29 | TOOLTIP, | 30 | TOOLTIP, |
532 | 30 | N_COLUMNS | 31 | N_COLUMNS |
533 | 31 | } | 32 | } |
534 | @@ -50,9 +51,10 @@ | |||
535 | 50 | set_table (table, true); | 51 | set_table (table, true); |
536 | 51 | set_model (fm); | 52 | set_model (fm); |
537 | 52 | 53 | ||
541 | 53 | set_pixbuf_column (Column.PIXBUF); | 54 | image_column = Column.PIXBUF; |
542 | 54 | set_markup_column (Column.MARKUP); | 55 | title_column = Column.TITLE; |
543 | 55 | set_tooltip_column (Column.TOOLTIP); | 56 | subtitle_column = Column.SUBTITLE; |
544 | 57 | tooltip_column = Column.TOOLTIP; | ||
545 | 56 | } | 58 | } |
546 | 57 | 59 | ||
547 | 58 | public void set_search_func (ViewSearchFunc func) { | 60 | public void set_search_func (ViewSearchFunc func) { |
548 | 59 | 61 | ||
549 | === modified file 'src/Widgets/FastView/FastGridModel.vala' | |||
550 | --- src/Widgets/FastView/FastGridModel.vala 2012-10-27 16:25:32 +0000 | |||
551 | +++ src/Widgets/FastView/FastGridModel.vala 2013-09-26 03:02:55 +0000 | |||
552 | @@ -28,6 +28,8 @@ | |||
553 | 28 | return typeof(string); | 28 | return typeof(string); |
554 | 29 | else if(col == 2) | 29 | else if(col == 2) |
555 | 30 | return typeof(string); | 30 | return typeof(string); |
556 | 31 | else if(col == 3) | ||
557 | 32 | return typeof(string); | ||
558 | 31 | else | 33 | else |
559 | 32 | return typeof(GLib.Object); | 34 | return typeof(GLib.Object); |
560 | 33 | } | 35 | } |
561 | @@ -49,7 +51,7 @@ | |||
562 | 49 | } | 51 | } |
563 | 50 | 52 | ||
564 | 51 | public int get_n_columns () { | 53 | public int get_n_columns () { |
566 | 52 | return 4; | 54 | return 5; |
567 | 53 | } | 55 | } |
568 | 54 | 56 | ||
569 | 55 | public TreePath? get_path (TreeIter iter) { | 57 | public TreePath? get_path (TreeIter iter) { |
570 | 56 | 58 | ||
571 | === added directory 'src/Widgets/FastView/TileView' | |||
572 | === added file 'src/Widgets/FastView/TileView/ImageUtils.vala' | |||
573 | --- src/Widgets/FastView/TileView/ImageUtils.vala 1970-01-01 00:00:00 +0000 | |||
574 | +++ src/Widgets/FastView/TileView/ImageUtils.vala 2013-09-26 03:02:55 +0000 | |||
575 | @@ -0,0 +1,51 @@ | |||
576 | 1 | /** | ||
577 | 2 | * Copyright 2009-2013 Yorba Foundation | ||
578 | 3 | * | ||
579 | 4 | * This software is licensed under the GNU Lesser General Public License | ||
580 | 5 | * (version 3 or later). See the COPYING file in this distribution. | ||
581 | 6 | * | ||
582 | 7 | * (Code taken from Shotwell Photo Manager: shotwell/src/util/image.vala) | ||
583 | 8 | */ | ||
584 | 9 | |||
585 | 10 | namespace Noise.ImageUtils { | ||
586 | 11 | internal void shift_colors (Gdk.Pixbuf pixbuf, int red, int green, int blue, int alpha) { | ||
587 | 12 | assert (red >= -255 && red <= 255); | ||
588 | 13 | assert (green >= -255 && green <= 255); | ||
589 | 14 | assert (blue >= -255 && blue <= 255); | ||
590 | 15 | assert (alpha >= -255 && alpha <= 255); | ||
591 | 16 | |||
592 | 17 | int width = pixbuf.get_width (); | ||
593 | 18 | int height = pixbuf.get_height (); | ||
594 | 19 | int rowstride = pixbuf.get_rowstride (); | ||
595 | 20 | int channels = pixbuf.get_n_channels (); | ||
596 | 21 | uchar *pixels = pixbuf.get_pixels (); | ||
597 | 22 | |||
598 | 23 | assert (channels >= 3); | ||
599 | 24 | assert (pixbuf.get_colorspace () == Gdk.Colorspace.RGB); | ||
600 | 25 | assert (pixbuf.get_bits_per_sample () == 8); | ||
601 | 26 | |||
602 | 27 | for (int y = 0; y < height; y++) { | ||
603 | 28 | int y_offset = y * rowstride; | ||
604 | 29 | |||
605 | 30 | for (int x = 0; x < width; x++) { | ||
606 | 31 | int offset = y_offset + (x * channels); | ||
607 | 32 | |||
608 | 33 | if (red != 0) | ||
609 | 34 | pixels[offset] = shift_color_byte (pixels[offset], red); | ||
610 | 35 | |||
611 | 36 | if (green != 0) | ||
612 | 37 | pixels[offset + 1] = shift_color_byte (pixels[offset + 1], green); | ||
613 | 38 | |||
614 | 39 | if (blue != 0) | ||
615 | 40 | pixels[offset + 2] = shift_color_byte (pixels[offset + 2], blue); | ||
616 | 41 | |||
617 | 42 | if (alpha != 0 && channels >= 4) | ||
618 | 43 | pixels[offset + 3] = shift_color_byte (pixels[offset + 3], alpha); | ||
619 | 44 | } | ||
620 | 45 | } | ||
621 | 46 | } | ||
622 | 47 | |||
623 | 48 | internal inline uchar shift_color_byte (int b, int shift) { | ||
624 | 49 | return (uchar) (b + shift).clamp (0, 255); | ||
625 | 50 | } | ||
626 | 51 | } | ||
627 | 0 | 52 | ||
628 | === added file 'src/Widgets/FastView/TileView/TileRenderer.vala' | |||
629 | --- src/Widgets/FastView/TileView/TileRenderer.vala 1970-01-01 00:00:00 +0000 | |||
630 | +++ src/Widgets/FastView/TileView/TileRenderer.vala 2013-09-26 03:02:55 +0000 | |||
631 | @@ -0,0 +1,234 @@ | |||
632 | 1 | /** | ||
633 | 2 | * Copyright 2013 elementary | ||
634 | 3 | * | ||
635 | 4 | * This software is licensed under the GNU Lesser General Public License | ||
636 | 5 | * (version 3 or later). See the COPYING file in this distribution. | ||
637 | 6 | */ | ||
638 | 7 | |||
639 | 8 | internal class Noise.Widgets.TileRenderer : Gtk.CellRenderer { | ||
640 | 9 | public Gdk.Pixbuf pixbuf { get; set; } | ||
641 | 10 | public string title { get; set; } | ||
642 | 11 | public string subtitle { get; set; } | ||
643 | 12 | |||
644 | 13 | private const int BRIGHTEN_SHIFT = 0x18; | ||
645 | 14 | private const int IMAGE_SHADOW_MARGIN = 12; | ||
646 | 15 | private const int IMAGE_SHADOW_RADIUS = 4; | ||
647 | 16 | private const double IMAGE_SHADOW_ALPHA = 0.65; | ||
648 | 17 | |||
649 | 18 | private int last_image_width = 0; | ||
650 | 19 | private int last_image_height = 0; | ||
651 | 20 | private Granite.Drawing.BufferSurface shadow_buffer; | ||
652 | 21 | private Pango.Rectangle title_text_logical_rect; | ||
653 | 22 | private Pango.Rectangle subtitle_text_logical_rect; | ||
654 | 23 | private Pango.Layout title_text_layout; | ||
655 | 24 | private Pango.Layout subtitle_text_layout; | ||
656 | 25 | private Gtk.Border margin; | ||
657 | 26 | private Gtk.Border padding; | ||
658 | 27 | private Gtk.Border border; | ||
659 | 28 | |||
660 | 29 | [Deprecated (replacement = "Gtk.CellRenderer.get_preferred_size", since = "")] | ||
661 | 30 | public override void get_size (Gtk.Widget widget, Gdk.Rectangle? cell_area, | ||
662 | 31 | out int x_offset, out int y_offset, | ||
663 | 32 | out int width, out int height) | ||
664 | 33 | { | ||
665 | 34 | x_offset = y_offset = width = height = 0; | ||
666 | 35 | } | ||
667 | 36 | |||
668 | 37 | public override Gtk.SizeRequestMode get_request_mode () { | ||
669 | 38 | return Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH; | ||
670 | 39 | } | ||
671 | 40 | |||
672 | 41 | public override void get_preferred_width (Gtk.Widget widget, | ||
673 | 42 | out int minimum_size, | ||
674 | 43 | out int natural_size) | ||
675 | 44 | { | ||
676 | 45 | update_layout_properties (widget); | ||
677 | 46 | |||
678 | 47 | int width = compute_total_image_width () | ||
679 | 48 | + margin.left + margin.right | ||
680 | 49 | + padding.left + padding.right | ||
681 | 50 | + border.left + border.right | ||
682 | 51 | + 2 * (int) xpad; | ||
683 | 52 | |||
684 | 53 | minimum_size = natural_size = width; | ||
685 | 54 | } | ||
686 | 55 | |||
687 | 56 | public override void get_preferred_height_for_width (Gtk.Widget widget, int width, | ||
688 | 57 | out int minimum_height, | ||
689 | 58 | out int natural_height) | ||
690 | 59 | { | ||
691 | 60 | update_layout_properties (widget); | ||
692 | 61 | |||
693 | 62 | int height = compute_total_image_height () | ||
694 | 63 | + title_text_logical_rect.height | ||
695 | 64 | + subtitle_text_logical_rect.height | ||
696 | 65 | + margin.top + margin.bottom | ||
697 | 66 | + padding.top + padding.bottom | ||
698 | 67 | + border.top + border.bottom | ||
699 | 68 | + 2 * (int) ypad; | ||
700 | 69 | |||
701 | 70 | minimum_height = natural_height = height; | ||
702 | 71 | } | ||
703 | 72 | |||
704 | 73 | public override void render (Cairo.Context cr, Gtk.Widget widget, Gdk.Rectangle bg_area, | ||
705 | 74 | Gdk.Rectangle cell_area, Gtk.CellRendererState flags) | ||
706 | 75 | { | ||
707 | 76 | update_layout_properties (widget); | ||
708 | 77 | |||
709 | 78 | Gdk.Rectangle aligned_area = get_aligned_area (widget, flags, cell_area); | ||
710 | 79 | |||
711 | 80 | int x = aligned_area.x; | ||
712 | 81 | int y = aligned_area.y; | ||
713 | 82 | int width = aligned_area.width; | ||
714 | 83 | int height = aligned_area.height; | ||
715 | 84 | |||
716 | 85 | // Apply margin | ||
717 | 86 | x += margin.right; | ||
718 | 87 | y += margin.top; | ||
719 | 88 | width -= margin.left + margin.right; | ||
720 | 89 | height -= margin.top + margin.bottom; | ||
721 | 90 | |||
722 | 91 | var ctx = widget.get_style_context (); | ||
723 | 92 | |||
724 | 93 | // Apply border width and padding offsets | ||
725 | 94 | x += border.right + padding.right; | ||
726 | 95 | y += border.top + padding.top; | ||
727 | 96 | |||
728 | 97 | width -= border.left + border.right + padding.left + padding.right; | ||
729 | 98 | height -= border.top + border.bottom + padding.top + padding.bottom; | ||
730 | 99 | |||
731 | 100 | render_image (ctx, cr, x, ref y, width, flags); | ||
732 | 101 | render_title (ctx, cr, x, ref y, width); | ||
733 | 102 | render_subtitle (ctx, cr, x, y, width); | ||
734 | 103 | } | ||
735 | 104 | |||
736 | 105 | private void render_image (Gtk.StyleContext ctx, Cairo.Context cr, int x, | ||
737 | 106 | ref int y, int width, Gtk.CellRendererState flags) | ||
738 | 107 | { | ||
739 | 108 | int image_width = compute_total_image_width (); | ||
740 | 109 | int image_height = compute_total_image_height (); | ||
741 | 110 | int offset = IMAGE_SHADOW_MARGIN; | ||
742 | 111 | |||
743 | 112 | // this cell renderer is not optimized for pixbufs of different dimensions | ||
744 | 113 | if (shadow_buffer == null || image_width != last_image_width | ||
745 | 114 | || image_height != last_image_height) | ||
746 | 115 | { | ||
747 | 116 | shadow_buffer = new Granite.Drawing.BufferSurface (image_width, image_height); | ||
748 | 117 | |||
749 | 118 | var context = shadow_buffer.context; | ||
750 | 119 | context.rectangle (offset, offset, pixbuf.width, pixbuf.height); | ||
751 | 120 | context.set_source_rgba (0, 0, 0, IMAGE_SHADOW_ALPHA); | ||
752 | 121 | context.fill (); | ||
753 | 122 | shadow_buffer.exponential_blur (IMAGE_SHADOW_RADIUS); | ||
754 | 123 | |||
755 | 124 | last_image_width = image_width; | ||
756 | 125 | last_image_height = image_height; | ||
757 | 126 | } | ||
758 | 127 | |||
759 | 128 | x += (width - image_width) / 2; | ||
760 | 129 | |||
761 | 130 | cr.set_source_surface (shadow_buffer.surface, x, y); | ||
762 | 131 | cr.paint (); | ||
763 | 132 | |||
764 | 133 | Gdk.Pixbuf image; | ||
765 | 134 | if (should_brighten_image (flags)) | ||
766 | 135 | image = get_brightened_pixbuf (pixbuf); | ||
767 | 136 | else | ||
768 | 137 | image = pixbuf; | ||
769 | 138 | |||
770 | 139 | ctx.render_icon (cr, image, x + offset, y + offset); | ||
771 | 140 | |||
772 | 141 | if (should_draw_highlight (flags)) { | ||
773 | 142 | ctx.add_class (Gtk.STYLE_CLASS_IMAGE); | ||
774 | 143 | ctx.render_frame (cr, x + offset - border.left, | ||
775 | 144 | y + offset - border.top, | ||
776 | 145 | pixbuf.width + border.left + border.right, | ||
777 | 146 | pixbuf.height + border.top + border.bottom); | ||
778 | 147 | } | ||
779 | 148 | |||
780 | 149 | y += image_height; | ||
781 | 150 | } | ||
782 | 151 | |||
783 | 152 | private void render_title (Gtk.StyleContext ctx, Cairo.Context cr, int x, | ||
784 | 153 | ref int y, int width) | ||
785 | 154 | { | ||
786 | 155 | // Center title layout horizontally | ||
787 | 156 | int offset = (width - title_text_logical_rect.width) / 2; | ||
788 | 157 | x += title_text_logical_rect.x + int.max (0, offset); | ||
789 | 158 | |||
790 | 159 | ctx.add_class ("title-text"); | ||
791 | 160 | ctx.render_layout (cr, x, y, title_text_layout); | ||
792 | 161 | ctx.remove_class ("title-text"); | ||
793 | 162 | |||
794 | 163 | y += title_text_logical_rect.height; | ||
795 | 164 | } | ||
796 | 165 | |||
797 | 166 | private void render_subtitle (Gtk.StyleContext ctx, Cairo.Context cr, int x, | ||
798 | 167 | int y, int width) | ||
799 | 168 | { | ||
800 | 169 | // Center title layout horizontally | ||
801 | 170 | int offset = (width - subtitle_text_logical_rect.width) / 2; | ||
802 | 171 | x += subtitle_text_logical_rect.x + int.max (0, offset); | ||
803 | 172 | |||
804 | 173 | ctx.render_layout (cr, x, y, subtitle_text_layout); | ||
805 | 174 | } | ||
806 | 175 | |||
807 | 176 | private void update_layout_properties (Gtk.Widget widget) { | ||
808 | 177 | var ctx = widget.get_style_context (); | ||
809 | 178 | var state = ctx.get_state (); | ||
810 | 179 | |||
811 | 180 | ctx.save (); | ||
812 | 181 | ctx.add_class (Gtk.STYLE_CLASS_IMAGE); | ||
813 | 182 | margin = ctx.get_margin (state); | ||
814 | 183 | padding = ctx.get_padding (state); | ||
815 | 184 | border = ctx.get_border (state); | ||
816 | 185 | |||
817 | 186 | subtitle_text_layout = widget.create_pango_layout (subtitle); | ||
818 | 187 | unowned Pango.FontDescription font_description; | ||
819 | 188 | ctx.get (state, Gtk.STYLE_PROPERTY_FONT, out font_description); | ||
820 | 189 | subtitle_text_layout.set_font_description (font_description); | ||
821 | 190 | subtitle_text_layout.set_ellipsize (Pango.EllipsizeMode.END); | ||
822 | 191 | subtitle_text_layout.set_alignment (Pango.Alignment.LEFT); | ||
823 | 192 | int text_width = pixbuf.width * Pango.SCALE; | ||
824 | 193 | subtitle_text_layout.set_width (text_width); | ||
825 | 194 | |||
826 | 195 | ctx.add_class ("title-text"); | ||
827 | 196 | title_text_layout = widget.create_pango_layout (title); | ||
828 | 197 | ctx.get (state, Gtk.STYLE_PROPERTY_FONT, out font_description); | ||
829 | 198 | title_text_layout.set_font_description (font_description); | ||
830 | 199 | title_text_layout.set_width (text_width); | ||
831 | 200 | title_text_layout.set_ellipsize (Pango.EllipsizeMode.END); | ||
832 | 201 | title_text_layout.set_alignment (Pango.Alignment.LEFT); | ||
833 | 202 | ctx.restore (); | ||
834 | 203 | |||
835 | 204 | Pango.Rectangle ink_rect; | ||
836 | 205 | title_text_layout.get_pixel_extents (out ink_rect, out title_text_logical_rect); | ||
837 | 206 | subtitle_text_layout.get_pixel_extents (out ink_rect, out subtitle_text_logical_rect); | ||
838 | 207 | } | ||
839 | 208 | |||
840 | 209 | private int compute_total_image_width () { | ||
841 | 210 | return pixbuf != null ? pixbuf.width + 2 * IMAGE_SHADOW_MARGIN : 0; | ||
842 | 211 | } | ||
843 | 212 | |||
844 | 213 | private int compute_total_image_height () { | ||
845 | 214 | return pixbuf != null ? pixbuf.height + 2 * IMAGE_SHADOW_MARGIN : 0; | ||
846 | 215 | } | ||
847 | 216 | |||
848 | 217 | private static bool should_brighten_image (Gtk.CellRendererState flags) { | ||
849 | 218 | return (flags & Gtk.CellRendererState.PRELIT) != 0; | ||
850 | 219 | } | ||
851 | 220 | |||
852 | 221 | private static bool should_draw_highlight (Gtk.CellRendererState flags) { | ||
853 | 222 | return (flags & Gtk.CellRendererState.SELECTED) != 0; | ||
854 | 223 | } | ||
855 | 224 | |||
856 | 225 | private static Gdk.Pixbuf? get_brightened_pixbuf (Gdk.Pixbuf pixbuf) { | ||
857 | 226 | if (pixbuf == null) | ||
858 | 227 | return null; | ||
859 | 228 | |||
860 | 229 | // create a new lightened pixbuf to display | ||
861 | 230 | var brightened = pixbuf.copy (); | ||
862 | 231 | ImageUtils.shift_colors (brightened, BRIGHTEN_SHIFT, BRIGHTEN_SHIFT, BRIGHTEN_SHIFT, 0); | ||
863 | 232 | return brightened; | ||
864 | 233 | } | ||
865 | 234 | } | ||
866 | 0 | 235 | ||
867 | === added file 'src/Widgets/FastView/TileView/TileView.vala' | |||
868 | --- src/Widgets/FastView/TileView/TileView.vala 1970-01-01 00:00:00 +0000 | |||
869 | +++ src/Widgets/FastView/TileView/TileView.vala 2013-09-26 03:02:55 +0000 | |||
870 | @@ -0,0 +1,70 @@ | |||
871 | 1 | /** | ||
872 | 2 | * Copyright 2013 elementary | ||
873 | 3 | * | ||
874 | 4 | * This software is licensed under the GNU Lesser General Public License | ||
875 | 5 | * (version 3 or later). See the COPYING file in this distribution. | ||
876 | 6 | */ | ||
877 | 7 | |||
878 | 8 | public class Noise.Widgets.TileView : Gtk.IconView { | ||
879 | 9 | private const string STYLESHEET = """ | ||
880 | 10 | /* general background color and texture */ | ||
881 | 11 | .tile-view { | ||
882 | 12 | color: alpha(@fg_color, 0.95); | ||
883 | 13 | background-color: @base_color; | ||
884 | 14 | } | ||
885 | 15 | |||
886 | 16 | /* workaround: suppress default cell borders for icon view */ | ||
887 | 17 | .tile-view.cell { | ||
888 | 18 | background-image: none; | ||
889 | 19 | background-color: @transparent; | ||
890 | 20 | border-width: 0; | ||
891 | 21 | border-style: solid; | ||
892 | 22 | border-color: @transparent; | ||
893 | 23 | box-shadow: inset 0 0 @transparent; | ||
894 | 24 | } | ||
895 | 25 | |||
896 | 26 | /* image selection frame */ | ||
897 | 27 | .tile-view.cell.image { | ||
898 | 28 | border-width: 3px; | ||
899 | 29 | border-radius: 3px; | ||
900 | 30 | border-color: alpha(@selected_bg_color, 0.95); | ||
901 | 31 | } | ||
902 | 32 | |||
903 | 33 | /* apply bold font to titles */ | ||
904 | 34 | .tile-view.cell.title-text { | ||
905 | 35 | font-weight: bold; | ||
906 | 36 | color: @fg_color; | ||
907 | 37 | } | ||
908 | 38 | """; | ||
909 | 39 | |||
910 | 40 | private Gtk.CellRenderer cell_renderer = new TileRenderer (); | ||
911 | 41 | |||
912 | 42 | public int image_column { | ||
913 | 43 | set { | ||
914 | 44 | add_attribute (cell_renderer, "pixbuf", value); | ||
915 | 45 | } | ||
916 | 46 | } | ||
917 | 47 | |||
918 | 48 | public int title_column { | ||
919 | 49 | set { | ||
920 | 50 | add_attribute (cell_renderer, "title", value); | ||
921 | 51 | } | ||
922 | 52 | } | ||
923 | 53 | |||
924 | 54 | public int subtitle_column { | ||
925 | 55 | set { | ||
926 | 56 | add_attribute (cell_renderer, "subtitle", value); | ||
927 | 57 | } | ||
928 | 58 | } | ||
929 | 59 | |||
930 | 60 | public TileView () { | ||
931 | 61 | pack_start (cell_renderer, false); | ||
932 | 62 | apply_default_theme (); | ||
933 | 63 | } | ||
934 | 64 | |||
935 | 65 | private void apply_default_theme () { | ||
936 | 66 | get_style_context ().remove_class (Gtk.STYLE_CLASS_VIEW); | ||
937 | 67 | Granite.Widgets.Utils.set_theming (this, STYLESHEET, "tile-view", | ||
938 | 68 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); | ||
939 | 69 | } | ||
940 | 70 | } | ||
941 | 0 | 71 | ||
942 | === modified file 'src/Widgets/InfoPanel.vala' | |||
943 | --- src/Widgets/InfoPanel.vala 2013-02-26 21:56:08 +0000 | |||
944 | +++ src/Widgets/InfoPanel.vala 2013-09-26 03:02:55 +0000 | |||
945 | @@ -63,7 +63,6 @@ | |||
946 | 63 | title = new Gtk.Label(""); | 63 | title = new Gtk.Label(""); |
947 | 64 | artist = new Gtk.Label(""); | 64 | artist = new Gtk.Label(""); |
948 | 65 | coverArt = new Gtk.Image(); | 65 | coverArt = new Gtk.Image(); |
949 | 66 | coverArt.set_size_request (Icons.ALBUM_VIEW_IMAGE_SIZE, Icons.ALBUM_VIEW_IMAGE_SIZE); | ||
950 | 67 | rating = new Granite.Widgets.Rating (true, Gtk.IconSize.MENU, true); // centered = true | 66 | rating = new Granite.Widgets.Rating (true, Gtk.IconSize.MENU, true); // centered = true |
951 | 68 | album = new Gtk.Label(""); | 67 | album = new Gtk.Label(""); |
952 | 69 | year_label = new Gtk.Label(""); | 68 | year_label = new Gtk.Label(""); |
953 | @@ -138,8 +137,11 @@ | |||
954 | 138 | } | 137 | } |
955 | 139 | 138 | ||
956 | 140 | private void update_cover_art () { | 139 | private void update_cover_art () { |
959 | 141 | if (current_media != null) | 140 | if (current_media != null) { |
960 | 142 | coverArt.set_from_pixbuf (CoverartCache.instance.get_cover (current_media)); | 141 | var cover_art = CoverartCache.instance.get_cover (current_media); |
961 | 142 | var cover_art_with_shadow = PixbufUtils.render_pixbuf_shadow (cover_art); | ||
962 | 143 | coverArt.set_from_pixbuf (cover_art_with_shadow); | ||
963 | 144 | } | ||
964 | 143 | } | 145 | } |
965 | 144 | 146 | ||
966 | 145 | private void ratingChanged (int new_rating) { | 147 | private void ratingChanged (int new_rating) { |
Please note this code is not supposed to work correctly on Luna, but on GTK+ 3.8 or newer (Ubuntu 13.04).