mirror of https://github.com/rusefi/rusefi.git
auto-sync
This commit is contained in:
parent
29672f2e69
commit
fa85678d21
|
@ -298,28 +298,23 @@ static THD_WORKING_AREA(csThreadStack, UTILITY_THREAD_STACK_SIZE); // declare th
|
||||||
|
|
||||||
#define isOutOfBounds(offset) ((offset<0) || (offset) >= sizeof(engine_configuration_s))
|
#define isOutOfBounds(offset) ((offset<0) || (offset) >= sizeof(engine_configuration_s))
|
||||||
|
|
||||||
static void setShort(const int offset, const int value) {
|
|
||||||
if (isOutOfBounds(offset))
|
|
||||||
return;
|
|
||||||
uint16_t *ptr = (uint16_t *) (&((char *) engine->engineConfiguration)[offset]);
|
|
||||||
*ptr = (uint16_t) value;
|
|
||||||
scheduleMsg(&logger, "setting short @%d to %d", offset, (uint16_t) value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void getShort(int offset) {
|
static void getShort(int offset) {
|
||||||
if (isOutOfBounds(offset))
|
if (isOutOfBounds(offset))
|
||||||
return;
|
return;
|
||||||
uint16_t *ptr = (uint16_t *) (&((char *) engine->engineConfiguration)[offset]);
|
uint16_t *ptr = (uint16_t *) (&((char *) engine->engineConfiguration)[offset]);
|
||||||
uint16_t value = *ptr;
|
uint16_t value = *ptr;
|
||||||
|
/**
|
||||||
|
* this response is part of dev console API
|
||||||
|
*/
|
||||||
scheduleMsg(&logger, "short @%d is %d", offset, value);
|
scheduleMsg(&logger, "short @%d is %d", offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setInt(const int offset, const int value) {
|
static void setShort(const int offset, const int value) {
|
||||||
if (isOutOfBounds(offset))
|
if (isOutOfBounds(offset))
|
||||||
return;
|
return;
|
||||||
int *ptr = (int *) (&((char *) engine->engineConfiguration)[offset]);
|
uint16_t *ptr = (uint16_t *) (&((char *) engine->engineConfiguration)[offset]);
|
||||||
*ptr = value;
|
*ptr = (uint16_t) value;
|
||||||
scheduleMsg(&logger, "setting int @%d to %d", offset, value);
|
getShort(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void getInt(int offset) {
|
static void getInt(int offset) {
|
||||||
|
@ -327,14 +322,28 @@ static void getInt(int offset) {
|
||||||
return;
|
return;
|
||||||
int *ptr = (int *) (&((char *) engine->engineConfiguration)[offset]);
|
int *ptr = (int *) (&((char *) engine->engineConfiguration)[offset]);
|
||||||
int value = *ptr;
|
int value = *ptr;
|
||||||
|
/**
|
||||||
|
* this response is part of dev console API
|
||||||
|
*/
|
||||||
scheduleMsg(&logger, "int @%d is %d", offset, value);
|
scheduleMsg(&logger, "int @%d is %d", offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setInt(const int offset, const int value) {
|
||||||
|
if (isOutOfBounds(offset))
|
||||||
|
return;
|
||||||
|
int *ptr = (int *) (&((char *) engine->engineConfiguration)[offset]);
|
||||||
|
*ptr = value;
|
||||||
|
getInt(offset);
|
||||||
|
}
|
||||||
|
|
||||||
static void getFloat(int offset) {
|
static void getFloat(int offset) {
|
||||||
if (isOutOfBounds(offset))
|
if (isOutOfBounds(offset))
|
||||||
return;
|
return;
|
||||||
float *ptr = (float *) (&((char *) engine->engineConfiguration)[offset]);
|
float *ptr = (float *) (&((char *) engine->engineConfiguration)[offset]);
|
||||||
float value = *ptr;
|
float value = *ptr;
|
||||||
|
/**
|
||||||
|
* this response is part of dev console API
|
||||||
|
*/
|
||||||
scheduleMsg(&logger, "float @%d is %f", offset, value);
|
scheduleMsg(&logger, "float @%d is %f", offset, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,7 +362,7 @@ static void setFloat(const char *offsetStr, const char *valueStr) {
|
||||||
}
|
}
|
||||||
float *ptr = (float *) (&((char *) engine->engineConfiguration)[offset]);
|
float *ptr = (float *) (&((char *) engine->engineConfiguration)[offset]);
|
||||||
*ptr = value;
|
*ptr = value;
|
||||||
scheduleMsg(&logger, "setting float @%d to %f", offset, value);
|
getFloat(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initEngineContoller(Logging *sharedLogger, Engine *engine) {
|
void initEngineContoller(Logging *sharedLogger, Engine *engine) {
|
||||||
|
|
|
@ -278,5 +278,5 @@ int getRusEfiVersion(void) {
|
||||||
return 1; // this is here to make the compiler happy about the unused array
|
return 1; // this is here to make the compiler happy about the unused array
|
||||||
if (UNUSED_CCM_SIZE == 0)
|
if (UNUSED_CCM_SIZE == 0)
|
||||||
return 1; // this is here to make the compiler happy about the unused array
|
return 1; // this is here to make the compiler happy about the unused array
|
||||||
return 20150215;
|
return 20150216;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// This file was generated by Version2Header
|
// This file was generated by Version2Header
|
||||||
// Fri Feb 13 20:54:42 EST 2015
|
// Mon Feb 16 16:09:44 EST 2015
|
||||||
#ifndef VCS_VERSION
|
#ifndef VCS_VERSION
|
||||||
#define VCS_VERSION "6833"
|
#define VCS_VERSION "6883"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,15 +3,23 @@ package com.rusefi.config;
|
||||||
public enum FieldType {
|
public enum FieldType {
|
||||||
INT, FLOAT, ANALOG_CHART_E;
|
INT, FLOAT, ANALOG_CHART_E;
|
||||||
|
|
||||||
public String getCommand() {
|
|
||||||
|
private String getTypeForCommand() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case FLOAT:
|
case FLOAT:
|
||||||
return "get_float";
|
return "float";
|
||||||
case INT:
|
case INT:
|
||||||
case ANALOG_CHART_E:
|
case ANALOG_CHART_E:
|
||||||
default:
|
default:
|
||||||
return "get_int";
|
return "int";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getLoadCommand() {
|
||||||
|
return "get_" + getTypeForCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStoreCommand() {
|
||||||
|
return "set_" + getTypeForCommand();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,10 @@ import java.awt.event.ActionListener;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.CLEAR;
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.PAUSE;
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.RESUME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Date: 12/21/13
|
* Date: 12/21/13
|
||||||
* Andrey Belomutskiy (c) 2012-2013
|
* Andrey Belomutskiy (c) 2012-2013
|
||||||
|
@ -22,7 +26,7 @@ public class AnalogChartPanel {
|
||||||
private static final String HELP_URL = "http://rusefi.com/wiki/index.php?title=Manual:DevConsole#Analog_Chart";
|
private static final String HELP_URL = "http://rusefi.com/wiki/index.php?title=Manual:DevConsole#Analog_Chart";
|
||||||
|
|
||||||
private final TreeMap<Double, Double> values = new TreeMap<>();
|
private final TreeMap<Double, Double> values = new TreeMap<>();
|
||||||
private final AnalogChart analogChart = new AnalogChart();
|
private final AnalogChartCanvas canvas = new AnalogChartCanvas();
|
||||||
|
|
||||||
private double minX;
|
private double minX;
|
||||||
private double maxX;
|
private double maxX;
|
||||||
|
@ -39,17 +43,27 @@ public class AnalogChartPanel {
|
||||||
@Override
|
@Override
|
||||||
public void onAnalogChart(String message) {
|
public void onAnalogChart(String message) {
|
||||||
unpackValues(values, message);
|
unpackValues(values, message);
|
||||||
|
if (!paused) {
|
||||||
// MessagesCentral.getConfig().postMessage(AnalogChartPanel.class, "chart arrived, len=" + message.length());
|
|
||||||
|
|
||||||
processValues();
|
processValues();
|
||||||
UiUtils.trueRepaint(analogChart);
|
UiUtils.trueRepaint(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final JPanel upperPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
|
final JPanel upperPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
|
||||||
|
|
||||||
|
JButton clearButton = new JButton(CLEAR.getMessage());
|
||||||
|
clearButton.setMnemonic('c');
|
||||||
|
clearButton.addActionListener(new AbstractAction() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
clear();
|
||||||
|
UiUtils.trueRepaint(canvas);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
upperPanel.add(clearButton);
|
||||||
|
|
||||||
JButton imageButton = new JButton(EngineSnifferPanel.SAVE_IMAGE);
|
JButton imageButton = new JButton(EngineSnifferPanel.SAVE_IMAGE);
|
||||||
imageButton.setMnemonic('s');
|
imageButton.setMnemonic('s');
|
||||||
upperPanel.add(imageButton);
|
upperPanel.add(imageButton);
|
||||||
|
@ -61,12 +75,12 @@ public class AnalogChartPanel {
|
||||||
int rpm = RpmModel.getInstance().getValue();
|
int rpm = RpmModel.getInstance().getValue();
|
||||||
String fileName = FileLog.getDate() + "rpm_" + rpm + "_analog" + ".png";
|
String fileName = FileLog.getDate() + "rpm_" + rpm + "_analog" + ".png";
|
||||||
|
|
||||||
UiUtils.saveImageWithPrompt(fileName, upperPanel, analogChart);
|
UiUtils.saveImageWithPrompt(fileName, upperPanel, canvas);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
final JButton pauseButton = new JButton("Pause");
|
final JButton pauseButton = new JButton(PAUSE.getMessage());
|
||||||
upperPanel.add(pauseButton);
|
upperPanel.add(pauseButton);
|
||||||
|
|
||||||
upperPanel.add(new URLLabel(EngineSnifferPanel.HELP_TEXT, HELP_URL));
|
upperPanel.add(new URLLabel(EngineSnifferPanel.HELP_TEXT, HELP_URL));
|
||||||
|
@ -75,7 +89,7 @@ public class AnalogChartPanel {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
pauseButton.setText(paused ? "Resume" : "Pause");
|
pauseButton.setText(paused ? RESUME.getMessage() : PAUSE.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -83,7 +97,7 @@ public class AnalogChartPanel {
|
||||||
upperPanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
upperPanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
||||||
content.add(upperPanel, BorderLayout.NORTH);
|
content.add(upperPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
content.add(analogChart, BorderLayout.CENTER);
|
content.add(canvas, BorderLayout.CENTER);
|
||||||
|
|
||||||
final JPanel lowerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
|
final JPanel lowerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
|
||||||
lowerPanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
lowerPanel.setBorder(BorderFactory.createLineBorder(Color.white));
|
||||||
|
@ -95,6 +109,11 @@ public class AnalogChartPanel {
|
||||||
lowerPanel.add(new ConfigField(Fields.digitalChartSize, "Engine Sniffer size").getContent());
|
lowerPanel.add(new ConfigField(Fields.digitalChartSize, "Engine Sniffer size").getContent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clear() {
|
||||||
|
minX = maxX = minY = maxY = 0;
|
||||||
|
values.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private void processValues() {
|
private void processValues() {
|
||||||
List<Double> keys = new ArrayList<>(values.keySet());
|
List<Double> keys = new ArrayList<>(values.keySet());
|
||||||
minX = keys.get(0);
|
minX = keys.get(0);
|
||||||
|
@ -113,12 +132,10 @@ public class AnalogChartPanel {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AnalogChart extends JComponent {
|
private class AnalogChartCanvas extends JComponent {
|
||||||
@Override
|
@Override
|
||||||
public void paint(Graphics g) {
|
public void paint(Graphics g) {
|
||||||
super.paint(g);
|
super.paint(g);
|
||||||
//Graphics2D g2 = (Graphics2D) g;
|
|
||||||
|
|
||||||
Dimension size = getSize();
|
Dimension size = getSize();
|
||||||
|
|
||||||
g.drawString("X range from " + minX + " to " + maxX, 4, 20);
|
g.drawString("X range from " + minX + " to " + maxX, 4, 20);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.rusefi.core.MessagesCentral;
|
||||||
import com.rusefi.io.CommandQueue;
|
import com.rusefi.io.CommandQueue;
|
||||||
import com.rusefi.io.serial.PortHolder;
|
import com.rusefi.io.serial.PortHolder;
|
||||||
import com.rusefi.ui.storage.Node;
|
import com.rusefi.ui.storage.Node;
|
||||||
|
import com.rusefi.ui.util.LocalizedMessages;
|
||||||
import com.rusefi.ui.util.UiUtils;
|
import com.rusefi.ui.util.UiUtils;
|
||||||
import com.rusefi.ui.widgets.AnyCommand;
|
import com.rusefi.ui.widgets.AnyCommand;
|
||||||
|
|
||||||
|
@ -15,6 +16,9 @@ import java.awt.event.ActionListener;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.CLEAR;
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.PAUSE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This panel displays plain-text 'msg' plain-text debug messages
|
* This panel displays plain-text 'msg' plain-text debug messages
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -64,7 +68,7 @@ public class MessagesPanel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
JButton resetButton = new JButton("clear");
|
JButton resetButton = new JButton(CLEAR.getMessage());
|
||||||
resetButton.setMnemonic('c');
|
resetButton.setMnemonic('c');
|
||||||
resetButton.addActionListener(new ActionListener() {
|
resetButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -74,7 +78,7 @@ public class MessagesPanel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final JButton pauseButton = new JButton("pause");
|
final JButton pauseButton = new JButton(PAUSE.getMessage());
|
||||||
pauseButton.setMnemonic('p');
|
pauseButton.setMnemonic('p');
|
||||||
pauseButton.addActionListener(new ActionListener() {
|
pauseButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.rusefi.ui.config;
|
package com.rusefi.ui.config;
|
||||||
|
|
||||||
|
import com.rusefi.FileLog;
|
||||||
import com.rusefi.config.Field;
|
import com.rusefi.config.Field;
|
||||||
import com.rusefi.config.FieldType;
|
|
||||||
import com.rusefi.core.MessagesCentral;
|
import com.rusefi.core.MessagesCentral;
|
||||||
import com.rusefi.core.Pair;
|
import com.rusefi.core.Pair;
|
||||||
import com.rusefi.io.CommandQueue;
|
import com.rusefi.io.CommandQueue;
|
||||||
|
@ -10,6 +10,8 @@ import com.rusefi.ui.util.JTextFieldWithWidth;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.KeyAdapter;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
|
||||||
public class ConfigField {
|
public class ConfigField {
|
||||||
private final Field field;
|
private final Field field;
|
||||||
|
@ -21,15 +23,21 @@ public class ConfigField {
|
||||||
public ConfigField(final Field field, String topLabel) {
|
public ConfigField(final Field field, String topLabel) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This would request initial value
|
||||||
|
*/
|
||||||
ConnectionStatus.INSTANCE.addListener(new ConnectionStatus.Listener() {
|
ConnectionStatus.INSTANCE.addListener(new ConnectionStatus.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionStatus(boolean isConnected) {
|
public void onConnectionStatus(boolean isConnected) {
|
||||||
CommandQueue.getInstance().write(field.getType().getCommand() + " " + field.getOffset());
|
CommandQueue.getInstance().write(field.getType().getLoadCommand() + " " + field.getOffset());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
JPanel center = new JPanel(new FlowLayout());
|
JPanel center = new JPanel(new FlowLayout());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* I guess a nice status enum is coming soon
|
||||||
|
*/
|
||||||
center.add(status);
|
center.add(status);
|
||||||
status.setToolTipText("Pending...");
|
status.setToolTipText("Pending...");
|
||||||
|
|
||||||
|
@ -53,6 +61,19 @@ public class ConfigField {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
view.addKeyListener(new KeyAdapter() {
|
||||||
|
@Override
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||||
|
String msg = field.getType().getStoreCommand() + " " + field.getOffset() + " " + view.getText();
|
||||||
|
FileLog.MAIN.logLine("Sending " + msg);
|
||||||
|
CommandQueue.getInstance().write(msg);
|
||||||
|
status.setText("S");
|
||||||
|
status.setToolTipText("Storing...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public JPanel getContent() {
|
public JPanel getContent() {
|
||||||
|
|
|
@ -22,6 +22,9 @@ import java.awt.event.ActionListener;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.CLEAR;
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.PAUSE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Engine Sniffer control consists of a set of {@link UpDownImage}
|
* Engine Sniffer control consists of a set of {@link UpDownImage}
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -85,7 +88,7 @@ public class EngineSnifferPanel {
|
||||||
|
|
||||||
statusPanel.setWaveReport(crank.createTranslator());
|
statusPanel.setWaveReport(crank.createTranslator());
|
||||||
|
|
||||||
JButton clearButton = new JButton("clear");
|
JButton clearButton = new JButton(CLEAR.getMessage());
|
||||||
clearButton.setMnemonic('c');
|
clearButton.setMnemonic('c');
|
||||||
clearButton.addActionListener(new ActionListener() {
|
clearButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -104,7 +107,7 @@ public class EngineSnifferPanel {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final JButton pauseButton = new JButton("pause");
|
final JButton pauseButton = new JButton(PAUSE.getMessage());
|
||||||
pauseButton.setMnemonic('p');
|
pauseButton.setMnemonic('p');
|
||||||
pauseButton.addActionListener(new ActionListener() {
|
pauseButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.rusefi.ui.util;
|
||||||
|
|
||||||
|
public enum LocalizedMessages {
|
||||||
|
CLEAR("clear"),
|
||||||
|
PAUSE("pause"),
|
||||||
|
RESUME("resume"),
|
||||||
|
;
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
LocalizedMessages(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,9 @@ import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.PAUSE;
|
||||||
|
import static com.rusefi.ui.util.LocalizedMessages.RESUME;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 7/7/13
|
* 7/7/13
|
||||||
* (c) Andrey Belomutskiy
|
* (c) Andrey Belomutskiy
|
||||||
|
@ -45,7 +48,7 @@ public class UiUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPauseButtonText(JButton pauseButton, boolean isPaused) {
|
public static void setPauseButtonText(JButton pauseButton, boolean isPaused) {
|
||||||
pauseButton.setText(isPaused ? "resume" : "pause");
|
pauseButton.setText(isPaused ? RESUME.getMessage() : PAUSE.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void centerWindow(Window w) {
|
public static void centerWindow(Window w) {
|
||||||
|
|
Loading…
Reference in New Issue