Skip to content

Instantly share code, notes, and snippets.

@fredgrott
Created April 17, 2025 19:24
Show Gist options
  • Save fredgrott/5f49bf8dd332a2d426e16b2a19f5c173 to your computer and use it in GitHub Desktop.
Save fredgrott/5f49bf8dd332a2d426e16b2a19f5c173 to your computer and use it in GitHub Desktop.
media query extension
// Copyright 2025 Fredrick Allan Grott. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
import 'dart:math';
import 'package:dual_screen/dual_screen.dart';
import 'package:flutter/material.dart';
import 'package:universal_platform/universal_platform.dart';
import 'package:userinterface/core/lifecycle/app_lifecycle_globals.dart';
/// Basically, to do Canonical Layouts we have to do
/// several changes including how we grab MediaQuery and MediaQueryData.
/// It starts with using a custom lifecycle mixin to wrap the app acaffold
/// that in turn grabs the Display and FlutterView objects.
///
/// Display is used to grab size and other stuff normally grabbed from
/// MediaQuery and propertyOf stuff is grabbed via the MediaQueryData.fromView
/// FlutterView constru8ct.
///
/// @author Fredrick Allan Grott
extension MediaQueryExtension on BuildContext {
/// devicePixelRatio from the physical screen.
static double devicePixelRatio = appDisplay!.devicePixelRatio;
/// set pixelsPerInch per platform desktop is different from mobile.
static double get pixelsPerInch => UniversalPlatform.isAndroid || UniversalPlatform.isIOS ? 150 : 96;
/// Non size stuff needs to be grabbed from MediaQueryData
/// with the appView so that we grab the current FlutterView as
/// that will then always be correct for desktop multi-window
/// and mobile foldables.
MediaQueryData get mediaQueryData => MediaQueryData.fromView(appView!);
/// Size from the Display object.
Size get sizePx => appDisplay!.size;
/// shortest side.
double get shortside => appDisplay!.size.shortestSide;
/// longest side
double get longside => appDisplay!.size.longestSide;
/// aspectRatio
double get aspectRatio => appDisplay!.size.aspectRatio;
/// textScaler
TextScaler get textScaler => mediaQueryData.textScaler;
/// highContrast
bool get highContrast => mediaQueryData.highContrast;
/// singleScreen, if not true than the hinge is open
bool get singleScreen => MediaQuery.of(this).hinge == null;
/// isRTL
bool get isRTL => Directionality.of(this).toString().contains(TextDirection.rtl.toString().toLowerCase());
/// boldText
bool get boldText => mediaQueryData.boldText;
/// Returns same as MediaQuery.of(context).size.width
double get widthPx => sizePx.width;
/// Returns same as MediaQuery.of(context).height
double get heightPx => sizePx.height;
/// Returns diagonal screen pixels
double get diagonalPx {
final Size s = sizePx;
return sqrt((s.width * s.width) + (s.height * s.height));
}
/// Returns pixel size in Inches
Size get sizeInches {
final Size pxSize = sizePx;
return Size(pxSize.width / pixelsPerInch, pxSize.height / pixelsPerInch);
}
/// Returns screen width in Inches
double get widthInches => sizeInches.width;
/// Returns screen height in Inches
double get heightInches => sizeInches.height;
/// Returns screen diagonal in Inches
double get diagonalInches => diagonalPx / pixelsPerInch;
/// Returns fraction (0-1) of screen width in pixels
double widthPct(double fraction) => fraction * widthPx;
/// Returns fraction (0-1) of screen height in pixels
double heightPct(double fraction) => fraction * heightPx;
/// gets orientation.
bool get isLandscape => mediaQueryData.orientation == Orientation.landscape;
/// Padding
EdgeInsets get padding => mediaQueryData.padding;
/// ViewPadding
EdgeInsets get viewPadding => mediaQueryData.viewPadding;
/// ViewInsets.
EdgeInsets get viewInsets => mediaQueryData.viewInsets;
bool get always24HourFormat => mediaQueryData.alwaysUse24HourFormat;
Brightness get brightness => mediaQueryData.platformBrightness;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment