KiCad PCB EDA Suite
Loading...
Searching...
No Matches
gtk/ui.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2020 Ian McInerney <Ian.S.McInerney at ieee.org>
5 * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <kiplatform/ui.h>
22
23#include <wx/choice.h>
24#include <wx/nonownedwnd.h>
25#include <wx/settings.h>
26#include <wx/window.h>
27
28#include <gtk/gtk.h>
29#include <gdk/gdk.h>
30
32{
33 wxColour bg = wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW );
34
35 // Weighted W3C formula
36 double brightness = ( bg.Red() / 255.0 ) * 0.299 +
37 ( bg.Green() / 255.0 ) * 0.587 +
38 ( bg.Blue() / 255.0 ) * 0.117;
39
40 return brightness < 0.5;
41}
42
43
44void KIPLATFORM::UI::ForceFocus( wxWindow* aWindow )
45{
46 aWindow->SetFocus();
47}
48
49
50bool KIPLATFORM::UI::IsWindowActive( wxWindow* aWindow )
51{
52 if( !aWindow )
53 return false;
54
55 GtkWindow* window = GTK_WINDOW( aWindow->GetHandle() );
56
57 if( window )
58 return gtk_window_is_active( window );
59
60 // We shouldn't really ever reach this point
61 return false;
62}
63
64
65void KIPLATFORM::UI::ReparentQuasiModal( wxNonOwnedWindow* aWindow )
66{
67 // Not needed on this platform
68}
69
70
72{
73 // Not needed on this platform
74}
75
76
77bool KIPLATFORM::UI::IsStockCursorOk( wxStockCursor aCursor )
78{
79 switch( aCursor )
80 {
81 case wxCURSOR_BULLSEYE:
82 case wxCURSOR_HAND:
83 case wxCURSOR_ARROW:
84 case wxCURSOR_BLANK:
85 return true;
86 default:
87 return false;
88 }
89}
90
91
100static void disable_area_apply_attributes_cb( GtkWidget* pItem, gpointer userdata )
101{
102 // GTK needs this enormous chain to get the actual type of item that we want
103 GtkMenuItem* pMenuItem = GTK_MENU_ITEM( pItem );
104 GtkWidget* child = gtk_bin_get_child( GTK_BIN( pMenuItem ) );
105 GtkCellView* pCellView = GTK_CELL_VIEW( child );
106 GtkCellLayout* pCellLayout = GTK_CELL_LAYOUT( pCellView );
107 GtkCellArea* pCellArea = gtk_cell_layout_get_area( pCellLayout );
108
109 g_signal_handlers_block_matched( pCellArea, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, userdata );
110}
111
112
113void KIPLATFORM::UI::LargeChoiceBoxHack( wxChoice* aChoice )
114{
115 AtkObject* atkObj = gtk_combo_box_get_popup_accessible( GTK_COMBO_BOX( aChoice->m_widget ) );
116
117 if( !atkObj || !GTK_IS_ACCESSIBLE( atkObj ) )
118 return;
119
120 GtkWidget* widget = gtk_accessible_get_widget( GTK_ACCESSIBLE( atkObj ) );
121
122 if( !widget || !GTK_IS_MENU( widget ) )
123 return;
124
125 GtkMenu* menu = GTK_MENU( widget );
126
127 gtk_container_foreach( GTK_CONTAINER( menu ), disable_area_apply_attributes_cb, menu );
128}
129
130
131void KIPLATFORM::UI::EllipsizeChoiceBox( wxChoice* aChoice )
132{
133 // This function is based on the code inside the function post_process_ui in
134 // gtkfilechooserwidget.c
135 GList* cells = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( aChoice->m_widget ) );
136
137 if( !cells )
138 return;
139
140 GtkCellRenderer* cell = (GtkCellRenderer*) cells->data;
141
142 if( !cell )
143 return;
144
145 g_object_set( G_OBJECT( cell ), "ellipsize", PANGO_ELLIPSIZE_END, nullptr );
146
147 // Only the list of cells must be freed, the renderer isn't ours to free
148 g_list_free( cells );
149}
150
151
152double KIPLATFORM::UI::GetPixelScaleFactor( const wxWindow* aWindow )
153{
154 double val = 1.0;
155
156 GtkWidget* widget = static_cast<GtkWidget*>( aWindow->GetHandle() );
157
158 if( widget && gtk_check_version( 3, 10, 0 ) == nullptr )
159 val = gtk_widget_get_scale_factor( widget );
160
161 return val;
162}
163
164
165double KIPLATFORM::UI::GetContentScaleFactor( const wxWindow* aWindow )
166{
167 // TODO: Do we need something different here?
168 return GetPixelScaleFactor( aWindow );
169}
170
171
172wxSize KIPLATFORM::UI::GetUnobscuredSize( const wxWindow* aWindow )
173{
174 return wxSize( aWindow->GetSize().GetX() - wxSystemSettings::GetMetric( wxSYS_VSCROLL_X ),
175 aWindow->GetSize().GetY() - wxSystemSettings::GetMetric( wxSYS_HSCROLL_Y ) );
176}
177
178
179void KIPLATFORM::UI::SetOverlayScrolling( const wxWindow* aWindow, bool overlay )
180{
181 gtk_scrolled_window_set_overlay_scrolling( GTK_SCROLLED_WINDOW( aWindow->GetHandle() ),
182 overlay );
183}
184
185
187{
188 gboolean allowed = 1;
189
190 g_object_get( gtk_settings_get_default(), "gtk-menu-images", &allowed, NULL );
191
192 return !!allowed;
193}
194
195
196void KIPLATFORM::UI::WarpPointer( wxWindow* aWindow, int aX, int aY )
197{
198 if( !wxGetEnv( wxT( "WAYLAND_DISPLAY" ), nullptr ) )
199 {
200 aWindow->WarpPointer( aX, aY );
201 }
202 else
203 {
204 GdkDisplay* disp = gtk_widget_get_display( static_cast<GtkWidget*>( aWindow->GetHandle() ) );
205 GdkSeat* seat = gdk_display_get_default_seat( disp );
206 GdkDevice* dev = gdk_seat_get_pointer( seat );
207 GdkWindow* win = gdk_device_get_window_at_position( dev, nullptr, nullptr );
208 GdkCursor* blank_cursor = gdk_cursor_new_for_display( disp, GDK_BLANK_CURSOR );
209 GdkCursor* cur_cursor = gdk_window_get_cursor( win );
210
211 if( cur_cursor )
212 g_object_ref( cur_cursor );
213
214 gdk_window_set_cursor( win, blank_cursor );
215 aWindow->WarpPointer( aX, aY );
216 gdk_window_set_cursor( win, cur_cursor );
217 }
218}
219
220
221void KIPLATFORM::UI::ImmControl( wxWindow* aWindow, bool aEnable )
222{
223}
static void disable_area_apply_attributes_cb(GtkWidget *pItem, gpointer userdata)
The following two functions are based on the "hack" contained in the attached patch at https://gitlab...
Definition: gtk/ui.cpp:100
bool AllowIconsInMenus()
If the user has disabled icons system-wide, we check that here.
Definition: gtk/ui.cpp:186
void EllipsizeChoiceBox(wxChoice *aChoice)
Configure a wxChoice control to ellipsize the shown text in the button with the ellipses placed at th...
Definition: gtk/ui.cpp:131
void FixupCancelButtonCmdKeyCollision(wxWindow *aWindow)
Definition: gtk/ui.cpp:71
void SetOverlayScrolling(const wxWindow *aWindow, bool overlay)
Used to set overlay/non-overlay scrolling mode in a window.
Definition: gtk/ui.cpp:179
void ImmControl(wxWindow *aWindow, bool aEnable)
Configures the IME mode of a given control handle.
Definition: gtk/ui.cpp:221
double GetPixelScaleFactor(const wxWindow *aWindow)
Tries to determine the pixel scaling factor currently in use for the window.
Definition: gtk/ui.cpp:152
bool IsStockCursorOk(wxStockCursor aCursor)
Checks if we designated a stock cursor for this OS as "OK" or else we may need to load a custom one.
Definition: gtk/ui.cpp:77
double GetContentScaleFactor(const wxWindow *aWindow)
Tries to determine the content scaling factor currently in use for the window.
Definition: gtk/ui.cpp:165
void WarpPointer(wxWindow *aWindow, int aX, int aY)
Move the mouse cursor to a specific position relative to the window.
Definition: gtk/ui.cpp:196
void LargeChoiceBoxHack(wxChoice *aChoice)
Configure a wxChoice control to support a lot of entries by disabling functionality that makes adding...
Definition: gtk/ui.cpp:113
void ReparentQuasiModal(wxNonOwnedWindow *aWindow)
Move a window's parent to be the top-level window and force the window to be on top.
Definition: gtk/ui.cpp:65
bool IsWindowActive(wxWindow *aWindow)
Check to see if the given window is the currently active window (e.g.
Definition: gtk/ui.cpp:50
wxSize GetUnobscuredSize(const wxWindow *aWindow)
Tries to determine the size of the viewport of a scrollable widget (wxDataViewCtrl,...
Definition: gtk/ui.cpp:172
void ForceFocus(wxWindow *aWindow)
Pass the current focus to the window.
Definition: gtk/ui.cpp:44
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition: gtk/ui.cpp:31
std::shared_ptr< PNS_LOG_VIEWER_OVERLAY > overlay
Definition: playground.cpp:36