src/com/jetbrains/WindowDecorations.java (22 lines of code) (raw):
/*
* Copyright 2000-2024 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jetbrains;
import java.awt.*;
import java.util.Map;
/**
* Window decorations consist of title bar, window controls and border.
* @see WindowDecorations.CustomTitleBar
*/
@Service
@Provided
public interface WindowDecorations {
/**
* If {@code customTitleBar} is not null, system-provided title bar is removed and client area is extended to the
* top of the frame with window controls painted over the client area.
* {@code customTitleBar=null} resets to the default appearance with system-provided title bar.
* @param frame frame to setup custom title bar on
* @param customTitleBar new title bar instance, or null
* @see CustomTitleBar
* @see #createCustomTitleBar()
*/
void setCustomTitleBar(Frame frame, CustomTitleBar customTitleBar);
/**
* If {@code customTitleBar} is not null, system-provided title bar is removed and client area is extended to the
* top of the dialog with window controls painted over the client area.
* {@code customTitleBar=null} resets to the default appearance with system-provided title bar.
* @param dialog dialog to setup custom title bar on
* @param customTitleBar new title bar instance, or null
* @see CustomTitleBar
* @see #createCustomTitleBar()
*/
void setCustomTitleBar(Dialog dialog, CustomTitleBar customTitleBar);
/**
* You must {@linkplain CustomTitleBar#setHeight(float) set title bar height} before adding it to a window.
* @return new CustomTitleBar instance
* @see CustomTitleBar
* @see #setCustomTitleBar(Frame, CustomTitleBar)
* @see #setCustomTitleBar(Dialog, CustomTitleBar)
*/
CustomTitleBar createCustomTitleBar();
/**
* Custom title bar allows merging of window content with native title bar,
* which is done by treating title bar as part of client area, but with some
* special behavior like dragging or maximizing on double click.
* Custom title bar has {@linkplain CustomTitleBar#getHeight() height} and controls.
* Behavior is platform-dependent, only macOS and Windows are supported.
* @see #setCustomTitleBar(Frame, CustomTitleBar)
*/
@Provided
interface CustomTitleBar {
/**
* Get title bar height, measured in pixels from the top of client area, i.e. excluding top frame border.
* @return title bar height
*/
float getHeight();
/**
* Set title bar height, measured in pixels from the top of client area,
* i.e. excluding top frame border. Must be > 0.
* @param height new title bar height
*/
void setHeight(float height);
/**
* Get all properties set for the title bar.
* @return map of properties
* @see #putProperty(String, Object)
*/
Map<String, Object> getProperties();
/**
* Put all properties from the map.
* @param m map of properties
* @see #putProperty(String, Object)
*/
void putProperties(Map<String, ?> m);
/**
* Windows and macOS properties:
* <ul>
* <li>{@code controls.visible} : {@link Boolean} - whether title bar controls
* (minimize/maximize/close buttons) are visible, default = true.</li>
* </ul>
* Windows properties:
* <ul>
* <li>{@code controls.width} : {@link Number} - width of block of buttons (not individual buttons).
* Note that dialogs have only one button, while frames usually have 3 of them.</li>
* <li>{@code controls.dark} : {@link Boolean} - whether to use dark or light color theme
* (light or dark icons respectively).</li>
* <li>{@code controls.rtl} : {@link Boolean} - Override the title bar alignment to become RTL.
* (LTR (Default) = Buttons on the right; RTL = Buttons on the left)</li>
* <li>{@code controls.<layer>.<state>} : {@link Color} - precise control over button colors,
* where {@code <layer>} is one of:
* <ul><li>{@code foreground}</li><li>{@code background}</li></ul>
* and {@code <state>} is one of:
* <ul>
* <li>{@code normal}</li>
* <li>{@code hovered}</li>
* <li>{@code pressed}</li>
* <li>{@code disabled}</li>
* <li>{@code inactive}</li>
* </ul>
* </ul>
*
* @param key property key
* @param value property value
*/
void putProperty(String key, Object value);
/**
* Get space occupied by title bar controls on the left (px).
* @return left inset
*/
float getLeftInset();
/**
* Get space occupied by title bar controls on the right (px).
* @return right inset
*/
float getRightInset();
/**
* By default, any component which has no cursor or mouse event listeners set is considered transparent for
* native title bar actions. That is, dragging simple JPanel in title bar area will drag the
* window, but dragging a JButton will not. Adding mouse listener to a component will prevent any native actions
* inside bounds of that component.
* <p>
* This method gives you precise control of whether to allow native title bar actions or not.
* <ul>
* <li>{@code client=true} means that mouse is currently over a client area. Native title bar behavior is disabled.</li>
* <li>{@code client=false} means that mouse is currently over a non-client area. Native title bar behavior is enabled.</li>
* </ul>
* <em>Intended usage:</em>
* <ul>
* <li><em>This method must be called in response to all {@linkplain java.awt.event.MouseEvent mouse events}
* except {@link java.awt.event.MouseEvent#MOUSE_EXITED} and {@link java.awt.event.MouseEvent#MOUSE_WHEEL}.</em></li>
* <li><em>This method is called per-event, i.e. when component has multiple listeners, you only need to call it once.</em></li>
* <li><em>If this method hadn't been called, title bar behavior is reverted back to default upon processing the event.</em></li>
* </ul>
* Note that hit test value is relevant only for title bar area, e.g. calling
* {@code forceHitTest(false)} will not make window draggable via non-title bar area.
*
* <h4>Example:</h4>
* Suppose you have a {@code JPanel} in the title bar area. You want it to respond to right-click for
* some popup menu, but also retain native drag and double-click behavior.
* <pre>
* CustomTitleBar titlebar = ...;
* JPanel panel = ...;
* MouseAdapter adapter = new MouseAdapter() {
* private void hit() { titlebar.forceHitTest(false); }
* public void mouseClicked(MouseEvent e) {
* hit();
* if (e.getButton() == MouseEvent.BUTTON3) ...;
* }
* public void mousePressed(MouseEvent e) { hit(); }
* public void mouseReleased(MouseEvent e) { hit(); }
* public void mouseEntered(MouseEvent e) { hit(); }
* public void mouseDragged(MouseEvent e) { hit(); }
* public void mouseMoved(MouseEvent e) { hit(); }
* };
* panel.addMouseListener(adapter);
* panel.addMouseMotionListener(adapter);
* </pre>
*
* @param client whether to force client, or non-client area response
*/
void forceHitTest(boolean client);
/**
* Get window, title bar is attached to.
* @return parent window
*/
Window getContainingWindow();
}
}