How to replace the griffon app icon for a custom icon - griffon

I want to replace the Griffon icon for a custom icon for my App. I have replaced the icons in my view as shown here:
application(id: "mainFrame", title: 'selekron',
preferredSize: [884, 800],
pack: true,
//location: [50,50],
locationByPlatform:true,
iconImage: imageIcon('/progresomusica-icon-48x48.png').image,
iconImages: [imageIcon('/progresomusica-icon-48x48.png').image,
imageIcon('/progresomusica-icon-32x32.png').image,
imageIcon('/progresomusica-icon-16x16.png').image]) {
I have the next settings in griffon-app/conf/BuildConfig.groovy:
deploy {
application {
title = "${appName} ${appVersion}"
vendor = System.properties['user.name']
homepage = "http://localhost/${appName}"
description {
complete = "${appName} ${appVersion}"
oneline = "${appName} ${appVersion}"
minimal = "${appName} ${appVersion}"
tooltip = "${appName} ${appVersion}"
}
icon {
'default' {
name = 'progresomusica-icon-64x64.png'
width = '64'
height = '64'
}
splash {
name = 'griffon.png'
width = '391'
height = '123'
}
selected {
name = 'progresomusica-icon-64x64.png'
width = '64'
height = '64'
}
disabled {
name = 'progresomusica-icon-64x64.png'
width = '64'
height = '64'
}
rollover {
name = 'progresomusica-icon-64x64.png'
width = '64'
height = '64'
}
shortcut {
name = 'progresomusica-icon-64x64.png'
width = '64'
height = '64'
}
}
I have deleted my $HOME/.griffon folder and run the app again but I keep getting the griffon red icon.
Any ideas about what am I missing?

Are you running the application on OSX? If so then have a look at $GRIFFON_HOME/scripts/_GriffonPackage.groovy. This file defines the following closure
resolveApplicationIcnsFile = {
File icnsFile = null
if (buildConfig.application.icon) {
icnsFile = new File(basedir, buildConfig.application.icon)
if (!icnsFile.exists()) icnsFile = null
}
if (icnsFile == null) {
icnsFile = new File(basedir, "griffon-app/conf/dist/shared/${griffonAppName}.icns")
if (!icnsFile.exists()) icnsFile = null
}
if (icnsFile == null) {
icnsFile = new File("${griffonHome}/media/griffon.icns")
}
icnsFile
}
Basically you have 2 choices for defining the icon to be used in OSX's dock otherwise the default icon gets chosen. If running the app on Windows or Linux then updating the main View (as you did) should be enough
iconImage: imageIcon('/progresomusica-icon-48x48.png').image,
iconImages: [imageIcon('/progresomusica-icon-48x48.png').image,
imageIcon('/progresomusica-icon-32x32.png').image,
imageIcon('/progresomusica-icon-16x16.png').image]) {

Related

SwiftUI UITextView wrapper how to size it content to match parent

I have such UITextView wrapper and it works but when I place it inside List row. I would like it to autosize, i.e. have width that match parent in this case List Row VStack { }, and height that is autosize based on text length. Text should wrap.
Now it nearly works but the longer text like a URL goes outside available row width.
List {
VStack(alignment: .leading) {
if self.hasNote {
TextView(text: text)
}
}
struct TextView: UIViewRepresentable {
// MARK: - Properties
let text: String
init(text: String) {
self.text = text
}
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
//textView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
textView.backgroundColor = UIColor.clear
textView.isScrollEnabled = false
textView.attributedText = self.attributedText
textView.textContainer.lineBreakMode = .byWordWrapping
//textView.layoutIfNeeded()
textView.sizeToFit()
return textView
}
}
UPDATE
Now I have something like this it does fit parent SwiftUI views (rows in List) but instead it does not wrap text (or stretch vertically based on content size. If scrolled it wraps text correctly.
Also if I set .frame(height: 500) I can see it wraps text. But it doesn't autosize correctly.
func makeUIView(context: Context) -> UITextView {
let textView = UITextView()
textView.backgroundColor = UIColor.clear
textView.isScrollEnabled = false
textView.isSelectable = true
let linkAttrs : [NSAttributedString.Key : Any] = [
.foregroundColor: accentColor,
.underlineColor: accentColor,
.underlineStyle: NSUnderlineStyle.single.rawValue
]
textView.linkTextAttributes = linkAttrs
textView.attributedText = self.attributedText
textView.textContainer.lineBreakMode = .byWordWrapping
textView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
textView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
textView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
textView.setContentHuggingPriority(.defaultLow, for: .vertical)
textView.sizeToFit()
return textView
}

Xamarin.Forms Action Bar - Center Aligned Image

Using Xamarin.Forms, how do I get the same effect as the application pictured below, specifically to show a centred image on the Action Bar / page tool bar (the section in a blue box)?
I would like to have a long width image in that section, and the solution must work for Android, iOS, Windows Phone, and Universal Windows (even if it means writing custom renderers or platform specific xamarin code).
I suggest you create your own Xamarin.Forms view and handle the navigation by yourself something similar to this:
public class CustomBackNavigationBar : StackLayout
{
public Image BackIcon;
public Image Icon;
public Label IconTitle;
public StackLayout IconContainer;
public CustomBackNavigationBar(string title, string icon)
{
Padding = new Thickness(15,5);
HeightRequest = 40;
Orientation = StackOrientation.Horizontal;
VerticalOptions = LayoutOptions.Start;
BackgroundColor = StaticData.BlueColor;
Spacing = 15;
BackIcon = new Image
{
Source = StaticData.BackIcon,
HorizontalOptions = LayoutOptions.Start
};
Label Title = new Label
{
Text = title,
TextColor = Color.White,
FontSize = Device.GetNamedSize(NamedSize.Default, typeof(Label)),
FontAttributes = FontAttributes.Bold,
VerticalTextAlignment = TextAlignment.Center
};
Icon = new Image
{
Source = icon
};
IconTitle = new Label
{
Text = StaticData.CallAgent,
TextColor = Color.White,
FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label)),
};
IconContainer = new StackLayout
{
HorizontalOptions = LayoutOptions.EndAndExpand,
Spacing = 2,
Children = { Icon, IconTitle }
};
Children.Add(BackIcon);
Children.Add(Title);
Children.Add(IconContainer);
#region Events
BackIcon.GestureRecognizers.Clear();
BackIcon.GestureRecognizers.Add(new TapGestureRecognizer
{
Command = new Command(PopAsync)
});
#endregion
}
async void PopAsync()
{
await App.AppNavigation.PopAsync();
}
}

How to define new icons with winjs commands?

How to use an icon which is not provided by WinJS? For example, use one from here.
The html looks like:
<div data-win-control="WinJS.UI.SplitViewCommand" data-win-options="{ label: 'Home', icon: 'home'}"></div>
The png image should be 20x20 pixels with a transparent background (https://msdn.microsoft.com/en-us/library/windows/apps/hh700483.aspx). The png is set as in javascript:
document.getElementById("thatFancyButton").style.backgroundImage = url('pathOfPNGImage');
so in your case it is (notice \' \' in url()):
<div data-win-control="WinJS.UI.SplitViewCommand" data-win-options="{ label: 'Home', icon: 'url(\'pathOfPng.png\')'}"></div>
You can also set one letter glyphs like icon: '©' and it will show it as icon.
Below is the snippet of the SplitViewCommand icon setting logic:
/// <field type="String" locid="WinJS.UI.SplitViewCommand.icon" helpKeyword="WinJS.UI.SplitViewCommand.icon">
/// Gets or sets the icon of the SplitViewCommand. This value is either one of the values of the AppBarIcon enumeration or the path of a custom PNG file.
/// </field>
icon: {
get: function () {
return this._icon;
},
set: function (value) {
this._icon = (_Icon[value] || value);
// If the icon's a single character, presume a glyph
if (this._icon && this._icon.length === 1) {
// Set the glyph
this._imageSpan.textContent = this._icon;
this._imageSpan.style.backgroundImage = "";
this._imageSpan.style.msHighContrastAdjust = "";
this._imageSpan.style.display = "";
} else if (this._icon && this._icon.length > 1) {
// Must be an image, set that
this._imageSpan.textContent = "";
this._imageSpan.style.backgroundImage = this._icon;
this._imageSpan.style.msHighContrastAdjust = "none";
this._imageSpan.style.display = "";
} else {
this._imageSpan.textContent = "";
this._imageSpan.style.backgroundImage = "";
this._imageSpan.style.msHighContrastAdjust = "";
this._imageSpan.style.display = "none";
}
}
},
If you happen to have errors with the background image size, modify win-commandimage class. I did this fix in styles to fit the image into button correctly:
.win-commandimage {
background-size:contain;
}

Correlate groups from XQueryTree data to a window

I ran XQueryTree on all my windows and I got them in z-order from topmost at top of the array to bottom-most at bottom of array.
I then filtered out only what is visible by doing XGetWindowAttributes on each and removing it if it is not map_state of IsVisible
For each visible window, I check and get the _NET_WM_PID, _NET_WM_NAME, x, y, height (as height + border_width), and width (as width + border_width).
My data is at this gist and also at bottom: https://gist.github.com/Noitidart/94562d08f243cd7ca7ec
My setup is of two monitors. And this is a fullscreenshot of them both:
There is one transparent window over each monitor, that is the height and width of the monitor, their titles are "nativeshot_canvas".
So looking through the data I see that windows are broken up into multiple entries by XQueryTree. My manual analysis tells me this:
"nativeshot_canvas" on left monitor
"nativeshot_canvas" on right monitor
UNKNOWN WINDOW 1
UNKNOWN WINDOW 2
horizontal menu bar on right monitor
horizontal menu bar on left monitor
vertical dock on right monitor
vertical dock on left monitor
UNKNOWN WINDOW 3
"Javascript Application" window
"Browser Console" window
"Mozilla Firefox" window with two tabs
"Desktop"
A graphic of the data and my manual analysis is below.
THE QUESTION
Is there a way to programmatically identify which entries correlate to a single window? In my manual analysis I used some patterns I came up with in that each window group starts with either a _NET_WM_PID (pid key in data below) or a _NET_WM_NAME (title key in data below). I don't think this is a good pattern because we see at top things have a PID but their width and height are 1.
edit: still stuck on how finding a gurantteed way to correlate these divisions into groups of windows. i basically need to get all x, y, width, and height of all the windows out there, if anyone has any input i would be very greatful
My code to list out the XQueryTree data:
var xqRoot = ostypes.TYPE.Window();
var xqParent = ostypes.TYPE.Window();
var xqChildArr = ostypes.TYPE.Window.ptr();
var nChilds = ostypes.TYPE.unsigned_int();
var gpTypeReturned = ostypes.TYPE.Atom();
var gpFormatReturned = ostypes.TYPE.int();
var gpNItemsReturned = ostypes.TYPE.unsigned_long();
var gpBytesAfterReturn = ostypes.TYPE.unsigned_long();
var gpItemsArr = ostypes.TYPE.unsigned_char.ptr();
var geoRoot = ostypes.TYPE.Window();
var geoX = ostypes.TYPE.int();
var geoY = ostypes.TYPE.int();
var geoW = ostypes.TYPE.unsigned_int();
var geoH = ostypes.TYPE.unsigned_int();
var geoBorderWidth = ostypes.TYPE.unsigned_int();
var geoDepth = ostypes.TYPE.unsigned_int();
var wAttr = ostypes.TYPE.XWindowAttributes();
var processWin = function(w) {
if (aOptions.filterVisible) {
var rez_WA = ostypes.API('XGetWindowAttributes')(ostypes.HELPER.cachedXOpenDisplay(), w, wAttr.address());
console.info('wAttr.map_state:', wAttr.map_state.toString());
if (!cutils.jscEqual(wAttr.map_state, ostypes.CONST.IsViewable)) {
return; // continue as this is a hidden window, do not list features, do not dig this window
}
}
var thisWin = {};
// fetch props on thisWin
thisWin.hwndXid = parseInt(cutils.jscGetDeepest(w));
if (aOptions.getPid) {
var rez_pid = ostypes.API('XGetWindowProperty')(ostypes.HELPER.cachedXOpenDisplay(), w, ostypes.HELPER.cachedAtom('_NET_WM_PID'), 0, 1, ostypes.CONST.False, ostypes.CONST.XA_CARDINAL, gpTypeReturned.address(), gpFormatReturned.address(), gpNItemsReturned.address(), gpBytesAfterReturn.address(), gpItemsArr.address());
if (ostypes.HELPER.getWinProp_ReturnStatus(ostypes.CONST.XA_CARDINAL, gpTypeReturned, gpFormatReturned, gpBytesAfterReturn) == 1) {
var jsN = parseInt(cutils.jscGetDeepest(gpNItemsReturned));
if (jsN == 0) {
thisWin.pid = null; // set to null as this window did not have a pid, but i add the key indicating i tested for it and the window had the proerty
} else {
//console.info('gpItemsArr:', gpItemsArr.toString(), 'casted:', ctypes.cast(gpItemsArr, ostypes.TYPE.CARD32).toString(), 'casted to single el:', ctypes.cast(gpItemsArr, ostypes.TYPE.CARD32.array(1).ptr).contents.toString()); // "gpItemsArr:" "ctypes.unsigned_char.ptr(ctypes.UInt64("0x7f229409d710"))" "casted:" "ctypes.unsigned_int(2483672848)" "casted to single el:" "ctypes.unsigned_int.array(1)([2212])" // showing that it must be cast and not just to type cuz its single element, but to array of 1 element
thisWin.pid = parseInt(cutils.jscGetDeepest(ctypes.cast(gpItemsArr, ostypes.TYPE.CARD32.array(1).ptr).contents[0]));
}
ostypes.API('XFree')(gpItemsArr);
} else {
thisWin.pid = undefined; // window didnt even have property
}
}
if (aOptions.getTitle) {
var rez_title = ostypes.API('XGetWindowProperty')(ostypes.HELPER.cachedXOpenDisplay(), w, ostypes.HELPER.cachedAtom('_NET_WM_NAME'), 0, 256 /* this number times 4 is maximum ctypes.char that can be returned*/, ostypes.CONST.False, ostypes.HELPER.cachedAtom('UTF8_STRING'), gpTypeReturned.address(), gpFormatReturned.address(), gpNItemsReturned.address(), gpBytesAfterReturn.address(), gpItemsArr.address());
if (ostypes.HELPER.getWinProp_ReturnStatus(ostypes.HELPER.cachedAtom('UTF8_STRING'), gpTypeReturned, gpFormatReturned, gpBytesAfterReturn) == 1) {
var jsN = parseInt(cutils.jscGetDeepest(gpNItemsReturned));
if (jsN == 0) {
thisWin.title = ''; // window had property but not title
} else {
thisWin.title = ctypes.cast(gpItemsArr, ostypes.TYPE.char.array(jsN).ptr).contents.readString();
}
ostypes.API('XFree')(gpItemsArr);
} else {
thisWin.title = undefined; // window didnt even have property
}
}
if (aOptions.getBounds) {
if (aOptions.filterVisible) {
// then get the info from wAttr as its already available
thisWin.left = parseInt(cutils.jscGetDeepest(wAttr.x));
thisWin.top = parseInt(cutils.jscGetDeepest(wAttr.y));
var borderWidth = parseInt(cutils.jscGetDeepest(wAttr.border_width));
thisWin.borderWidth = borderWidth;
thisWin.width = parseInt(cutils.jscGetDeepest(wAttr.width))/* + borderWidth*/;
thisWin.height = parseInt(cutils.jscGetDeepest(wAttr.height))/* + borderWidth*/;
thisWin.right = thisWin.left + thisWin.width;
thisWin.bottom = thisWin.top + thisWin.height;
} else {
var rez_bounds = ostypes.API('XGetGeometry')(ostypes.HELPER.cachedXOpenDisplay(), w, geoRoot.address(), geoX.address(), geoY.address(), geoW.address(), geoH.address(), geoBorderWidth.address(), geoDepth.address());
thisWin.left = parseInt(cutils.jscGetDeepest(geoX));
thisWin.top = parseInt(cutils.jscGetDeepest(geoY));
var borderWidth = parseInt(cutils.jscGetDeepest(wAttr.border_width));
thisWin.borderWidth = borderWidth;
thisWin.width = parseInt(cutils.jscGetDeepest(wAttr.width))/* + borderWidth*/;
thisWin.height = parseInt(cutils.jscGetDeepest(wAttr.height))/* + borderWidth*/;
thisWin.right = thisWin.left + thisWin.width;
thisWin.bottom = thisWin.top + thisWin.height;
}
}
rezWinArr.splice(0, 0, thisWin);
// dig the win even if it doesnt qualify
var rez_XQ = ostypes.API('XQueryTree')(ostypes.HELPER.cachedXOpenDisplay(), w, xqRoot.address(), xqParent.address(), xqChildArr.address(), nChilds.address()); // interesting note about XQueryTree and workspaces: "The problem with this approach is that it will only return windows on the same virtual desktop. In the case of multiple virtual desktops, windows on other virtual desktops will be ignored." source: http://www.experts-exchange.com/Programming/System/Q_21443252.html
var jsNC = parseInt(cutils.jscGetDeepest(nChilds));
if (jsNC > 0) {
var jsChildArr = ctypes.cast(xqChildArr, ostypes.TYPE.Window.array(jsNC).ptr).contents;
// for (var i=jsNC-1; i>-1; i--) {
for (var i=0; i<jsNC; i++) {
var wChild = jsChildArr[i];
processWin(wChild);
}
ostypes.API('XFree')(xqChildArr);
}
}
processWin(ostypes.HELPER.cachedDefaultRootWindow());

How to get drives( 'C' or 'E' or 'F' )available in a system?

I am developing an Bootstrapper application. When we move to the installation location selection wizard, we can have a browse option to change the location of our setup installation.
When we clock that browse option, i need to show only the drives( 'C', 'D' and 'F') available in a system. When we select the drive, it will not expand. i need that drive alone (Ex: C:) in the installation location text in the installation wizard.
Can anyone please guide me that how to achieve my requirement?
My code:
private void btn_Browse_Click(object sender, EventArgs e)
{
txt_InstallLocation.Focus();
FBD_Source.RootFolder = Environment.SpecialFolder.Desktop;
if (FBD_Source.ShowDialog() == DialogResult.OK)
{
txt_InstallLocation.TextBox.Text = FBD_Source.SelectedPath;
BA.Model.Bootstrapper.Engine.StringVariables["APPDIR"] = FBD_Source.SelectedPath + "\\";
}
}
I need to modify the below line of code.
FBD_Source.RootFolder = Environment.SpecialFolder.Desktop;
Can anyone please assist me to proceed further or direct me in right path?
Your can find the available drives like this.
var drives = System.Environment.GetLogicalDrives();
foreach (string d in drives)
Console.WriteLine(d);
Don't use the FolderBrowserDialog.
Create a form with a dynamically created radiobutton/list and make the user select one of those options
Something like this
var drives = System.Environment.GetLogicalDrives();
Form selectionForm = new Form() { MaximizeBox = false, FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog, StartPosition = FormStartPosition.CenterScreen };
ListBox lb = new ListBox() { Dock = DockStyle.Fill };
foreach (var item in drives)
lb.Items.Add(item);
selectionForm.Controls.Add(lb);
Button btnOk = new Button() { Dock = DockStyle.Left, Width = selectionForm.Width / 2 };
btnOk.Text = "OK";
Button btnCancel = new Button() { Dock = DockStyle.Right, Width = selectionForm.Width / 2 };
btnCancel.Text = "Cancel";
Panel bottomPanel = new Panel() { Dock = DockStyle.Bottom, Height = 50 };
bottomPanel.Controls.Add(btnOk);
bottomPanel.Controls.Add(btnCancel);
selectionForm.Controls.Add(bottomPanel);
selectionForm.ShowDialog();
MessageBox.Show(lb.SelectedItem.ToString());

Resources