// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Note: This code is not runnable, it contains code snippets displayed in the
// gallery.

import 'package:flutter/material.dart';

class ButtonsDemo {
  void setState(VoidCallback callback) { }
  late BuildContext context;

  void buttons() {

// START buttons_elevated
// Create an elevated button.
ElevatedButton(
  child: const Text('BUTTON TITLE'),
  onPressed: () {
    // Perform some action
  },
);

// Create a disabled button.
// Buttons are disabled when onPressed isn't
// specified or is null.
const ElevatedButton(
  onPressed: null,
  child: Text('BUTTON TITLE'),
);

// Create a button with an icon and a
// title.
ElevatedButton.icon(
  icon: const Icon(Icons.add, size: 18.0),
  label: const Text('BUTTON TITLE'),
  onPressed: () {
    // Perform some action
  },
);
// END

// START buttons_outlined
// Create an outlined button.
OutlinedButton(
  child: const Text('BUTTON TITLE'),
  onPressed: () {
    // Perform some action
  },
);

// Create a disabled button.
// Buttons are disabled when onPressed isn't
// specified or is null.
const OutlinedButton(
  onPressed: null,
  child: Text('BUTTON TITLE'),
);

// Create a button with an icon and a
// title.
OutlinedButton.icon(
  icon: const Icon(Icons.add, size: 18.0),
  label: const Text('BUTTON TITLE'),
  onPressed: () {
    // Perform some action
  },
);
// END

// START buttons_text
// Create a text button.
TextButton(
  child: const Text('BUTTON TITLE'),
  onPressed: () {
    // Perform some action
  },
);

// Create a disabled button.
// Buttons are disabled when onPressed isn't
// specified or is null.
const TextButton(
  onPressed: null,
  child: Text('BUTTON TITLE'),
);
// END


// START buttons_dropdown
// Member variable holding value.
String? dropdownValue;

// Dropdown button with string values.
DropdownButton<String>(
  value: dropdownValue,
  onChanged: (String? newValue) {
    // null indicates the user didn't select a
    // new value.
    setState(() {
      if (newValue != null)
        dropdownValue = newValue;
    });
  },
  items: <String>['One', 'Two', 'Free', 'Four']
    .map<DropdownMenuItem<String>>((String value) {
      return DropdownMenuItem<String>(
        value: value,
        child: Text(value));
    })
    .toList(),
);
// END


// START buttons_icon
// Member variable holding toggle value.
late bool value;

// Toggleable icon button.
IconButton(
  icon: const Icon(Icons.thumb_up),
  onPressed: () {
    setState(() => value = !value);
  },
  color: value ? Theme.of(context).primaryColor : null,
);
// END


// START buttons_action
// Floating action button in Scaffold.
Scaffold(
  appBar: AppBar(
    title: const Text('Demo'),
  ),
  floatingActionButton: const FloatingActionButton(
    onPressed: null,
    child: Icon(Icons.add),
  ),
);
// END
  }
}


class SelectionControls {
  void setState(VoidCallback callback) { }

  void selectionControls() {

// START selectioncontrols_checkbox
// Member variable holding the checkbox's value.
bool? checkboxValue = false;

// Create a checkbox.
Checkbox(
  value: checkboxValue,
  onChanged: (bool? value) {
    setState(() {
      checkboxValue = value;
    });
  },
);

// Create a tristate checkbox.
Checkbox(
  tristate: true,
  value: checkboxValue,
  onChanged: (bool? value) {
    setState(() {
      checkboxValue = value;
    });
  },
);

// Create a disabled checkbox.
// Checkboxes are disabled when onChanged isn't
// specified or null.
const Checkbox(value: false, onChanged: null);
// END


// START selectioncontrols_radio
// Member variable holding value.
int? radioValue = 0;

// Method setting value.
void handleRadioValueChanged(int? value) {
  setState(() {
    radioValue = value;
  });
}

// Creates a set of radio buttons.
Row(
  children: <Widget>[
    Radio<int>(
      value: 0,
      groupValue: radioValue,
      onChanged: handleRadioValueChanged,
    ),
    Radio<int>(
      value: 1,
      groupValue: radioValue,
      onChanged: handleRadioValueChanged,
    ),
    Radio<int>(
      value: 2,
      groupValue: radioValue,
      onChanged: handleRadioValueChanged,
    ),
  ],
);

// Creates a disabled radio button.
const Radio<int>(
  value: 0,
  groupValue: 0,
  onChanged: null,
);
// END


// START selectioncontrols_switch
// Member variable holding value.
bool switchValue = false;

// Create a switch.
Switch(
  value: switchValue,
  onChanged: (bool value) {
    setState(() {
      switchValue = value;
    }
  );
});

// Create a disabled switch.
// Switches are disabled when onChanged isn't
// specified or null.
const Switch(value: false, onChanged: null);
// END
  }
}


class GridLists {
  void gridlists() {
// START gridlists
// Creates a scrollable grid list with images
// loaded from the web.
GridView.count(
  crossAxisCount: 3,
  padding: const EdgeInsets.all(4.0),
  mainAxisSpacing: 4.0,
  crossAxisSpacing: 4.0,
  children: <String>[
    'https://example.com/image-0.jpg',
    'https://example.com/image-1.jpg',
    'https://example.com/image-2.jpg',
    '...',
    'https://example.com/image-n.jpg',
  ].map<Widget>((String url) {
    return GridTile(
      footer: GridTileBar(
        title: Text(url),
      ),
      child: Image.network(url, fit: BoxFit.cover),
    );
  }).toList(),
);
// END
  }
}


class AnimatedImage {
  void animatedImage() {
// START animated_image
Image.network('https://example.com/animated-image.gif');
// END
  }
}
