|
17 | 17 | import org.eclipse.wb.internal.core.utils.check.AssertionFailedException; |
18 | 18 | import org.eclipse.wb.internal.core.utils.execution.ExecutionUtils; |
19 | 19 | import org.eclipse.wb.internal.core.utils.reflect.ReflectionUtils; |
| 20 | +import org.eclipse.wb.internal.core.utils.ui.DrawUtils; |
20 | 21 | import org.eclipse.wb.internal.swt.VisualDataMockupProvider; |
21 | 22 | import org.eclipse.wb.os.OSSupport; |
22 | 23 |
|
| 24 | +import org.eclipse.draw2d.ColorConstants; |
23 | 25 | import org.eclipse.swt.SWT; |
| 26 | +import org.eclipse.swt.graphics.Color; |
24 | 27 | import org.eclipse.swt.graphics.Device; |
| 28 | +import org.eclipse.swt.graphics.GC; |
25 | 29 | import org.eclipse.swt.graphics.Image; |
26 | 30 | import org.eclipse.swt.graphics.Point; |
27 | 31 | import org.eclipse.swt.graphics.Rectangle; |
|
46 | 50 |
|
47 | 51 | public abstract class OSSupportLinux extends OSSupport { |
48 | 52 | private static Version MINIMUM_VERSION = new Version(3, 126, 0); |
| 53 | + // constants |
| 54 | + private static final Color TITLE_BORDER_COLOR_DARKEST = DrawUtils.getShiftedColor(ColorConstants.titleBackground, |
| 55 | + -24); |
| 56 | + private static final Color TITLE_BORDER_COLOR_DARKER = DrawUtils.getShiftedColor(ColorConstants.titleBackground, |
| 57 | + -16); |
49 | 58 |
|
50 | 59 | static { |
51 | 60 | System.loadLibrary("wbp3"); |
@@ -177,6 +186,8 @@ public void endShot(Object controlObject) { |
177 | 186 | public void makeShots(Object controlObject) throws Exception { |
178 | 187 | Shell shell = getShell(controlObject); |
179 | 188 | makeShots0(shell); |
| 189 | + // check for decorations and draw if needed |
| 190 | + drawDecorations(shell, shell.getDisplay()); |
180 | 191 | } |
181 | 192 |
|
182 | 193 | /** |
@@ -209,6 +220,80 @@ private void makeShots0(final Shell shell) throws Exception { |
209 | 220 | } |
210 | 221 | } |
211 | 222 |
|
| 223 | + /** |
| 224 | + * Draws decorations if available/applicable. |
| 225 | + */ |
| 226 | + private void drawDecorations(Shell shell, final Display display) { |
| 227 | + Image shellImage = (Image) shell.getData(WBP_IMAGE); |
| 228 | + // draw title if any |
| 229 | + if (shellImage != null && (shell.getStyle() & SWT.TITLE) != 0) { |
| 230 | + Rectangle shellBounds = shell.getBounds(); |
| 231 | + Rectangle imageBounds = shellImage.getBounds(); |
| 232 | + Point offset = shell.toControl(shell.getLocation()); |
| 233 | + offset.x = -offset.x; |
| 234 | + offset.y = -offset.y; |
| 235 | + // adjust by menu bar size |
| 236 | + if (shell.getMenuBar() != null) { |
| 237 | + offset.y -= getWidgetBounds(shell.getMenuBar()).height; |
| 238 | + } |
| 239 | + // draw |
| 240 | + Image decoratedShellImage = new Image(display, shellBounds); |
| 241 | + GC gc = new GC(decoratedShellImage); |
| 242 | + // draw background |
| 243 | + gc.setBackground(ColorConstants.titleBackground); |
| 244 | + gc.fillRectangle(0, 0, shellBounds.width, shellBounds.height); |
| 245 | + // title area gradient |
| 246 | + gc.setForeground(ColorConstants.titleGradient); |
| 247 | + gc.fillGradientRectangle(0, 0, shellBounds.width, offset.y, true); |
| 248 | + int buttonGapX = offset.x - 1; |
| 249 | + int nextPositionX; |
| 250 | + // buttons and title |
| 251 | + { |
| 252 | + // menu button |
| 253 | + Image buttonImage = Activator.getImage("decorations/button-menu-icon.png"); |
| 254 | + Rectangle buttonImageBounds = buttonImage.getBounds(); |
| 255 | + int buttonOffsetY = offset.y / 2 - buttonImageBounds.height / 2; |
| 256 | + gc.drawImage(buttonImage, buttonGapX, buttonOffsetY); |
| 257 | + nextPositionX = buttonGapX + buttonImageBounds.width + buttonGapX; |
| 258 | + } |
| 259 | + { |
| 260 | + // close button |
| 261 | + Image buttonImage = Activator.getImage("decorations/button-close-icon.png"); |
| 262 | + Rectangle buttonImageBounds = buttonImage.getBounds(); |
| 263 | + nextPositionX = shellBounds.width - buttonImageBounds.width - buttonGapX; |
| 264 | + int buttonOffsetY = offset.y / 2 - buttonImageBounds.height / 2; |
| 265 | + gc.drawImage(buttonImage, nextPositionX, buttonOffsetY); |
| 266 | + nextPositionX -= buttonGapX + buttonImageBounds.width; |
| 267 | + } |
| 268 | + { |
| 269 | + // maximize button |
| 270 | + Image buttonImage = Activator.getImage("decorations/button-max-icon.png"); |
| 271 | + Rectangle buttonImageBounds = buttonImage.getBounds(); |
| 272 | + int buttonOffsetY = offset.y / 2 - buttonImageBounds.height / 2; |
| 273 | + gc.drawImage(buttonImage, nextPositionX, buttonOffsetY); |
| 274 | + nextPositionX -= buttonGapX + buttonImageBounds.width; |
| 275 | + } |
| 276 | + { |
| 277 | + // minimize button |
| 278 | + Image buttonImage = Activator.getImage("decorations/button-min-icon.png"); |
| 279 | + Rectangle buttonImageBounds = buttonImage.getBounds(); |
| 280 | + int buttonOffsetY = offset.y / 2 - buttonImageBounds.height / 2; |
| 281 | + gc.drawImage(buttonImage, nextPositionX, buttonOffsetY); |
| 282 | + } |
| 283 | + // outline |
| 284 | + gc.setForeground(TITLE_BORDER_COLOR_DARKEST); |
| 285 | + gc.drawRectangle(offset.x - 1, offset.y - 1, imageBounds.width + 1, imageBounds.height + 1); |
| 286 | + gc.setForeground(TITLE_BORDER_COLOR_DARKER); |
| 287 | + gc.drawRectangle(offset.x - 2, offset.y - 2, imageBounds.width + 3, imageBounds.height + 3); |
| 288 | + // shell screen shot |
| 289 | + gc.drawImage(shellImage, offset.x, offset.y); |
| 290 | + // done |
| 291 | + gc.dispose(); |
| 292 | + shellImage.dispose(); |
| 293 | + shell.setData(WBP_IMAGE, decoratedShellImage); |
| 294 | + } |
| 295 | + } |
| 296 | + |
212 | 297 | private boolean bindImage(final Control control, final Image image) { |
213 | 298 | return ExecutionUtils.runObject(() -> { |
214 | 299 | if (control.getData(WBP_NEED_IMAGE) != null && control.getData(WBP_IMAGE) == null) { |
@@ -412,7 +497,12 @@ public Image getMenuBarVisualData(Menu menu, List<Rectangle> bounds) { |
412 | 497 | */ |
413 | 498 | @Override |
414 | 499 | public final Rectangle getMenuBarBounds(Menu menu) { |
415 | | - return getWidgetBounds(menu); |
| 500 | + Rectangle bounds = getWidgetBounds(menu); |
| 501 | + Shell shell = menu.getShell(); |
| 502 | + Point p = shell.toControl(shell.getLocation()); |
| 503 | + p.x = -p.x; |
| 504 | + p.y = -p.y - bounds.height; |
| 505 | + return new Rectangle(p.x, p.y, bounds.width, bounds.height); |
416 | 506 | } |
417 | 507 |
|
418 | 508 | @Override |
|
0 commit comments