use of com.codename1.ui.ComponentSelector.ComponentClosure in project CodenameOne by codenameone.
the class CN1CSSCLI method compile.
private static void compile(File inputFile, File outputFile) throws IOException {
File baseDir = inputFile.getParentFile().getParentFile();
File checksumsFile = getChecksumsFile(baseDir);
if (!checksumsFile.exists()) {
saveChecksums(baseDir, new HashMap<String, String>());
}
if (!checksumsFile.exists()) {
throw new RuntimeException("Failed to create checksums file");
}
FileChannel channel = new RandomAccessFile(checksumsFile, "rw").getChannel();
FileLock lock = channel.lock();
try {
Map<String, String> checksums = loadChecksums(baseDir);
if (outputFile.exists() && !isMavenProject(inputFile)) {
String outputFileChecksum = getMD5Checksum(outputFile.getAbsolutePath());
String previousChecksum = checksums.get(inputFile.getName());
if (previousChecksum == null || !previousChecksum.equals(outputFileChecksum)) {
File backups = new File(inputFile.getParentFile(), ".backups");
backups.mkdirs();
File bak = new File(backups, outputFile.getName() + "." + System.currentTimeMillis() + ".bak");
Files.copy(outputFile.toPath(), bak.toPath(), StandardCopyOption.REPLACE_EXISTING);
System.out.println(outputFile + " has been modified since it was last compiled. Making copy at " + bak);
outputFile.delete();
}
}
if (outputFile.exists() && inputFile.lastModified() <= outputFile.lastModified()) {
System.out.println("File has not changed since last compile.");
return;
}
try {
URL url = inputFile.toURI().toURL();
// CSSTheme theme = CSSTheme.load(CSSTheme.class.getResource("test.css"));
CSSTheme theme = CSSTheme.load(url);
theme.cssFile = inputFile;
theme.resourceFile = outputFile;
JavaSEPort.setBaseResourceDir(outputFile.getParentFile());
WebViewProvider webViewProvider = new WebViewProvider() {
@Override
public BrowserComponent getWebView() {
if (web == null) {
if (!CN1Bootstrap.isCEFLoaded()) /* && !CN1Bootstrap.isJavaFXLoaded()*/
{
// to output the correct bounds so we are killing FX support. CEF only.
throw new MissingNativeBrowserException();
}
if (!CN.isEdt()) {
CN.callSerially(() -> {
getWebView();
});
int counter = 0;
while (web == null && counter++ < 50) {
Util.sleep(100);
}
return web;
}
web = new BrowserComponent();
ComponentSelector.select("*", web).add(web, true).selectAllStyles().setBgTransparency(0).setMargin(0).setPadding(0).setBorder(Border.createEmpty()).each(new ComponentClosure() {
@Override
public void call(Component c) {
c.setOpaque(false);
}
});
web.setOpaque(false);
Form f = new Form();
f.getContentPane().getStyle().setBgColor(0xff0000);
f.getContentPane().getStyle().setBgTransparency(0xff);
if (f.getToolbar() == null) {
f.setToolbar(new com.codename1.ui.Toolbar());
}
f.getToolbar().hideToolbar();
f.setLayout(new com.codename1.ui.layouts.BorderLayout());
f.add(CN.CENTER, web);
f.show();
}
return web;
}
};
File cacheFile = new File(theme.cssFile.getParentFile(), theme.cssFile.getName() + ".checksums");
if (outputFile.exists() && cacheFile.exists()) {
theme.loadResourceFile();
theme.loadSelectorCacheStatus(cacheFile);
}
theme.createImageBorders(webViewProvider);
theme.updateResources();
theme.save(outputFile);
theme.saveSelectorChecksums(cacheFile);
String checksum = getMD5Checksum(outputFile.getAbsolutePath());
checksums.put(inputFile.getName(), checksum);
saveChecksums(baseDir, checksums);
} catch (MalformedURLException ex) {
Logger.getLogger(CN1CSSCLI.class.getName()).log(Level.SEVERE, null, ex);
}
} finally {
if (lock != null) {
lock.release();
}
if (channel != null) {
channel.close();
}
}
}
use of com.codename1.ui.ComponentSelector.ComponentClosure in project CodenameOne by codenameone.
the class DefaultLookAndFeel method drawPullToRefresh.
/**
* {@inheritDoc}
*/
public void drawPullToRefresh(Graphics g, final Component cmp, boolean taskExecuted) {
final Form parentForm = cmp.getComponentForm();
final int scrollY = cmp.getScrollY();
Component cmpToDraw;
if (taskExecuted) {
cmpToDraw = updating;
} else {
if (-scrollY > getPullToRefreshHeight()) {
cmpToDraw = releaseToRefresh;
} else {
cmpToDraw = pullDown;
}
}
if (pull.getComponentAt(0) != updating && cmpToDraw != pull.getComponentAt(0)) {
parentForm.registerAnimated(new Animation() {
int counter = 0;
Image i;
{
i = UIManager.getInstance().getThemeImageConstant("pullToRefreshImage");
if (i == null) {
i = getDefaultRefreshIcon();
}
}
public boolean animate() {
counter++;
if (pull.getComponentAt(0) == releaseToRefresh) {
((Label) releaseToRefresh).setIcon(i.rotate(180 - (180 / 6) * counter));
} else {
((Label) pullDown).setIcon(i.rotate(180 * counter / 6));
}
if (counter == 6) {
((Label) releaseToRefresh).setIcon(i);
((Label) pullDown).setIcon(i.rotate(180));
parentForm.deregisterAnimated(this);
}
// Placing the repaint inside a callSerially() because repaint directly
// inside animate causes painting artifacts in many instances
CN.callSerially(new Runnable() {
public void run() {
cmp.repaint(cmp.getAbsoluteX(), cmp.getAbsoluteY() - getPullToRefreshHeight(), cmp.getWidth(), getPullToRefreshHeight());
}
});
return false;
}
public void paint(Graphics g) {
}
});
}
if (pull.getComponentAt(0) != cmpToDraw && cmpToDraw instanceof Label && (pull.getComponentAt(0) instanceof Label)) {
((Label) cmpToDraw).setIcon(((Label) pull.getComponentAt(0)).getIcon());
}
Component current = pull.getComponentAt(0);
if (current != cmpToDraw) {
pull.replace(current, cmpToDraw, null);
}
pull.setWidth(cmp.getWidth());
pull.setX(cmp.getAbsoluteX());
pull.setY(cmp.getY() - scrollY - getPullToRefreshHeight());
pull.layoutContainer();
// We need to make the InfiniteProgress to animate, otherwise the progress
// just stays static.
ComponentSelector.select("*", pull).each(new ComponentClosure() {
@Override
public void call(Component c) {
if (c instanceof InfiniteProgress) {
((InfiniteProgress) c).animate(true);
} else {
c.animate();
}
}
});
pull.paintComponent(g);
}
use of com.codename1.ui.ComponentSelector.ComponentClosure in project CodenameOne by codenameone.
the class Sheet method show.
/**
* Shows the sheet over the current form using a slide-up transition with given duration in milliseconds.
*
* <p>If another sheet is currently being shown, then this will replace that sheet, and use an appropriate slide
* animation to adjust the size.</p>
* @param duration The duration of the slide transition in milliseconds.
* @see #show()
*/
public void show(final int duration) {
// We need to add some margin to the title to prevent overlap with the
// back button and the commaneds.
int titleMargin = Math.max(commandsContainer.getPreferredW() + commandsContainer.getStyle().getHorizontalMargins(), backButton.getPreferredW() + backButton.getStyle().getHorizontalMargins());
// Set the padding in the content pane to match the corner radius
Style s = getStyle();
Style titleParentStyle = title.getParent().getStyle();
titleParentStyle.setMarginLeft(titleMargin);
titleParentStyle.setMarginRight(titleMargin);
Border border = s.getBorder();
if (border instanceof RoundRectBorder) {
RoundRectBorder b = (RoundRectBorder) border;
$(contentPane).setPaddingMillimeters(b.getCornerRadius());
}
// Deal with iPhoneX notch.
UIManager uim = UIManager.getInstance();
Style statusBarStyle = uim.getComponentStyle("StatusBar");
Style titleAreaStyle = uim.getComponentStyle("TitleArea");
int topPadding = statusBarStyle.getPaddingTop() + statusBarStyle.getPaddingBottom() + titleAreaStyle.getPaddingTop();
int positionInt = getPositionInt();
Rectangle displaySafeArea = new Rectangle();
Display.getInstance().getDisplaySafeArea(displaySafeArea);
int bottomPadding = s.getPaddingBottom();
int safeAreaBottomPadding = CN.getDisplayHeight() - (displaySafeArea.getY() + displaySafeArea.getHeight());
bottomPadding = bottomPadding + safeAreaBottomPadding;
if (positionInt == S || positionInt == C) {
// For Center and South position we use margin to
// prevent overlap with top notch. This looks better as overlap is only
// an edge case that occurs when the sheet is the full screen height.
$(this).setMargin(topPadding, 0, 0, 0);
$(this).setPadding(s.getPaddingTop(), s.getPaddingRightNoRTL(), bottomPadding, s.getPaddingLeftNoRTL());
} else {
// For other cases we use padding to prevent overlap with top notch. This looks
// better as it appears that the sheet bleeds all the way to the top edge of the screen,
// but the content is not obscured by the notch.
$(this).setPadding(topPadding, s.getPaddingRightNoRTL(), bottomPadding, s.getPaddingLeftNoRTL());
}
// END Deal with iPhoneX notch
Form f = CN.getCurrentForm();
if (f.getAnimationManager().isAnimating()) {
f.getAnimationManager().flushAnimation(new Runnable() {
public void run() {
show(duration);
}
});
return;
}
if (getParent() != null) {
remove();
}
Container cnt = CN.getCurrentForm().getFormLayeredPane(Sheet.class, true);
if (!(cnt.getLayout() instanceof BorderLayout)) {
cnt.setLayout(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
cnt.getStyle().setBgPainter(new Painter() {
@Override
public void paint(Graphics g, Rectangle rect) {
int alph = g.getAlpha();
g.setAlpha((int) (alph * 30 / 100.0));
g.setColor(0x0);
g.fillRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
g.setAlpha(alph);
}
});
cnt.revalidate();
}
if (cnt.getComponentCount() > 0) {
$(".Sheet", cnt).each(new ComponentClosure() {
@Override
public void call(Component c) {
if (c instanceof Sheet) {
Sheet s = (Sheet) c;
if (s.isAncestorSheetOf(Sheet.this) || s == Sheet.this) {
// via a back chain
return;
}
s.fireCloseEvent(false);
// Hiding this sheet may eliminate the possibility of
// its parent sheets from being shown again,
// so their close events should also be fired in this case.
Sheet sp = s.getParentSheet();
while (sp != null) {
if (sp == Sheet.this) {
break;
}
if (!sp.isAncestorSheetOf(Sheet.this)) {
sp.fireCloseEvent(false);
}
sp = sp.getParentSheet();
}
}
}
});
Component existing = cnt.getComponentAt(0);
cnt.replace(existing, this, null);
cnt.animateLayout(duration);
} else {
cnt.add(getPosition(), this);
this.setWidth(getPreferredW(cnt));
this.setHeight(getPreferredH(cnt));
this.setX(getHiddenX(cnt));
this.setY(getHiddenY(cnt));
cnt.animateLayout(duration);
}
}
use of com.codename1.ui.ComponentSelector.ComponentClosure in project CodenameOne by codenameone.
the class TextSelection method update.
/**
* Updates the text selected spans based on the selected bounds.
*/
public void update() {
if (selectionRoot == null) {
selectionRoot = root;
}
final TreeSet<Component> selectedComponents = new TreeSet<Component>(ltr ? LTRComparator : RTLComparator);
$("*", selectionRoot).each(new ComponentClosure() {
@Override
public void call(Component c) {
TextSelectionSupport ts = c.getTextSelectionSupport();
if (ts != null && ts.isTextSelectionEnabled(TextSelection.this)) {
selectedComponents.add(c);
}
}
});
Spans spans = selectedSpans;
spans.clear();
tmpRect.setBounds(selectedBounds);
for (Component cmp : selectedComponents) {
TextSelectionSupport st = cmp.getTextSelectionSupport();
if (st == null) {
continue;
}
if (isVerticallyCoveredByBounds(cmp, selectedBounds)) {
// When selecting scrollable components, we need to adjust the bounds
// so that we get the entire contents - not just the visible viewport
selectedBounds.setX(getX(cmp, selectionRoot));
selectedBounds.setY(getY(cmp, selectionRoot));
selectedBounds.setWidth(Math.max(cmp.getScrollDimension().getWidth(), cmp.getWidth()));
selectedBounds.setHeight(Math.max(cmp.getScrollDimension().getHeight(), cmp.getHeight()));
}
spans.add(st.getTextSelectionForBounds(this, selectedBounds));
// In case selectedBounds was changed we reset
selectedBounds.setBounds(tmpRect);
}
}
Aggregations